Last modified 8 months ago Last modified on 09/18/11 07:43:19

The network code in Warzone uses TCP to implement a peer-to-peer network with a central hub or server that redistributes messages from other hosts (in lib/netplay/netplay.cpp). Each host has responsibility for orders given to its own droids and structures, and sends the messages in its order queue to other hosts (as a NET_SHARE_GAME_QUEUE message). All orders are executed in the same sequence at the same logical game time on all clients, so that the state of all clients is identical. Information about the state is printed with syncDebug() and a CRC checksum of the printed state is sent over the network each game tick (GAME_GAME_TIME in lib/gamelib/gtime.cpp). If the messages belonging to a game tick do not arrive in time, the game must pause (and the common latency between orders given and orders processed may be increased to compensate future network lag). The CRC checksums from each client are compared, to verify that all clients have the same game state.

If the clients don't have exactly the same game state, the printed state from all players is saved (after being automatically sent to you over the network). There is some old synchronisation code in place intended to re-synchronise (in src/multisync.ppc) the game state if the clients don't agree (in version 2.3 and earlier, the game state was never synchronised, so this used to be needed), but the re-synchronisation code doesn't really help at all, and might therefore be removed in the future. If the game client somehow goes out of synch, the game state syncDebug data is saved in ~/.warzone2100-master/logs/desync[TIME]_p[CLIENT].txt, where [TIME] is the logical game time and [CLIENT] is the client number. To try to figure out what went wrong, compare the files with the earliest [TIME] (but make sure you're looking not looking at old files from a previous game) and different [CLIENT]s, and search the code to see what printed the first differences in the log. Hopefully it will be possible to guess from the differences what it was that caused the differences, and to fix it.

Stuff such as projectiles are not sent on the network. Instead, each player processes each game object and figures out on its own stuff such as where it would fire and sends a projectile in that direction. Since they have the same code and the same data, they will fire at the same targets (in version 2.3 and earlier, this was totally not true, noone would ever agree on what was shooting at what). The object being targetted checks for hit and damage, and if damaged, all clients know it without having to send any network messages.

Warzone used to be designed to be very relaxed about getting things right on the first try, and did absolutely no data locking or permission queries before sending decisions to other hosts. Errors were expected and attempted to be corrected during the checking phase. As you can probably guess, that lead to lots of weird stuff happening, noone agreeing on which tanks are where, and random tanks exploding randomly, and everyone thinking that everyone else is cheating.

There are many things that need to be improved in the network code:

  • The TCP hub connections model is not very efficient, and means that if the host goes down, everyone else go down with it, too. Instead, everyone should try to connect to everyone else, and continue with another hub if the old “hub” goes down.
  • The use of TCP instead of UDP makes the implementation a lot easier, but most games that use a peer-to-peer distributed decision making system also use UDP for the lower overhead and faster transmission times.
  • There should be a way for players to reconnect if they are dropped during the game.

Category:Coding? Category:Code documentation?