Anyway to sync the network 'Frame' number for an object?

Has anybody experimented or attempted to get the network frame ‘number’ for an object to synchronize both server and client side? I’m trying to store received data according to a time-stamp, but that time-stamp has to be in sync between all clients and the server. Ideally, I want to use the current network ‘frame’ that the game session is on, if such a thing exists, since I expect that would already be synchronized so that clients can disregard packets over a certain age?

Synchronizing a integer time-stamp between server and client seems to be a royal nightmare as it is. No matter what I do I can’t keep them in sync. All I could think of was to use Local System Time as the epoch for the game, and when a client receives the servers epoch-time they can adjust their local time-stamp to match it, and from that point on everybody should remain in sync regardless of framerate.

Unfortunately since that time could also different for each player that too isn’t really reliable enough :confused: I have spotted FDateTime::UTCNow() which appears to take UTC time - is that a global time that would already be in sync no matter where the players?

> Synchronizing a integer time-stamp between server and client seems to be a royal nightmare as it is.
Yup.
I haven’t found an easy way to do this with ue4 and ended up implementing a (rather heavy weight) custom solution.

> Has anybody experimented or attempted to get the network frame ‘number’ for an object to synchronize both server and client side?
In UNetConnection::ReceivedPacket() UE4 uses a form of incrementing integer system.
Clients will reject a packet if the contained integer is less than that previously received
So out of order packets are dropped, but this doesn’t have much directly to do with time.
That is your ‘frame number’ - but I suspect this doesn’t help with the problem you are having…

> UTC time - is that a global time that would already be in sync …?
Somewhat.
UTC time is generally used to get rid of time zone offsets when saving things to databases et al. that will be sent to other clients.
Looking at other functions in that class (all about date handling) FDateTime::UTCNow() is likely to be inaccurate to many tens of milliseconds.
This also relies on the local time of the client being ‘correct’. What you want is the high performance timer.

The high performance timer lives in FPlatformTime::Seconds(), ue4 chooses to expose this as a double (not a long int unfortunately).
FPlatformTime::Seconds() is a platform dependent epoch timer eg. how much time has elapsed since a given client was switched on.
This means that you can only use deltas to determine elapsed time (ie. last known time - now) and that each client returns a different time.

Using FPlatformTime::Seconds() you can determine a time offset between the server and each client by assuming the server time as the ‘correct’ (offset 0) time.

Keep in mind that if the client queries the time and the server responds, the message arrives at the client with a round trip delay (client -> server -> client).
You will only experience half this delay for future (server -> client) calls.
The round trip latency can be worked out by passing the time the ‘time sync’ request was originally made by the client as part of the message sent back and forth.

Other possible problems you may have to deal with:

  • How does the client behave before a timesync is received from the server.
  • FPlatformTime::Seconds() timer can wrap (was every 30 days of system up time on old Windows NT boxes).
  • Transport latency - in the real world latency can change during game play frame to frame (dynamically adjust the time sync offset during play?).
  • Allowing two concurrent instances of this code to run correctly on a single PC (for when testing locally).