Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization
Source: https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization Mirror: https://web.archive.org/web/20191214121548/https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization Author: Yahn W. Bernier (Valve), 2001
Overview
FPS Internet play must handle latency/loss even with broadband. Covers client/server architecture, predictive modeling, and lag compensation tradeoffs.
Basic loops
Client: sample input → send movement command with sim time → read server packets → render. Server: read usercmds → execute → simulate server objects → send visible state per client.
Usercmd (Half-Life)
Fields include lerp_msec, msec (frametime), viewangles, forwardmove/sidemove/upmove, buttons. Pure dumb client with 500ms RTT feels unusable on Internet.
Client-side prediction
Store commands; from last server-acked state, replay unacked commands with shared movement code (pm_shared/). Server remains authoritative. Caveats: do not replay footstep/VFX every re-run (mark first-time predicted); client-only fields need sliding window of intermediate states.
Weapon firing prediction
Share weapon logic too; replicate ammo/timers/anims as authoritative state. Avoid client-authoritative "I am at x and I headshot player 2" — cheating.
Leading targets without lag comp
Even with movement prediction, hitscan results wait for server. High latency → must lead moving targets; Quake3 used hit confirmation tones to help players learn lead.
Display of others: extrapolation vs interpolation
Extrapolation: ballistic forward from last state — bad under high jerk / instant turns; limit time (QW ~100ms). Interpolation: render in the past between updates; 100ms buffer at 10 Hz; 200ms survives one loss. Position history (search straddling timestamps) better than "always move toward latest" when update spacing varies with bandwidth choke. Detect teleports (flag or large delta) — do not interpolate across them. HL default: 20 updates/s, 100ms interp; clients may request higher rates.
Lag compensation algorithm
Before executing usercmd: estimate latency; find world update the player had; move other players back accounting for latency and client's interpolation amount (lerp_msec); run command (traces); restore players. Also rewind ancillary state (alive/dead, ducking).
Design implications
Enables aim-at-what-you-see for hitscan. Paradoxes: high-lag shooter can hit low-lag player who already took cover ("shot around a corner"). Valve favored local responsiveness. Head-on fights and unsighted strafers reduce perceived unfairness. Projectiles: HL does not lag-compensate projectile entities (open questions about whose time space they live in); firing sound still predicted.
Conclusion
Lag compensation is a game-design choice; for HL/TFC/CS benefits outweighed inconsistencies.