Synchronizing games for multiplayer

36b416ed76cbaff49c8f6b7511458883
0
poita 101 Jul 31, 2006 at 06:41

I understand that many RTS games handle multiplayer by synchronizing the game for each player, so that the exact same game is played on each client. This is in contrast to simply sending object states every network cycle and interpolating.

I’ll illustrate my question with an example of a simple game with 2 players.

Game starts
1. Player 1 issues a move order and the order is sent to player 2, scheduled to be processed a few network cycles away.
2. Player 2 receives the order shortly after.
3. The scheduled time arrives and both players process the order.

Now, obviously both players must know about the order so that the game remains synchronized. So what if the original message sent by player 1 never arrives? I’d imagine that to overcome this, player 2 should send some sort of confirmation message back to player 1 to confirm that he received the message. If player 1 doesn’t receive the confirmation message then he assumes that player 2 never received the original order and the order is resent.

My question is now that what if the confirmation message gets lost and never arrives? Player 1 will assume that player 2 never got the original message (even though he did) and will not process the order. Meanwhile, player 2 assumes everything is going as planned and processes the order. The game now goes out of sync.

Can somebody enlighten me on how to go about solving this problem?

If I haven’t explained it well enough then please let me know and I’ll try again :D

Thanks in advance

9 Replies

Please log in or register to post a reply.

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Jul 31, 2006 at 08:34

If Player 1 never gets confirmation, it resends the order. It is important to keep track of order Id’s and when the order is created so you don’t process an order twice and it is executed at the correct time. You should probably have some 10hz (YMMV) game update cycle, and keep track of game cycle ids (if you make sure that all commands have been executed on all clients before ending an game cycle then you have solved the time issue). You might get some hints at http://www.gamasutra.com/features/20010322/terrano_pfv.htm and spending some time over at www.google.com searching for p2p +rts or something..

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 168 Jul 31, 2006 at 08:39

Well, you could use TCP for the connection. That will take care of your worries about unreceived messages (of course the connection can still fail entirely, but you’ll be informed when this happens).

However, in general games use UDP messages, which aren’t guaranteed to be received. This is okay because usually there is a constant stream of updates going out and if one of the updates goes missing there will be another (newer) one coming along soon anyway, so it’s not worth it to try to ensure that every single update is received.

Most games operate on a client-server architecture, which means that player 1 wouldn’t send a move order directly to player 2 - instead, player 1 sends his move order to the server, the game is simulated on the server, and players 1 and 2 both receive position and velocity updates for each unit from the server. The clients can extrapolate the motion and behavior of the units in between updates, but the server has the final say on where everything is and what it’s doing (to attempt to prevent cheating, and keep everything in sync). Of course if one of the clients has a slow connection, they will be lagged - more advanced systems attempt to measure connection latency and correct for it on the server, to give slow players a fairer chance at the game.

6837d514b487de395be51432d9cdd078
0
TheNut 179 Jul 31, 2006 at 11:02

You should use the right protocol for the right task. When an update is mandatory (player commands), you should send it over TCP. When you know something is not important, you can send it via UDP (player voice chat). Some RTS just use TCP the whole time because it’s easier and sufficient. To boot, no matter how good your error checking scheme or ordering of packets for UDP is, the TCP driver on your system will be far more efficient and correct.

With TCP none of the players need to confirm the message. They are guaranteed to receive it and so the server only cares about processing and broadcasting. One way to handle synchronization is to calibrate all client PCs to the server time (see NTP: http://www.ntp.org/)). With these two combined, the players will know exactly when something is supposed to be done and how to adjust the results based on the time deltas.

Another way to keep all players in sync is to periodically ping players and expect a response. If a player fails to respond after a period of time, the server will put the game on hold until the player returns and resynchronizes (you see this in games like Warcraft III). Sometimes a player will be a whole second or two behind, but that’s ok. In games like command and conquer, the server just ignores the client and the game goes on. When the client resyncs back into the game, they will advance to the current state very quickly.

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Jul 31, 2006 at 13:43

@TheNut

… To boot, no matter how good your error checking scheme or ordering of packets for UDP is, the TCP driver on your system will be far more efficient and correct.

This is not entirely true. When the TCP protocol looses packages the transfer speed tends to plummet. This is really annoying when you’re on a broadband connection and you get some temporary interference. For a game environment you might want to do ‘safe UDP’ for packages to be recived in real time, but YMMV.

6837d514b487de395be51432d9cdd078
0
TheNut 179 Jul 31, 2006 at 14:28

@”TheNut”

… To boot, no matter how good your error checking scheme or ordering of packets for UDP is, the TCP driver on your system will be far more efficient and correct.
@SigKILL

This is not entirely true. When the TCP protocol looses packages the transfer speed tends to plummet.

In the world of reliable transfers, this is a given. The problem can be no better with a UDP implementation. In fact, UDP implementations will be far more subject to congestion issues than TCP, requiring both parties to continuously hammer the routers to transmit data, thus making the network more congested. This is why ISPs hate UDP for gaming.

Keep in mind I’m looking at this from a stability and correctness point of view, which is what Poita’s problem is about. TCP efficiently handles all connections, error checking, timers, resends, packet fragmentation and reassembly at the transport level, not the application level. TCP will also reserve a connection line for you, which will try to minimize congested paths, whereas UDP on the other hand is based on a free-for-all model that may not always be in your favor. TCP also streams data, which makes efficient use of the network and flow control; whereas UDP just blasts packets out in blocks and flow control becomes your own responsibility. Dozens of engineers have worked on the protocol, vigorously testing it and approving it for use, whereas any UDP “extras” you conjure up will be solely your own responsibility to test and verify (lots of development hours!).

UDP is an option, but it’s not an out of the box solution. There are a lot of variables to consider and a lot of development and testing time required. For reliable UDP packets, you will essentially be rewriting the TCP protocol, which begs the question why would you want to do that? Many games use TCP (Warcraft III is one that I recall) and they work great.

2f9f82c36ec6a28702dc365e43753d79
0
Ooka 101 Jul 31, 2006 at 15:28

For a good read in internet protocols: http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/ip.htm

TCP tries to be a universal solution, and it works, but it’s not as efficient as a custom protocol. The packets are larger and the protocol strict, which isn’t a bad thing, but it’s not the best thing for some people.

If you can come up with your own relay scheme and then implement an error checking routine, along with interpolation for missed and predicted packets, then it’s most likely going to have less overhead than TCP. The problem is in designing a robust protocol that can not only flag errors and failures, but compensate for temporary glitches and corrupted data.

It all depends on how much data you’re trying to send, and at what rate. And for error correction, you’re probably going to want to send packets in triplicate, so as to be able to check the accuracy of transmission. If you have small amounts of data, or a slow rate of communication, TCP will work just fine, and it’s a proven, stable format. If you have lots and lots of data or a very high send rate, a custom protocol is ideal.

A possible solution is to have a simple thread set up that listens for a boolean packet every .5 seconds, and sends a boolean every .5 seconds. If true, the connection is live, and the thread pops out it’s own “true” flag to the other client. If missed, it sends itself a “false” packet and initiates the interpolation algorithm. Then, it’s up to you to decide how long a “missed” connection will be allowed before the “connection broken” flag is thrown, and ends the session.

In any case, a relay is the solution to your problem. Bounce small amounts of data back and forth between clients and make a listener thread that reacts to any changes to do what you want the program to do.

A9102969e779768e6f0b8cb87e864c94
0
dave_ 101 Jul 31, 2006 at 15:53

@TheNut

UDP is an option, but it’s not an out of the box solution.

It can be, there are various networking solutions that use UDP and network libraries that can give you features on top of UDP.

For example: http://enet.cubik.org/

6f0a333c785da81d479a0f58c2ccb203
0
monjardin 102 Jul 31, 2006 at 19:30

TCP versus UDP is a tired argument. :(

http://www.devmaster.net/wiki/UDP_vs_TCP

http://www.devmaster.net/wiki/Networking_links

Game Programming Gems 3 has an article called Real-Time-Strategy Network Protocol that proposes a solution using TCP.

36b416ed76cbaff49c8f6b7511458883
0
poita 101 Aug 01, 2006 at 09:01

Thanks everyone for the replies.

When the TCP protocol looses packages the transfer speed tends to plummet. This is really annoying when you’re on a broadband connection and you get some temporary interference.

This is what I thought and the main reason I’m straying away from TCP. AFAIK when you lose packets the TCP transmission speed changes quite drastically making it very difficult to maintain a smooth simulation. I’m valuing smoothness over speed here. I’d rather the game ran smoothly and slow than fast and jerky.

@SigKILL

I’ve actually read that Age of Empires article before and it’s the main reason I like the idea of using UDP. I read it again and I’ve kind of got my head around most of it.