Game Networking Protocols

This section discusses in high-level terms the various techniques used to organize the transmission and reception of game data. If you are looking for information on Internet protocols (TCP/IP, UDP), see the previous section.

Game-networking protocols for LAN games can be organized on a two-axis grid where one axis shows how they synchronize with each other and the other axis contains the kind of data they communicate.

Lock-Step versus Open-Loop Asynchronous Synchronization

Lock-Step

Lock-step games arise naturally from the basic single-player game model. In a typical single-player game, controllers are read once a frame, new positions calculated, and game logic handled. A resulting frame is then rendered and flipped to the screen. (See Chapter 2, “Fundamentals of Game Programming.”)

A lock-step game works in almost the same way. After it reads the controllers, however, it sends a packet with that data to all the other players in the game. It then waits until all the players have in turn sent it a packet with their controller data before calculating the results. If you think of a real-time game as really a turn-based game where every “move” is one frame in size, then a lock-step game requires that everyone make his move before the game figures the results.

Lock-step games are probably the easiest models to program because they fit so well into what is already in the game. It is also relatively easy to add cheat protection to these games. By sending some data every so often on the state of the game and the controllers, the game sessions can “sanity-check” each other. If one client is saying the world is in a different state than the others, clearly a cheat or a bug is happening.

When creating lock-step multiplayer games, special attention must be paid to random events. Most games contain random elements. It is important that all players use the same random-number generator with the same current seed so the same random events happen at the same time and in the same way in each game session. Usually the host provides the seed on client connection.

The only downside to this approach is that everyone must report his input for the game to continue. This limitation makes lock-step games totally inappropriate for Internet play where latency spikes can stop the game cold in its tracks. It also means that everyone’s frame rate is tied to that of the slowest player. In general, however, for LAN-based games, a lock-step game isn’t a bad solution.

Open-Loop Asynchronous

Open-loop asynchronous games are very different from lock-step games. These games are based on the idea that small errors you can’t see don’t matter. They relax the requirement that everyone’s gameplay be exactly synchronized and in doing so escape the frame-by-frame problems of lock-step games.

An open-loop asynchronous game is always running around its game loop at the fastest speed it can handle. Periodically, it gets updates about where the other players were and what they were up to at a given time in the past. Based on those updates it adjusts the other players in its game model. Between updates it guesses what the other players will be doing. Such guesses are called dead reckoning, a term invented by the military for military simulations. When an update for a dead-reckoned object comes in, the guesses are adjusted to bring them back in line with what the other player is actually doing.

A variety of techniques are available for making that guess and the subsequent adjustment. Simple adjustments just move the player directly to where he should be, correcting for movement and time elapsed. Such adjustment, although easy to implement, results in the effect game players call “warping,” where an object in the world suddenly jumps discontinuously from one place to another. This is a visible and potentially frustrating artifact.

To hide warping, open-loop asynchronous games typically implement some form of interpolation between the old and new positions. The problem is similar to color dithering. When an update comes in, you derive an error term for both position and motion vector. You then add part of that error term in every subsequent frame until you have reduced it to 0.

Another issue with open-loop asynchronous games is the question of world state. In a lock-step game, everyone has a complete and correct picture of an identical world state. In an open-loop asynchronous game, everyone has a correct idea of his own state and an approximate idea of everyone else’s. This is generally fine until you hit player-to-player interactions, such as combat. Suppose in my world state I see you in my crosshairs, but in your world state you aren’t. I pull the trigger. Are you hit or not?

There is no way to actually reconcile the two views in an open-loop game. However, it is usually possible to pick the best view. In a first-person shooter game, for instance, the person doing the shooting has a reticle and can see exactly where he is aiming, but his target has only a general idea of where the shooter is pointing his gun. The result of this analysis is the conclusion that the shooter should decide if it is a hit or miss and communicate that fact to everyone else. In general, there is always a preferred viewpoint in any situation like this.

Open-loop asynchronous games have a number of great qualities for Internet games. They are reasonably latency-immune, and each player runs at his maximum frame rate. Unfortunately, they have one great weakness—security. In the previous example, the shooter is sending a packet to everyone saying, “I shot Jane!” All it takes is a little hack to the shooter’s program so it always sends “I shot whoever” packets rather than “I missed whoever” packets, and you have a player who cannot miss. Various game-specific and partially complete approaches can partially solve this problem, but a complete general solution has not been found. Therefore, it remains a big issue that must be addressed in the design of any open-loop game today.

In practice most Internet games today are modified open-loop games where one of the “players” is a server controlled by the game maker. Generally, this server is considered the one true arbiter of key game decisions. A LAN game could use a similar technique where the host acted as the server, but in practice, LAN games don’t suffer from the same cheating problems Internet games do. After all, if Fred-who is in the next cubicle cheats, you can just reach out and slap him.

Controller-State versus Object-State Communication

The first networked games used controller-state communication. This type of communication extends naturally from a simple single-player game model. Once a frame, the game would read the controllers (see Chapter 11, “Java Native Interface”) and send a packet to all the other players telling them what was read.

This kind of communication can be rather verbose (one packet per player per frame) and does not provide enough information to guess what the next packet will be. (See the previous discussion of dead reckoning in “Open-Loop Synchronous.”) It is well suited to lock-step games but not to open-loop asynchronous games. Nonetheless, hybrids are out there that cross many of these techniques, so it really is a separate (though related) decision from your game-synchronization model.

Object-state communication is different. Rather then sending a raw packet saying, “In this frame, my controllers are doing this,” the effect of the user’s actions on his in-game representation is calculated first, and then a packet containing his entire state is sent to other players. This packet is time stamped. When it arrives at the other players’ computers, the computer calculates the player’s current state based on the state sent and the time it took to arrive.

Consider as an example a flight simulator. The object-state packet would describe the plane’s location, orientation, and speed, and might even describe the state of its flight control surfaces. The receiving players “cook” that information and make a guess on the plane’s current state based on what the plane was doing and the time it was doing it.

If the plane was moved only when state packets arrived, it would not give the illusion of continuous motion but would pop from figured place to figured place. To avoid this type of movement, between the arrival of packets, the guessing continues from frame to frame, and the plane is updated. (The simplest form of guess, and the one usually used, is “I will be doing what I was doing.”) Such guessing is called dead reckoning. (See the previous section, “Open-Loop Asynchronous.”)

Object-state communication works most naturally with open-loop asynchronous game synchronization, but, as in controller-state communications, hybrids do exist. This approach requires a lot more work to implement well and may be overkill for LAN games, but it is vital to the smooth gameplay of Internet-based games.



Practical Java Game Programming
Practical Java Game Programming (Charles River Media Game Development)
ISBN: 1584503262
EAN: 2147483647
Year: 2003
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net