Client-side prediction is a technique used in multiplayer games to reduce (the appearance of) lag: each player’s machine runs its own simulation of what should happen next, and then quickly syncs with the server’s “official” version of events. In this article, we’ll look at why we’d want to do this in the first place.
This technique became popular when networked games like Quake (whose source code is available on GitHub) started popping up. The available networking speeds at the time were not so fast – especially for the internet – so attempting to keep all players synced perfectly with the server gave poor results.
Understanding the Problem
To start explaining the problem let’s understand where it comes from.
At a first look, the problem that client-side prediction solves just doesn’t exist!
A non-authoritative server setup.
Everything is simple: the player moves their character and the game tells the server the new position; the server then passes this new position on to the other players, whose clients update the position of the first player in-game. That’s it.
But what if the player modifies the game to make it pass a different position to the server?
Passing a fake value.
Cheating! The server will trust the player’s new position of
(39, 4), even though the player is some considerable distance away, and will update the other clients accordingly. The cheater can then effectively teleport, making the game unplayable for the other players.
Since cheating is so easy, we need a new solution. What if the server had total control over the game state?
With the authoritative server version of the game, the flow will look like this:
An authoritative server setup.
Here, the client tells the server, “I want to move the character to the right”; the server processes this, and decides that this means that the character should now be at
(1, 0); the server then tells all the players’ clients that the first player’s character should be at
(1, 0); and all the players see the character move to the new position.
Problem solved, right? Not entirely…
The New Problem
The teleportation problem was mostly avoided, but the latency problem was introduced. The client needs to wait for the server’s response about their intent to move before displaying the movement to the player. This workflow makes the game feels laggy on average connections and almost unplayable on poor ones.
Lag is introduced between the “intent” and “move” phases.
Client-side prediction refines the above model. During the phase when the client has sent the intent and is waiting for the server’s response, it will display the movement that it predicts will happen:
This avoids the sensation of lag by removing the waiting time between the player’s input and the displayed output.
The simulation that occurs on the client should have the same outcome as the simulation that occurs on the server, but there are exceptions – for instance, if two players attempt to move to the same spot at once, one will be forced out. When the server’s response is sent to the client, the client just needs to confirm that it matches its own prediction; if it doesn’t, then the client needs to use the server’s response as the true information source and discard the prediction to fix the client’s state.
I hope this article helps you to understand this useful technique for network games that need to avoid the majority of cheating problems while also avoiding lag.