HTML and CSS Reference
These sections have covered several important problems in network programming. The following section
discusses two very different approaches that deal with these problems in different ways.
State Broadcast vs. Lockstep
The most intuitive approach to network programming is the Lockstep method , whereby the server performs the
initial sync and then broadcasts only player actions, with the expectation that all players will simulate exactly the
same game. Although the lockstep method is the most bandwidth-efficient approach, it suffers from many issues.
First, it requires that each client processes the same actions at the same time. This means that any packet loss or
out-of-order packets are unacceptable. Second, the game engine must be entirely deterministic, with no randomness
(but note that it is possible to use pseudorandom numbers, so long as all clients share the same seed, or the random
numbers are presented in advance from the server). Third, the use of floating point in these systems is problematic,
as floating-point computations vary slightly from one machine to another, and these differences can accumulate
until the clients are out of sync. Note that the use of floating-point numbers outside the game engine is fine; so
long as they have no effect on the game, they can be used in displaying graphics, audio processing, and so on with
Another approach is the state broadcast method , iwhereby the server broadcasts the complete game state to all
clients, and each client replaces his or her own game state with the server copy periodically. Although this approach
ensures that the server automatically resolves any synchronization issues, it also dramatically increases the amount
of bandwidth that the server must use. For example, if the game state is 1KB, and there are 32 players in the game,
the server would have to upload 320KB per second to send the ten updates per second necessary to create a smooth
experience. For games such as Minecraft , which has a game state on the order of megabytes, this approach is
intractable. Note that, even when applying the state broadcast method, clients still need to share actions so that they
can fast-forward (for more information, see the section “Fast-Forwarding the Game State”).
Dealing with Latency
Regardless of which method is used, the problem of latency has to be addressed. Note that a single player's latency is
the amount of time it takes for data to travel from his or her computer to the server. For a client-server architecture,
the state latency is the time between when a player requests an action on his or her machine and when that action
reaches the player with the most latent connection. When a player takes an action, the server delays the action by the
state latency. The expectation is that the client's action reaches all other players in time for everyone to execute the
action at exactly the same time. If the server delays the action by too much, the game will not feel responsive, making
it hard for the player to time his or her actions precisely. If the server delays the action by too little, the game is frozen
until players can receive overdue messages, and this can cause stuttering, throwing off the rhythm of the game.
One of the challenges in real-time multiplayer network programming is latency prediction , estimating the latency
among all machines in the game. When the prediction is not accurate, latency can cause stuttering in the game play
or intermittent pausing. Even with accurate latency prediction, the delay between physically pressing a button and
seeing the effect of that press can be disorienting. To address these problems, one can add client-side prediction . With
client-side prediction, each client stores two copies of the game state: one copy that contains completely accurate
information but that is delayed because of latency and another that is current but that assumes that no other clients
have sent any new actions. As the client receives new actions or game states from the server, the client updates his or
her delayed copy of the game state, replaces the current copy with a copy of the delayed game state, and fast-forwards
the newly copied state to the present time (see Figure 12-2 ). This technique gives the illusion of responding to player
actions immediately, while also correcting the state as it goes out of sync.