🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Network Synchronization Problems

Started by
4 comments, last by Zik 22 years, 9 months ago
Hey gang. I’m currently working on a little project to learn more about making networked games. The game is basically Warlords (for those of you who remember the Atari 2600) – four players guard their castles as a ball bounces around the screen. It’s kind of a cross between Pong and Break Out (and possibly one of the greatest games that I had for my 2600 – four player action, who ever heard of such a thing! . But anyway, my setup looks like this. I have a server sitting out there, running the game. I have a bunch of clients, one per human player. There is at least one client and as many as four. My two loops look like this. The server collects input from all the clients, parses it, updates game state, and then sends all changes to the clients. The client collects the data from the server, parses it, updates local game state, draws the screen, collects user input, and sends the input to the server. Lather, rinse, repeat. Basically the server is in charge of everything, and the client does nothing besides display the game and collect input. Before I added user input collection everything was running just fine. With the addition of user input, I suddenly had a real-time requirement. I thought I had planned for this, but obviously I didn’t do as good a job as I had hoped. I can’t find the medium between where things are smooth and the polled input happens right away. Either the game is smooth and user input is reflected a sec or two later, or the game bursts yet input is displayed instantly (or almost). Basically the difference is buffering, whether the client only processes one game packet at a time or as many as are in the network queue. If the client only processes one packet, the user is acting on the current set of data, which, according to the server, is very old. If the client processes all packets possible, things jump according to the quirks in the network at the time. I’m not sure how to handle this properly. I’m using TCP/IP through Winsock, with my own binary protocol I’ve developed. A packet (as used above) is a collection of messages, each message with a small header on it with a type, size, and object ID. The packet adds a wrapper around all of that with an special tag that verifies the data as a packet and a size for all the data in the packet. Generally one packet is one game update. Both server and client sockets are non-blocking. The server I made non-blocking because I didn’t want one lagging client to disrupt the game. Originally the clients were blocking, but I keep going back and forth on that one. But at the current moment, with data coming in faster than I can handle it, it doesn’t seem to matter much. Any suggestions? Thanks a lot, -Steve Rhinoceros: A Unicorn designed by comittee -- Anonymous
"Anar caluva tielyanna."
Advertisement
Its not so important for the server (as all it does is sit and send/recv packets) but within the client you want to seperate the network ''engine'' away from the client code. For example you could run through the message que and update it in a seperate thread.

Also you should try to avoid as much as possible making the game update at the same rate as the network, send updates on time critical events (people firing, moving etc) straight away but only send regular updates every few milliseconds. That way your game logic can be processed at a higher rate and still leave the apperance of a smooth game.
Sounds to me like you need to start reading the future! Although it is almost 11PM and I am still stuck at work coding away, so my brain could be just a little frazzeled (14hrs plus a day of coding can''t be good). Prediction, its the only way to start overcomming the lags.

You need to work out your latency times and try to predict where something would be that amount of time in the future. Not an easy task I have to say and it requires some thought in order to make life easier for yourself. This is something that I will be looking into in a big way for my next game.

Also, TCP/IP messaging is not such a great thing. It has a tendency to increase your latencies. UDP with your own garanteed delivery protocol is much better.

This combined with MEH''s suggestions should start to see things right.

Hope it helps.

Several things are happening really. As you mentioned the processing one packet at a time will never really work, as you''ll process packets at your udpate rate and just due to network latency and timmer divergence between the client and server, the clients will eventually drop far behind the recived udpdates.

Processing all packets at a time is better however its very sensetive to network conditions. Several network conditions cause the game to appear to be jumpy, erratic, and unresponsive. These are :

A)TCP buffering can be causing your problem, try disabling nagels algorithim for TCP

B)The client is running ahead of the server, thus spending much of its time waiting for packets. To fix this you will have to synchornize the clocks of the server and client as much as possible. Time stamp the packets, and tell the client to update up to the servers time and not beyond. This will leave you some packets in the buffer but it should be relatively few.

Use a common time synchronization protocol like NTP. A good description of the algorithim and impelemntion can be found on www.codewhore.com

This should smooth out your simulation without the need for any interperlation. However it''s an action game you might want to explore that possiblity just for bandwidth reduction.

Good Luck

-ddn

Interesting read DDN cheers!
Cool, thanks for all the help guys! Yeah, I did disable nagels algorithm, but it still looks like the server is doing some buffering on his end. I think I will move to UDP for this. I didn''t think I was sending enough data to make a difference - well, live and learn, I guess Separating the network engine from the rest of the game helped a lot, as did cutting down the size of the packets by only sending critical information every time. But it''s still acting weird, so I''ll go UDP and try that clock synchronization.

(But first I have to fix my debug logging code. It broke when I added the network thread, and I don''t know why. I have critical sections around all the file IO, but it''s still crashing and burning, with what looks like the file being closed in the middle of being written. Oh well, I''ll figure it out, I''m sure

Thanks again!
-Steve


Rhinoceros:
A Unicorn designed by comittee
-- Anonymous
"Anar caluva tielyanna."

This topic is closed to new replies.

Advertisement