In broad terms, there are a few standard architectures for networking systems.
In terms of topology, you have:
- 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)
- Promiscuous Peer-to-Peer: Every peer talks directly to every other peer, either explicitly, or implicitly via multicast or broadcast transmissions.
- 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:
- Synchronise State: Clients continually send messages which broadcast their full current state. (this is the one you mentioned)
- 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.
- 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.
- 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:
- 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.
- 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"
- 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.
- 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.