Solving the Latency Gap: Prediction and Reconciliation in Source Engine
Explore how the Source Engine uses client-side prediction and server reconciliation to eliminate input lag while maintaining an authoritative server state.
11 Oct 2025, 11:25 UTC

The Problem: The 'Input Lag' Paradox
In a multiplayer game, the server is the final authority on where every player is located. If a client waited for the server to acknowledge a movement keypress before updating the screen, a player with 100ms of latency would feel a jarring delay between pressing 'W' and actually moving. This makes precise movement impossible.
The Source Engine solves this using Client-Side Prediction and Server Reconciliation. The goal is to decouple the player's perceived responsiveness from the network round-trip time (RTT) while maintaining a single, authoritative game state.
How Prediction Masks Latency
Instead of waiting for the server, the client runs a local version of the movement physics. When you press a key, the client immediately simulates the result and moves your character forward. To the player, the game feels like a local single-player experience.
However, the client is essentially "guessing" that the server will agree with its movement. The client sends these input commands to the server, tagged with a sequence number. The server then processes these inputs and sends back a snapshot of the "true" position of the player.
Correcting the Drift: Reconciliation
Because the server might have encountered a collision the client missed (like another player blocking a doorway), the server's authoritative position may differ from the client's predicted position. This is where Reconciliation occurs.
When the client receives a server snapshot, it checks if the server's position for a specific command sequence matches its own recorded position for that same sequence. If they differ, the client performs a "snap-back" and a "fast-forward":
- Rewind: The client resets the player's position to the last known-good state provided by the server.
- Re-simulate: The client re-runs all inputs that have been sent but not yet acknowledged by the server, effectively "replaying" the movement from the corrected position to the present moment.
Worked Example: The 66-Tick Jump
Consider a player on a 66-tick server (where the game updates every ~15ms) with a 50ms ping. Here is the lifecycle of a single jump input:
| Time (ms) | Client Action | Server Action | Result |
|---|---|---|---|
| 0 | Presses Jump; predicts upward velocity immediately. | Idle | Player sees character jump instantly. |
| 25 | Continues predicting upward arc. | Receives Jump command; calculates physics. | Server agrees jump is valid. |
| 50 | Predicts peak of jump. | Sends snapshot confirming position at T=25. | Packet in transit. |
| 75 | Receives snapshot for T=25. | Idle | Client compares predicted T=25 vs Server T=25. |
If the server snapshot at T=75 showed the player was actually blocked by a low ceiling, the client would instantly snap the player down to the ceiling height and re-simulate the movement from T=25 to T=75 in a single frame, correcting the error.
The Trade-off: The 'Shot Around the Corner' Effect
To make combat feel fair, Source uses Lag Compensation. When a player fires a weapon, the server doesn't check where the target is now; it rewinds the target's position to where they were when the shooter actually saw them (based on the shooter's latency and interpolation).
While this ensures you don't have to "lead" your shots based on ping, it creates a specific artifact: you may be killed by a player even after you have moved behind a wall on your own screen, because on the attacker's screen (and the server's rewind), you were still exposed.
Practical Verification
You can observe these systems in action in most Source-based games via the developer console (typically the ~ key). To see the impact of prediction, try the following:
- Enable the network graph to monitor packet loss and ping:
net_graph 1. - Disable client-side prediction:
cl_predict 0. - Attempt to move. You will notice a heavy delay (equal to your RTT) between your input and the character's movement.
- Re-enable prediction:
cl_predict 1to restore responsiveness.
Note: Changing these settings may be restricted in competitive matchmaking environments to prevent cheating or unfair advantages.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.