Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Minecraft-Community-Edition/client/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Minecraft Community Edition supports both split-screen local multiplayer and network multiplayer. The game uses a client-server architecture where one instance acts as the authoritative server and others connect as clients.
Multiplayer Architecture
Client-Server Model
// Server side
class MinecraftServer {
ServerConnection* connection; // Network listener
PlayerList* players; // Connected players
ServerLevelArray levels; // Authoritative worlds
};
// Client side
class MultiPlayerLevel : public Level {
vector<ClientConnection*> connections; // Server connections
MultiPlayerChunkCache* chunkCache; // Received chunks
};
Location: MinecraftServer.cpp:69 and MultiPlayerLevel.cpp:26
Network Flow
┌─────────────┐ Packets ┌─────────────┐
│ Client │ ─────────────────> │ Server │
│ │ │ │
│ LocalPlayer │ <───────────────── │ServerPlayer │
└─────────────┘ Updates/Sync └─────────────┘
│ │
▼ ▼
MultiPlayerLevel ServerLevel (x3)
Split-Screen Local Multiplayer
Local Player Management
Up to 4 players can play on the same console:
class Minecraft {
shared_ptr<MultiplayerLocalPlayer> localplayers[XUSER_MAX_COUNT];
GameMode* localgameModes[XUSER_MAX_COUNT];
ItemInHandRenderer* localitemInHandRenderers[XUSER_MAX_COUNT];
int localPlayerIdx; // Currently active player
};
Location: Minecraft.h (referenced in Minecraft.cpp:861)
Adding Local Players
bool Minecraft::addLocalPlayer(int idx) {
// Create temporary player for connecting screen
localplayers[idx] = make_shared<MultiplayerLocalPlayer>(
this, level, user, NULL
);
localgameModes[idx] = NULL;
// Add to network session
g_NetworkManager.AddLocalPlayerByUserIndex(idx);
updatePlayerViewportAssignments();
return true;
}
Location: Minecraft.cpp:989
Viewport Assignment
Players are assigned screen regions based on count:
1 Player: Full screen
2 Players: Split horizontally or vertically
if (splitScreenVertical) {
VIEWPORT_TYPE_SPLIT_LEFT
VIEWPORT_TYPE_SPLIT_RIGHT
} else {
VIEWPORT_TYPE_SPLIT_TOP
VIEWPORT_TYPE_SPLIT_BOTTOM
}
3-4 Players: Quadrants
VIEWPORT_TYPE_QUADRANT_TOP_LEFT
VIEWPORT_TYPE_QUADRANT_TOP_RIGHT
VIEWPORT_TYPE_QUADRANT_BOTTOM_LEFT
VIEWPORT_TYPE_QUADRANT_BOTTOM_RIGHT
Location: Minecraft.cpp:883-986
Network Multiplayer
Connection Establishment
class ServerConnection {
public:
void listen(); // Accept incoming connections
void tick(); // Process network packets
};
class ClientConnection {
public:
void connect(string host, int port);
void sendPacket(shared_ptr<Packet> packet);
void tick(); // Handle received packets
};
Default Port: 25565 (Minecraft standard)
Location: Referenced in MinecraftServer.cpp:168
Player Connection Lifecycle
1. Connection Request
ClientConnection* connection = new ClientConnection();
connection->connect(serverIp, port);
2. Login Handshake
// Client sends login packet
LoginPacket* login = new LoginPacket();
login->username = playerName;
login->protocolVersion = VERSION;
connection->send(login);
3. World Sync
// Server sends level data
LevelDataPacket* levelData = new LevelDataPacket();
levelData->seed = level->getSeed();
levelData->gameType = level->getGameType();
connection->send(levelData);
// Server sends spawn chunks
for (ChunkPos pos : spawnChunks) {
connection->send(new ChunkDataPacket(pos));
}
4. Player Spawn
// Server spawns player
ServerPlayer* player = new ServerPlayer(server, level, username);
player->moveTo(spawnX, spawnY, spawnZ);
level->addEntity(player);
// Broadcast to other players
players->broadcastAll(
new AddPlayerPacket(player)
);
5. Disconnect
void ClientConnection::disconnect(DisconnectReason reason) {
sendAndDisconnect(
new DisconnectPacket(reason)
);
}
Player Synchronization
Server Player
The authoritative representation:
class ServerPlayer : public Player {
ClientConnection* connection;
ChunkPos lastChunk;
public:
void tick() override;
void sendInventory();
void broadcastMove();
};
Updates Sent:
- Position and rotation
- Health and hunger
- Inventory changes
- Experience
- Effects (potion, fire, drowning)
Client Player
Client-side prediction and rendering:
class MultiplayerLocalPlayer : public LocalPlayer {
ClientConnection* connection;
public:
void tick() override;
void sendInput();
void applyServerUpdate();
};
Updates Sent:
- Input (movement, jumping, crouching)
- Block breaking/placing
- Item usage
- Inventory actions
World Synchronization
Chunk Packets
Chunks are sent as the player moves:
class ChunkDataPacket : public Packet {
public:
int x, z; // Chunk coordinates
bool groundUp; // Full chunk
int availableSections; // Section bitmask
byte* data; // Compressed chunk data
int dataLength;
};
Compression:
- Chunks are zlib compressed
- Reduces network bandwidth by ~80%
- Client decompresses on receive
Location: Referenced in MultiPlayerLevel.cpp:876
Chunk Unloading
void MultiPlayerLevel::setChunkVisible(int x, int z, bool visible) {
if (visible) {
chunkCache->create(x, z);
} else {
chunkCache->drop(x, z);
setTilesDirty(x*16, 0, z*16,
x*16+15, maxBuildHeight, z*16+15);
}
}
Location: MultiPlayerLevel.cpp:389
Block Updates
Single Block:
class TileUpdatePacket : public Packet {
public:
int x, y, z;
int tile;
int data;
};
Multiple Blocks:
class ChunkTilesUpdatePacket : public Packet {
public:
int xChunk, zChunk;
vector<short> offsets; // Relative positions
vector<byte> tiles; // Block IDs
vector<byte> data; // Block data
};
Block Change Tracking
Client changes are reverted pending server confirmation:
struct ResetInfo {
int x, y, z;
int ticks; // Time until reset
int tile; // Original block
int data;
};
vector<ResetInfo> updatesToReset;
if (--r.ticks == 0) {
Level::setTileAndDataNoUpdate(r.x, r.y, r.z, r.tile, r.data);
}
Location: MultiPlayerLevel.cpp:16-24 and MultiPlayerLevel.cpp:127-150
Entity Synchronization
Entity Spawning
class AddEntityPacket : public Packet {
public:
int entityId;
eINSTANCEOF type;
int x, y, z; // Position (* 32 for fixed point)
byte yRot, xRot; // Rotation
};
Location: Referenced in tracking system
Movement Packets
Small Movement (relative):
class MoveEntityPacket : public Packet {
public:
int entityId;
byte dx, dy, dz; // Delta * 32
};
Large Movement (absolute):
class TeleportEntityPacket : public Packet {
public:
int entityId;
int x, y, z; // Absolute * 32
byte yRot, xRot;
};
Entity Data Updates
class SetEntityDataPacket : public Packet {
public:
int entityId;
map<int, DataItem*> data; // Changed values only
};
Sent when:
- Entity on fire state changes
- Crouching/sprinting changes
- Drowning bubbles change
- Name tag changes (if supported)
Entity Removal
class RemoveEntityPacket : public Packet {
public:
int entityId;
};
Connection Management
Client Connection
class ClientConnection {
SavedDataStorage* savedDataStorage; // Shared with server
bool connected;
int timeoutCounter;
public:
void tick();
void send(shared_ptr<Packet> packet);
void handlePacket(shared_ptr<Packet> packet);
};
Timeout Detection:
if (++timeoutCounter > 20*30) { // 30 seconds
disconnect(DisconnectPacket::eDisconnect_Timeout);
}
Location: Referenced in MultiPlayerLevel.cpp:44
Server Connection
class ServerConnection {
MinecraftServer* server;
vector<ClientConnection*> connections;
public:
void tick(); // Tick all connections
void broadcast(shared_ptr<Packet> packet);
};
Location: MinecraftServer.cpp:168
Pending Connections
Local players connecting to local server:
ClientConnection* m_pendingLocalConnections[XUSER_MAX_COUNT];
bool m_connectionFailed[XUSER_MAX_COUNT];
void Minecraft::addPendingLocalConnection(int idx,
ClientConnection* conn) {
m_pendingLocalConnections[idx] = conn;
}
Location: Minecraft.cpp:1049
Packet Processing
Server-Side Handling
void ServerConnection::tick() {
for (ClientConnection* conn : connections) {
while (Packet* packet = conn->receive()) {
switch(packet->getType()) {
case PLAYER_INPUT:
handlePlayerInput(conn, packet);
break;
case PLAYER_ACTION:
handlePlayerAction(conn, packet);
break;
case USE_ITEM:
handleUseItem(conn, packet);
break;
}
}
}
}
Client-Side Handling
void ClientConnection::tick() {
while (Packet* packet = receive()) {
switch(packet->getType()) {
case CHUNK_DATA:
handleChunkData(packet);
break;
case ADD_ENTITY:
handleAddEntity(packet);
break;
case MOVE_ENTITY:
handleMoveEntity(packet);
break;
case TILE_UPDATE:
handleTileUpdate(packet);
break;
}
}
}
Location: Connection tick methods in MultiPlayerLevel.cpp:118
Disconnect Handling
Disconnect Reasons
enum DisconnectReason {
eDisconnect_None,
eDisconnect_Quitting,
eDisconnect_Timeout,
eDisconnect_Kicked,
eDisconnect_SignOut,
eDisconnect_NetworkError
};
Graceful Disconnect
void MultiPlayerLevel::disconnect(bool sendDisconnect) {
if (sendDisconnect) {
for (ClientConnection* conn : connections) {
conn->sendAndDisconnect(
new DisconnectPacket(eDisconnect_Quitting)
);
}
} else {
for (ClientConnection* conn : connections) {
conn->close();
}
}
}
Location: MultiPlayerLevel.cpp:606
Removing Players
void Minecraft::removeLocalPlayerIdx(int idx) {
if (localgameModes[idx] != NULL) {
MultiPlayerLevel* mpLevel =
(MultiPlayerLevel*)getLevel(localplayers[idx]->dimension);
mpLevel->removeClientConnection(
localplayers[idx]->connection, true
);
g_NetworkManager.RemoveLocalPlayerByUserIndex(idx);
getLevel(localplayers[idx]->dimension)->removeEntity(
localplayers[idx]
);
delete localgameModes[idx];
localgameModes[idx] = NULL;
}
localplayers[idx] = nullptr;
updatePlayerViewportAssignments();
}
Location: Minecraft.cpp:1163
Network Optimization
Slow Queue System
Reduces packet spam for less critical updates:
static int s_slowQueuePlayerIndex = 0;
static int s_slowQueueLastTime = 0;
static bool s_slowQueuePacketSent = false;
void MinecraftServer::cycleSlowQueueIndex() {
s_slowQueuePlayerIndex =
(s_slowQueuePlayerIndex + 1) % players->count();
}
Used For:
- Entity metadata updates
- Non-critical inventory syncs
- Effect particles
Location: MinecraftServer.cpp:63-65
Packet Batching
Multiple small packets combined:
ChunkTilesUpdatePacket* packet = new ChunkTilesUpdatePacket();
for (TileUpdate update : pendingUpdates) {
packet->add(update.x, update.y, update.z,
update.tile, update.data);
}
broadcast(packet);
Update Frequency
Different update rates for different data:
- Position: Every tick (20 TPS)
- Health: On change only
- Inventory: On change only
- Time: Every 20 ticks (1 second)
- Chunk visibility: On enter/exit range
Location: MinecraftServer.cpp:1477
Key Takeaways
- Client-Server Model: One authoritative server, multiple clients
- Split-Screen Support: Up to 4 local players with separate viewports
- Chunk Streaming: Dynamic loading as players explore
- Entity Tracking: Only entities in range are synchronized
- Prediction: Client predicts movement, server corrects
- Compression: Chunk data compressed for bandwidth efficiency