Backend Development 14 min read

Building a Minimal Game Server Framework from Scratch

This article explains how to design and implement a simple game server framework, covering the definition of server development, the two main game‑server architectures, core scene‑service requirements, a lightweight network library built on sockets, and sample C# code for connectors, server and client networking components.

Architecture Digest
Architecture Digest
Architecture Digest
Building a Minimal Game Server Framework from Scratch

Server development is a broad concept; narrowly it refers to backend logic such as CRUD operations or new game features, while broadly it also includes front‑end clients, operations tools, and all other development work surrounding the core logic.

Game server needs fall into two categories: a host‑client model for single‑player games with online features, and the classic MMO (multiple massive online) model where a host serves many clients in a client‑server architecture.

Both categories ultimately require a scene service that provides low network latency and rich interaction, typically implemented as a single‑threaded main loop that updates all entities and notifies clients.

To meet these requirements a lightweight network library is introduced, which converts transport‑layer streams (TCP/UDP) into application‑level packet messages, offers a poll‑based IO model to hide platform differences, and abstracts connection details for both client and server sides.

Key interfaces and a connector implementation are shown below:

public interface IRemote
{
    string RemoteIp { get; }
    int RemotePort { get; }
    int Id { get; }
    int Push(byte[] buffer, int len, int offset);
    int PushBegin(int len);
    int PushMore(byte[] buffer, int len, int offset);
}

public interface ILocal
{
    string RemoteIp { get; }
    int RemotePort { get; }
}

internal class Connector : IRemote, ILocal
{
    private const int HeadLen = 4;
    private Socket sysSocket;
    private ConnectorBuffer receiveBuffer = new ConnectorBuffer();
    private ConnectorBuffer sendBuffer = new ConnectorBuffer();
    private readonly SwapContainer
> msgQueue = new SwapContainer
>();
    private RC4 rc4Read;
    private RC4 rc4Write;
    internal bool DefferedClose { get; private set; }
    internal bool Connected { get; set; }
    public int Id { get; private set; }
    // ...
}

The server side is managed by ServerNetwork , which listens for incoming sockets, creates a Connector for each client, and uses swap containers to safely add or remove connectors across IO and user threads.

public class ServerNetwork
{
    public int ClientCount { get { return clientConnectorsDict.Count; } }
    private readonly Dictionary
clientConnectorsDict = new Dictionary
();
    private readonly SwapContainer
> toAddClientConnectors = new SwapContainer
>();
    private readonly SwapContainer
> toRemoveClientConnectors = new SwapContainer
>();
    private int nextClientConnectorId = 1;
    private Socket listenSocket;
    public void BeginAccept() { /* ... */ }
    public void Poll() { /* ... */ }
    // ...
}

On the client side, ClientNetwork holds a single Connector , provides methods to connect, send data, and poll for incoming messages, encapsulating the same poll‑based IO model.

public class ClientNetwork
{
    private Connector connector;
    private ConnectAsyncResult defferedConnected = null;
    private readonly string hostIp;
    private readonly int hostPort;
    private readonly Socket sysSocket;
    public void Connect() { /* ... */ }
    public void SendData(byte[] buffer) { /* ... */ }
    public void SendDatav(params byte[][] buffers) { /* ... */ }
    public void Poll() { /* ... */ }
    public void Close() { /* ... */ }
    // ...
}

The network protocol is deliberately simple: each packet consists of a length field followed by the payload data, which is sufficient for a prototype framework.

While this minimal framework can support a small online game, it has two critical shortcomings: synchronous database calls for persistence and a single‑process bottleneck for handling many connections. The author promises a follow‑up article that will address these issues to reach an industrial‑grade solution.

Backend DevelopmentC++frameworkNetwork ProgrammingSocketgame server
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.