0
\$\begingroup\$

I have only looked into the basics, at least I assume it gets more complex. So does network code really change from one game to the next or is it pretty much portable. For example I can create say a 2 person chat app, now if you want to make it multi-chat you then need to use mutli-threading, ie a new thread for every connection(load a new Winsock object for each connection). I am also reading about mutex ojects, blocking and non-blocking sockets.

You then have 2 base networking API's, Winsock and BSD sockets, there are various wrappers for these such as Boost.

The principle is that you then send a snapshot of all the gamestate data back and forth between client and server and have some kind of load balancing to take into account lag and general synchronicity.

I can't see how this would really change from game to game though, these are fairly linear principles and one set of networking code should be compatible with the next?

\$\endgroup\$
6
\$\begingroup\$

In broad terms, there are a few standard architectures for networking systems.

In terms of topology, you have:

  1. Client-Server: All clients talk to a single server, which may be a dedicated server executable, or may be another copy of the game, just operating in "server mode". (this is the one you mentioned)
  2. Promiscuous Peer-to-Peer: Every peer talks directly to every other peer, either explicitly, or implicitly via multicast or broadcast transmissions.
  3. Connection Graphs: Peers self-organise into a network, so some peers talk directly to each other, while others can act to forward messages between clients which can't talk to each other directly

Each of these approaches requires a different strategy for managing bandwidth, detecting joins/parts, for synchronising game clocks, and for handling other network events.

In terms of synchronisation strategies, there are four main approaches to keeping each client's view of the world in synch:

  1. Synchronise State: Clients continually send messages which broadcast their full current state. (this is the one you mentioned)
  2. Synchronise Edge-Crossing: Clients only send messages when their state changes. For example, an edge-crossing-style client likely will not send messages when it's idling; instead, it will inform other clients only when its position changes (and then, it will only inform about the updated position, not any of the rest of its unchanged state). This approach is great for cutting down on the amount of bandwidth required to play a game.
  3. Synchronise inputs: Clients don't send their state at all -- instead, they send their control inputs, and the game instead relies on the game logic working the same way for each client. This is often how turn-based games are implemented; the turn doesn't happen until everyone has submitted their moves, and then everyone processes what happens next, and some old LAN-only action games also used this approach.
  4. Future events: This is a more unusual approach, but high-latency game designs occasionally get built around queuing up future actions. Instead of each client saying "I'm here now", they say "in 20 seconds, I will be at this position." In a lot of ways, this is like a version of "edge-crossing" that's even more resistant to lag. See NetStorm for an early example of this approach.

There are also a few methods of coping with latency. Especially on the Internet, you can often have 300 milliseconds of latency, and there are a couple different ways to cope with that. Different approaches are appropriate for different types of games. Here are a few:

  1. Lockstep: Nobody does anything until a synchronisation packet has been received from everyone. Once all synchronisation packets have been received, everyone can advance by one simulation step. This is usually the approach used by the "Synchronise inputs" synchronisation approach. And for obvious reasons, it doesn't work at all with the "Synchronise Edge-Crossing" approach.
  2. Dead-reckoning: When we haven't heard authoritative information about the game state, we make an educated guess based upon the last state we knew about, and the amount of time since we last heard what the game state was. So if the last thing we heard was that a client was at a particular position and moving left, and it's been a second since then, we might make an educated guess that they've continued moving left since we last heard from them, and so continue moving them to the left. This process of making educated guesses is referred to as "dead reckoning"
  3. Alternately, we can perform Interpolation, in which when we hear updated state data, we smoothly adjust our client's view of the world state over a short period of time, so that they don't appear to 'pop' around from place to place as they make unpredictable moves.
  4. And of course, you can do both Dead-reckoning and Interpolation, making predictions about where things will go, And smoothly adjusting when you guessed wrong. This is almost always nicer than either of these two techniques on their own, but it makes the code a lot more complicated, since you're needing to perform interpolations on dead-reckoned positions, and be continuing to perform dead-reckoning while error-correcting interpolations are occurring. So you need to weigh up whether the implementation costs are justified for the benefit it gives.

So there's no one universally right choice for how game networking works. You need to pick what sort of system architecture (or architectures) are most appropriate for each individual game, bearing in mind the hardware and networks on which the game will be being played.

\$\endgroup\$
  • \$\begingroup\$ I've done a lot of reading and thinking in an attempt to assemble in my head a comprehensive picture of game synchronization fundamentals. Your answer just crystallized a bunch of disparate ideas. Thank you! Do you know of a single textbook-style resource that I could keep by my desk for this? \$\endgroup\$ – kdbanman Nov 26 '14 at 14:33
2
\$\begingroup\$

There are many issues that could be dealt with using a variety of techniques. Does the game have physics? If so, are physics being checked on the server securely? How is lag handled? What is the behaviour on the client-side when the round trip times increases?

Is there a logging system in place to allow further debugging or studying in case of errors, cheating and other unwanted occurrences? What do we log?

More importantly, is the system scalable? If the game is going to be player by a handful of users at the same time, it may not be an issue. Other times dozens or hundreds of players play together so the question becomes more prominent.

Another issue is what kind of tools are necessary for moderators. Are moderators needed? If so what tools do we provide them with?

I cannot think of all the reasons but there are differences in networking code, just like there will be differences in rendering code or in the code that handles user input. In theory we could have come up with a generic interface but it may not be suitable for every user (game developer).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.