Synchronizing a timer on two networked computer

Started by
11 comments, last by Cybertron 20 years, 3 months ago
I am thinking about multiplayer games and had an idea about how to deal with latency (using winsock with and UDP) For a projectile if you know how much time has passed since it was actualy created and when the packet arrived you could easily approximate the correct position Now to do that you would need a timer (couting the number of milliseconds since the game started or something) on both computers that are synchronised to a high degree of accuracy and giving each packet a ''timestamp'' To do this I could send a ''ping'' packet and using the time / 2 to measure the latency and to retrive the current timer Of course using a fake timestamp would have to be detected to prevent it from turning misiles into instant hits What do you think of this idea and what would be the best way to do it?
Advertisement
The question is, how do you get the timestamps synchronized?
I don''t know, maybe you should have a look at the network time protocol (NTP). There could be some idea in it (but I realy don''t know).
Let me know if you find out something.
FPS games is about the clients and the server shouting at each other. Clients send their commands to the server, and the server sends back the game state changes. Whether or not the packets reach their destination is pretty much a non-issue because of the rate at which machines exchange their packets (20 times per second is the average norm); at worst you get choppy animation and at best you have a slight delay between issued commands and their rendition on the screen. Avoiding choppy animation can be done by the Client by trying to estimate how much time it will take for a command to be executed and assume the Server will accept the packet and render a conforming game state based on this estimate; this is called ''predictive interpolation'' or ''dead-reckoning''.

A Client can estimate how long it takes a packet to reach its destination and come back to adjust its game clock by sending a timestamp in the packet and having the server add its own timestamp in the returned packet. By examining the returned packet, you can determine the time it took to get there and back (difference between the current Client timestamp and that you put in the original outgoing packet), along with the differences in game clocks between the Client and the Server assuming an equal time for sending the Client-to-Server packet and Server-to-Client packet.
So if I could synchronize a timer on the two computers then I could know how long ago an event happened. The object''s position can be adjusted so there is no visibe delay at all. The time stamp will be added to the UDP packet so you know exactly when it was sent.

''Shouting'' data is good for players and AI becuase they are unpredictable. Bullets and missiles only need to be sent once - they travel in a straight line. Homing missiles need to be updated frequently though

I think my idea is better then using the current ping because it won''t screw up when it fluctuates and it only needs to be done once - computers are VERY good at counting seconds (thats why your clock isnt horribly off)

The server is the only one actually running the game, clients just guess what the game looks like and do what the server says when something changes
Here''s an article on how games are synchronised in Age of Empires: http://www.gamasutra.com/features/20010322/terrano_01.htm
hehe age of empires, that game is ancient. It is still interesting to see that is still has the same basic idea though

The article on unreal.epicgames.com about the network architecture is also a good read


BTW if you want to access Gamasutra without that ''free registration'' BS just use a program like the Proxomitron to block cookie_check.js (I like privacy)
Couple of suggestions...

If you are going to use the ping for prediction, don''t use a single ping value. Store the pings from each packet (up to a threshold number of pings, say 50 or so), drop the worst 20% of pings, then average and divide by 2. This will give it more consistency.

Traditional dead-reckoning is probably not the best method for FPS games, where sudden changes in velocity of entities can be dramatic. A close-quarters skirmish between 5 or 6 entities could quickly bring the network to a crawl if they all have to update at full frame rates.

If you are feeling ambitious, you might want to look for a paper titled "Using a Position History-Based Protocol for Distributed Object Visualization" - Singhal and Cheriton. It describes a spin-off of dead-reckoning that generates a convergance curve that results in smoother extrapolation, and less network activity during erratic movements.

Peace
Also, if you want a good example of how to synchronize clocks between networked computers, you might want to pick up a copy of Peter Walsh''s ''Advanced 3D Game Programming with DirectX 9.0''. Interestingly it doesn''t use DirectPlay as I figured it would being a book on DX, but uses winsock. It also describes a framework for handling reliable communication over UDP for important messages, as well as unreliable and unordered packets for update messages that can handle being lost.

Although I wouldn''t necessarily recommend this book for it''s Direct3D tutorials, it contains what is probably the best tutorial I have seen on network communications for multiplayer games, going through concepts such as endianness, thread safety, data extraction and compression (such as using bits instead of bytes for state flags), etc. And importantly, it has a NetClock class that keeps every computer on the network in-sync with each other. It also demonstrates a fairly good dead-reckoning system, although the game that comes with it doesn''t use it (and is very choppy as a result).

It also implements ''pluggable factories'' for generating messages, which is really nice way of handling messages, where each message type has it''s own C++ class.

It also shows you a simple way to simulate packet-loss to make sure your application doesn''t go haywire under poor network conditions, which is a very valuable tool.

Peace

I havn''t had any luck with books, they have all turned out to be duds. I am, however, very very good at learning things myself

I don''t have to worry about erratic motion because its not an FPS Its a space game (think wing commander) so space ships will be slower and chunkier. Only the yaw, pitch and roll rotations need to be sent. The rotation is represented by three vectors (look, up and right, one can be omitted).

The bandwidth can easily handle that. I was thinking of a UDP packet size of 512 bytes with multiple messages crammed into it. Very little data needs to be sent The order doesn''t matter, if a newer update has been processed it will be disgarded.

I relly like my idea of a timestamp now. The server can interpolate the position/rotation of the ship x number of seconds ago and then apply the new values and move it x seconds into the future to get the current values

Of course I havn''t started yet, just planning!

This topic is closed to new replies.

Advertisement