Minecraft Community Edition uses a client-server architecture even for single-player games. This design enables seamless transitions between local and multiplayer gameplay.
Architecture Diagram
┌─────────────────────────────────────┐
│ Minecraft (Client) │
│ ┌───────────────────────────────┐ │
│ │ MultiplayerLocalPlayer(s) │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ ClientConnection(s) │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ Connection (Socket)
▼
┌─────────────────────────────────────┐
│ MinecraftServer (Server) │
│ ┌───────────────────────────────┐ │
│ │ ServerConnection │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ PlayerConnection(s) │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ ServerPlayer(s) │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ ServerLevel(s) │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Client Architecture
Minecraft Class
The main client class manages the game state and rendering (Minecraft.h:47):
class Minecraft
{
public:
// Level and rendering
MultiPlayerLevel * level;
LevelRenderer * levelRenderer;
GameRenderer * gameRenderer;
// Players (split-screen support)
shared_ptr < MultiplayerLocalPlayer > player;
shared_ptr < MultiplayerLocalPlayer > localplayers [XUSER_MAX_COUNT];
int localPlayerIdx;
// Network connections (one per local player)
ClientConnection * m_pendingLocalConnections [XUSER_MAX_COUNT];
bool m_connectionFailed [XUSER_MAX_COUNT];
// Game loop
void tick ( bool bFirst , bool bUpdateTextures );
void run_middle ();
};
Even in single-player mode, the client maintains a ClientConnection to a local MinecraftServer instance running in the same process.
MultiplayerLocalPlayer
Represents a local player on the client:
class MultiplayerLocalPlayer : public Player
{
ClientConnection * connection;
int userIndex; // For split-screen
// Input handling
virtual void move ( float xa , float za );
virtual void attack ( Entity * entity );
virtual void useItem ();
};
Server Architecture
MinecraftServer Class
The server manages world simulation and player connections (MinecraftServer.h:60):
class MinecraftServer : public ConsoleInputSource
{
public:
ServerConnection * connection;
Settings * settings;
ServerLevelArray levels; // Multiple dimensions
bool running;
int tickCount;
// Server settings
bool onlineMode;
bool animals;
bool npcs;
bool pvp;
bool allowFlight;
void run ( __int64 seed , void * lpParameter );
void tick ();
void stopServer ();
};
Server Tick System
The server runs at a fixed 20 ticks per second:
private:
static const int MS_PER_TICK = 1000 / SharedConstants ::TICKS_PER_SECOND; // 50ms
public:
void tick () {
// 1. Handle console input
handleConsoleInputs ();
// 2. Tick all levels (dimensions)
for (ServerLevel * level : levels) {
level -> tick ();
}
// 3. Tick all player connections
connection -> tick ();
// 4. Save chunks periodically
if (tickCount % 900 == 0 ) { // Every 45 seconds
saveAllChunks ();
}
tickCount ++ ;
}
The server must maintain 20 TPS (ticks per second) for proper gameplay. Performance issues causing tick lag affect all connected players.
Connection Management
ClientConnection
Manages the client-side network connection (ClientConnection.h:9):
class ClientConnection : public PacketListener
{
private:
enum eClientConnectionConnectingState {
eCCPreLoginSent = 0 ,
eCCPreLoginReceived ,
eCCLoginSent ,
eCCLoginReceived ,
eCCConnected
};
Connection * connection; // Low-level socket
Minecraft * minecraft;
MultiPlayerLevel * level;
bool started;
bool done;
public:
ClientConnection ( Minecraft * mc , const wstring & ip , int port );
ClientConnection ( Minecraft * mc , Socket * socket , int userIndex );
void tick ();
void send ( shared_ptr < Packet > packet );
void close ();
// Packet handlers
virtual void handleLogin ( shared_ptr < LoginPacket > packet );
virtual void handleChunkVisibility ( shared_ptr < ChunkVisibilityPacket > packet );
virtual void handleAddPlayer ( shared_ptr < AddPlayerPacket > packet );
virtual void handleMovePlayer ( shared_ptr < MovePlayerPacket > packet );
};
Connection Handshake
The connection process follows this sequence:
ServerConnection
Manages all incoming connections on the server (ServerConnection.h:10):
class ServerConnection
{
private:
vector < shared_ptr < PendingConnection >> pending;
vector < shared_ptr < PlayerConnection >> players;
MinecraftServer * server;
public:
void NewIncomingSocket ( Socket * socket );
void tick ();
void stop ();
};
PlayerConnection
Manages a single player’s connection on the server (PlayerConnection.h:12):
class PlayerConnection : public PacketListener
{
public:
Connection * connection;
shared_ptr < ServerPlayer > player;
MinecraftServer * server;
bool done;
void tick ();
void send ( shared_ptr < Packet > packet );
void disconnect ( DisconnectPacket :: eDisconnectReason reason );
// Packet handlers
virtual void handlePlayerAction ( shared_ptr < PlayerActionPacket > packet );
virtual void handleMovePlayer ( shared_ptr < MovePlayerPacket > packet );
virtual void handleChat ( shared_ptr < ChatPacket > packet );
};
Player Management
PlayerList
The server maintains a centralized player list:
class PlayerList
{
public:
vector < shared_ptr < ServerPlayer >> players;
MinecraftServer * server;
void addPlayer ( shared_ptr < ServerPlayer > player );
void removePlayer ( shared_ptr < ServerPlayer > player );
void broadcastPacket ( shared_ptr < Packet > packet );
void sendLevelData ( ServerPlayer * player );
};
Player Lifecycle
Connection : PlayerConnection created when socket connects
Login : Player entity created after successful authentication
Spawn : Player spawned in world, visible to other players
Gameplay : Continuous packet exchange (movement, actions, chat)
Disconnect : Player removed, resources cleaned up
Split-Screen Local Play
Minecraft CE supports up to 4 local players simultaneously, each with their own connection to the local server.
Adding Local Players
// Minecraft.h:119
bool Minecraft :: addLocalPlayer ( int idx ) {
// Create local player
localplayers [idx] = createExtraLocalPlayer (idx, name, pad, dimension);
// Create client connection to local server
Socket * socket = createLocalSocket ();
ClientConnection * connection = new ClientConnection ( this , socket, idx);
m_pendingLocalConnections [idx] = connection;
// Update viewport assignments
updatePlayerViewportAssignments ();
return true ;
}
Each local player:
Has their own ClientConnection to the server
Maintains separate inventory and game state
Renders to their own viewport
Can have different privileges and permissions
Server Lifecycle
Server Initialization
// MinecraftServer.h:124
bool MinecraftServer :: initServer ( __int64 seed , NetworkGameInitData * initData ,
DWORD initSettings , bool findSeed ) {
// 1. Load or generate level
loadLevel (storageSource, name, seed, levelType, initData);
// 2. Initialize dimensions (Overworld, Nether, End)
for ( int dim : { 0 , - 1 , 1 }) {
levels [dim] = createServerLevel (dim);
}
// 3. Start server connection
connection = new ServerConnection ( this );
// 4. Begin ticking
running = true ;
return true ;
}
Server Main Loop
void MinecraftServer :: run ( __int64 seed , void * lpParameter ) {
initServer (seed, initData, settings, findSeed);
__int64 lastTick = currentTimeMillis ();
while (running) {
__int64 now = currentTimeMillis ();
__int64 delta = now - lastTick;
if (delta > MS_PER_TICK) {
tick ();
lastTick = now;
} else {
// Sleep to avoid busy-waiting
Sleep ( 1 );
}
}
stopServer ();
}
Server Shutdown
void MinecraftServer :: stopServer () {
running = false ;
// Save all chunks
saveAllChunks ();
// Disconnect all players
connection -> stop ();
// Clean up levels
for (ServerLevel * level : levels) {
delete level;
}
}
Best Practices
Always use critical sections when accessing shared state: EnterCriticalSection ( & m_setLevelCS);
level = newLevel;
LeaveCriticalSection ( & m_setLevelCS);
Check connection state before sending packets: if (connection && connection -> isStarted () && ! connection -> isClosed ()) {
connection -> send (packet);
}
Networking Deep dive into the network protocol and packet system
Overview High-level architecture and component overview