system-design

Design a Multiplayer Game Server (Real-Time)

Difficulty: Tier 3 Asked at: gaming companies, Amazon (GameLift), Meta, senior loops Time budget: 45–60 min

The finale: a real-time multiplayer game is the most latency-brutal and consistency-brutal system in the repo at once. Dozens of players’ actions must sync across the world in tens of milliseconds, everyone must agree on the game state, and cheaters must be stopped — all while the physics keeps ticking. It pulls together stateful connections, authoritative state, and cheat-resistance. A fitting capstone that reuses half the repo.

Prerequisites: Real-Time Communication, Design a Chat System, Geospatial / Spatial partitioning


1. Requirements

Functional:

Non-functional:

Out of scope: the game’s art/logic, payment/store, the physics engine internals.


2. Estimation


3. The core: authoritative server + state sync

🚨 The server is authoritative — it holds the true game state and simulates the world; clients send inputs and render the state the server sends back. This is the foundation of consistency and cheat resistance: 🚨 never trust the client with authoritative state (a hacked client would cheat).

flowchart TB
    P1[Player 1] <-->|inputs / state, UDP| GS[Game Server<br/>authoritative simulation<br/>tick loop 30-60Hz]
    P2[Player 2] <--> GS
    P3[Player 3] <--> GS
    MM[Matchmaking] -->|assign players| GS
    GS --> State[(Session state<br/>in memory)]
    GS -.persist results.-> DB[(Durable store<br/>stats, progression)]

Each game session runs on a server as a tick loop: gather player inputs → advance the simulation (physics, collisions, rules) → broadcast the new authoritative state to all players → repeat 30–60×/sec.


4. Deep dives

4a. Latency hiding — client prediction & reconciliation

Even at tens of ms, waiting for the server round-trip before showing your own movement feels laggy. So clients predict locally (apply your input immediately) and reconcile when the authoritative state arrives (correct any divergence, smoothly). Other players’ positions are interpolated between received states (and slightly delayed) for smoothness. 🚨 Client prediction + server reconciliation + interpolation is how games feel instant despite network latency — the signature technique.

4b. Why UDP, not TCP

🚨 Games use UDP, not TCP. TCP’s ordered, reliable, retransmit-everything behavior causes head-of-line blocking — a lost packet stalls everything, and an old position retransmitted is useless (you want the latest, not the missed old one). UDP sends fast, unordered, lossy datagrams; the game handles what little reliability it needs at the app layer (e.g. resend critical events, ignore stale positions). Fresh-over- complete is the right trade for real-time state. (Real-Time Communication)

4c. The authoritative tick loop & consistency

The server resolves all conflicts deterministically each tick (who hit whom, using server-side positions and timestamps), so every player agrees on the outcome — no client can claim “I shot first.” Lag compensation: the server rewinds to the shooter’s view-time to fairly adjudicate hits despite latency. This authoritative, tick-based resolution is what gives consistency in a chaotic real-time world.

4d. Matchmaking

Group players into sessions by skill (rating), region (latency — put players on a nearby server), and mode. It’s a matching/queueing problem: players enter a queue, matchmaker forms balanced groups, assigns them to a game server (spun up on demand near them). Balance match quality vs wait time. Sessions are then handed to a game server from a fleet (autoscaled).

4e. Cheat prevention

Clients are untrusted and actively hacked. Defenses: 🚨 server-authoritative state (the big one — the server validates every action; a client can’t teleport or shoot through walls because the server simulates truth), server-side validation of inputs (is this move physically possible?), anti-cheat detection (statistical anomalies), and not sending clients data they shouldn’t see (e.g. don’t send enemy positions behind walls → prevents wallhacks). Never trust the client is the through-line.

4f. Scaling & session management

Each session is a stateful, in-memory simulation on a server (like a shard). Scale by running many independent sessions across a fleet — sessions don’t interact, so this scales horizontally by adding servers (like partitioning by session). Handle server failure (a crashed session is bad — replicate critical state or accept match loss); place servers regionally for latency. Reconnect logic restores a dropped player into the ongoing session.


5. Bottlenecks & scaling further

  1. Latency → UDP, client prediction/reconciliation, interpolation, regional servers.
  2. Consistency → authoritative server tick loop with deterministic resolution + lag compensation.
  3. Cheating → server-authoritative + input validation + minimal client info.
  4. Scale → many independent sessions across an autoscaled fleet (partition by session).
  5. Matchmaking → queue + skill/region-based grouping; balance quality vs wait.
  6. Disconnects → reconnect into the running session; handle jitter/loss gracefully.

6. Trade-off summary

Decision Chosen Alternative Why
Authority Server-authoritative Client-authoritative / P2P Consistency + cheat resistance
Transport UDP TCP Fresh-over-complete; no head-of-line blocking
Perceived latency Client prediction + reconciliation Wait for server Feels instant despite real latency
Consistency Authoritative tick + lag compensation Trust client claims Fair, agreed outcomes
Scale Independent sessions on a fleet One big server Sessions don’t interact; scale horizontally
Anti-cheat Never trust client + validate Trust client Clients are hacked

7. Follow-up questions

Why must the server be authoritative, and what does that give you? Because the clients are untrusted — players hack them — so if the client held the authoritative game state or its claims were believed, cheating would be trivial (teleport, infinite health, shoot through walls). Making the server authoritative means the server holds the one true game state, simulates the world each tick, and treats client messages only as *inputs* to validate and apply, not as facts to accept. This gives you two things at once. First, consistency: since a single authoritative simulation resolves every interaction deterministically (using server-side positions and timestamps), all players agree on outcomes — there's a single source of truth for "who shot first," rather than conflicting client claims. Second, cheat resistance: the server validates that each action is legal (is this move physically possible? is this shot line-of-sight valid?) and rejects impossible ones, so a hacked client can't do things the rules forbid because the server, not the client, decides what actually happens. "Never trust the client" is the through-line of multiplayer design, and server authority is how it's enforced.
If the server is authoritative, how does the game still feel instant despite network latency? Through client-side prediction, server reconciliation, and interpolation. When you press move, the client immediately applies the input locally and shows your character moving — predicting what the authoritative server will do — so your own actions feel instant instead of waiting for a round-trip. Meanwhile the input also goes to the server, which simulates authoritatively and sends back the true state; the client reconciles its predicted state against that authoritative state, correcting any divergence smoothly (usually small, since the prediction is usually right). For *other* players, the client interpolates their positions between the state updates it receives (rendering them slightly in the past) so their movement looks smooth despite arriving as discrete, occasionally-late packets. Together these hide latency: your own actions are predicted for immediacy, others' are interpolated for smoothness, and the authoritative server keeps everyone eventually consistent while correcting mispredictions. This trio — predict locally, reconcile with the server, interpolate others — is the signature technique that makes fast-paced online games playable over real networks.
Why do games use UDP instead of TCP? Because real-time games want the *freshest* data fast, and TCP's guarantees actively work against that. TCP provides reliable, in-order delivery by retransmitting lost packets and holding back later data until the missing piece arrives — head-of-line blocking — which means one dropped packet stalls the whole stream, adding latency spikes that ruin gameplay. And TCP's reliability is often useless here: if a player-position update is lost, you don't want it retransmitted later, because by then a newer position has superseded it — the stale old one is worthless. UDP sends fast, unordered, best-effort datagrams with no retransmission or ordering overhead, so a lost packet is simply skipped and the next fresh update arrives on time. The game then adds back *only* the reliability it actually needs at the application layer — for example, resending critical, non-superseded events (a player died) while letting continuous state updates be lossy. This "fresh over complete" trade-off is exactly right for real-time state, which is why UDP (and UDP-based protocols) dominate multiplayer networking.
How do you scale to millions of concurrent players? By exploiting that game sessions are independent and scaling them horizontally across a fleet, like partitioning by session. Players are grouped by matchmaking into sessions of a few to a hundred players, and each session is a self-contained, in-memory authoritative simulation running on a game server — sessions don't interact with each other, so there's no cross-session coordination. To handle millions of players you run tens of thousands of these independent sessions across a large, autoscaled fleet of game servers, spinning servers up as matchmaking creates sessions and tearing them down as matches end, and placing servers in regions close to their players to minimize latency. This is the same "partition into independent units and add machines" scaling used for ride-hailing (by geography) or a matching engine (by symbol) — here the independent unit is the match. The remaining concerns are operational: matchmaking as a queueing/grouping service, regional placement for latency, autoscaling for the fleet, and handling server failure (replicating critical state or accepting the loss of a match) and player reconnects into ongoing sessions.

8. What junior / mid / senior answers look like


Further reading