Game Development

Netcode: Prediction and Reconciliation

2020. Riot Games launched Valorant with the promise that 'cheaters do not exist'. Part of that promise is the netcode architecture: client-side prediction with reconciliation on 128-tick servers. A player in Stockholm at 15 ms ping and a player in Delhi at 90 ms ping must have a fair fight. Riot engineers spent two years on netcode - and it shows: Valorant has fewer complaints about 'wrong hits' than CS:GO with a comparable architecture.

  • **Valorant** uses client-side prediction with 128-tick servers and lag compensation up to 140 ms. The tick rate is twice that of CS:GO (64 ticks) - this halves positional error.
  • **Guilty Gear Strive** (Arc System Works, 2021) was the first major fighting game with GGPO rollback netcode. The fighting game community notes: online matches at 100 ms ping became indistinguishable from local co-op.
  • **Apex Legends** (Respawn) uses hybrid interpolation: 60 Hz server, snapshot interpolation for opponents, prediction for the local character. Dead Reckoning (extrapolation) on packet loss - smoothness is preserved even at 10% packet loss.

Client-Side Prediction: Responsiveness Without Waiting

At 100 ms ping without prediction, every key press causes a 100 ms delay before movement - controls feel like operating a character through deep-sea cables. Client-side prediction: the client applies input immediately without waiting for a server response. The character moves instantly on the client while the server processes the same input in parallel. When the server response arrives, the client compares its predicted state to the authoritative server state. If they match - nothing happens. If there is a discrepancy - reconciliation is needed. Valve introduced this pattern in Half-Life (1998), and it is now the standard in Unreal Engine (Character Movement Component), Unity Netcode, and Mirror Networking.

Input buffer: the client stores a history of all unacknowledged inputs with timestamps. When a server acknowledgment arrives for tick N, the client discards all inputs up to and including N from the buffer.

Why does the client store a history of unacknowledged inputs in a buffer?

Server Authority and Reconciliation

Prediction makes controls responsive, but creates a problem: the client's local state may diverge from the authoritative server state. The server processes the same inputs but may have seen collisions the client missed (another player blocked the path). Reconciliation is the process of correcting the prediction. The Valve/Source Engine scheme: 1) receive server state at tick N, 2) rewind local state to the server state, 3) replay all buffered inputs from tick N+1 to the current tick. Visually this looks like a sudden teleport - 'rubber-banding'. To avoid this, smoothing is applied: visually move the visual object toward the predicted position while the physics position is corrected.

Error threshold: not every discrepancy requires reconciliation. An error under 5-10 pixels is the result of float rounding, not a real divergence. Only substantial discrepancies warrant a full input replay.

Rubber-banding (a character suddenly teleporting) is a symptom of what?

Rollback Netcode: Rewinding the Simulation

Fighting games require reaction times of 1/60 second - one frame. At 100 ms ping, classic delay-based netcode adds 3-4 frames of lag to every action - a disaster for the genre. Rollback netcode (GGPO, 2008): the client predicts the opponent's input (usually 'repeat last input'), simulates the game with the predicted input, and renders the frame immediately. When the real input arrives, if the prediction was wrong - roll back the simulation to the point of divergence and replay with the correct input. If the prediction was correct - nothing happens. Guilty Gear Strive, Street Fighter 6, Mortal Kombat 11 - all use GGPO or variations of it.

Rollback of N frames requires N saved simulation states. For 8 frames with an ECS holding 1000 entities - that is 8 state snapshots. State compression is critical: only changed components. GGPO limits rollback to 8 frames (133 ms) - beyond that, the game adds artificial input delay.

Rollback netcode predicts opponent input as 'repeat last'. Why does this work well enough?

Snapshot Interpolation: Smoothness Without Prediction

For entities the player does not control (other players, NPCs), prediction is inapplicable - arbitrary input cannot be predicted. Snapshot interpolation solves this: instead of predicting, smoothly interpolate between the two most recently received snapshots. The client renders state that was in the past (by the interpolation delay - typically 2-3 ticks). It looks perfectly smooth, with a small visual lag. Overwatch uses 64 ms interpolation for other players: visually smooth, and the delay is imperceptible for a spectator. For the controlled character - prediction without interpolation.

Extrapolation as an alternative: continue an object's movement trajectory beyond the last snapshot. Lower latency, but artifacts when direction changes ('running through walls'). Most games use interpolation for other players, not extrapolation.

Snapshot interpolation adds a visual delay for other players. Why is this trade-off accepted?

Key Ideas

  • **Client-side prediction** applies input immediately without waiting for the server - controls feel instant at any ping.
  • **Reconciliation** corrects prediction divergence from authoritative server state by replaying input history; visual smoothing hides the correction.
  • **Rollback netcode** (GGPO) lets fighting games work without perceptible delay: predict - render frame - on mismatch roll back and re-simulate.
  • **Snapshot interpolation** provides smoothness for objects with unknown input (other players) at the cost of 100-150 ms visual delay.

Related Topics

Prediction and reconciliation are the next layer above multiplayer networking:

  • Multiplayer Networking — Client-side prediction solves the main weakness of the authoritative server - latency; it is the next evolution of the same architecture
  • Physics Engine — Deterministic physics simulation is required for reconciliation: client and server must produce identical results from the same data

Вопросы для размышления

  • During reconciliation, the client replays input history. If the history spans 60 frames (1 second of lag), the replay may take longer than one frame. How do modern engines address this?
  • Rollback netcode requires saving the full simulation state every frame. How do you optimize this for a game with 10,000 dynamic objects?
  • Snapshot interpolation delays display by 100 ms. In which game genre is this completely unacceptable, and why?

Связанные уроки

  • net-14-udp
Netcode: Prediction and Reconciliation

0

1

Sign In