Java – How to sync clocks over networking for game development

game developmentjavanetworkingpython

I'm writing a game that has a lot of time based aspects. I use time to help estimate player positions when the network stalls and packets aren't going through (and the time between packet's being received and not). It's a pacman type game in the sense that a player picks a direction and can't stop moving, so that system makes sense (or at least I think it does).

So I have two questions: 1) How do I sync the clocks of the games at the start since there is delay in the network. 2) Is it okay NOT to sync them and just assume that they are the same (my code is time-zone independent). It's not a super competitive game where people would change their clocks to cheat, but still.

The game is being programmed in Java and Python (parallel development as a project)

Best Answer

I think it is definitely not OK to synchornize the clock in the system. User does not expect you to touch the system settings and many systems won't even let you to.

All you need is to have a correlation to convert timestamp from one side's clock to the other side's clock. On the other hand you need this correlation to be rather precise, say at least to a hundredth of a second, if you want to use it for predicting player positions. System clock won't ever be this well correlated between random machines. So you should establish the correlation yourself, using some variation on the NTP theme, probably embedded in your other messages to conserve network bandwidth.

The basic idea might be that with each packet you sent out timestamp you sent it and sequence number of and timestamp when you received last packet from the other side. From this you calculate the roundtrip: For example if packet Q says it was sent at 1000 and packet P was received at 500, than given you sent packet P at 0 and are receiving Q at 800, the round-trip is (800 - 0) - (1000 - 500) = 300. There is no way to know the assymetry, so you just assume the packet takes half (150) ticks in either direction. And that remote timestamp is ahead of local by 1000 - (800 - 150) = 350 ticks. The round-trip will vary. If you assume the clock are reasonably precise, you should use a long-term average of the correlation.

Note, that you don't want to use system clock for the clock either. They may get resynchronized midway, throwing you off track. You should use clock(CLOCK_MONOTONIC) on Unix or GetTickCount on Windows (not sure how those APIs are wrapped in Java or Python right now).


Note: The SO_TIMESTAMP socket option (see socket(7) mentioned by ott-- in comment on the question) would be useful for separating out the effect of latency of the event loop that receives the packets. Whether it's worth the effort depends on just how good precision you need.

Related Topic