High precision clock syncing tech between clients and server with accuracy of <1ms


(Demo of system, notice how the virtual client and server are synced to within a millisecond; watch full video here: https://www.youtube.com/watch?v=YGYGRquqi-c&feature=youtu.be)

Have you ever wanted to synchronize events between clients and the server, but found that tick() returns completely different values on different machines, os.time() simply isn’t accurate enough, and simply triggering an event via remote events results in clients receiving events at inconsistent timings? In that case, this system is for you!

Check it out on github: https://github.com/Kenji-Shore/Roblox-Client-Server-Time-Sync-Module

This system provides incredibly high accuracy (I have measured a consistent ~1 ms accuracy in normal conditions), so much so that this can even be used for things that demand incredibly high precision, like synchronizing a bullet flying through the air on multiple clients.

How do I know it works?
Proving the accuracy of a clock syncing technology is a very difficult task because there is no perfectly synced clock to act as a baseline for comparison. So, I’ve come up with some clever ways to engineer and perfect this system.

  1. Firstly, I have observed that when you simulate a client and server in Play Solo, tick() is perfectly in sync for both the client and server. I used this knowledge to first extensively study Roblox’s networking behavior, discovering how Roblox fires off signals in larger packages which happen every few frames.
  2. To prove this system’s capabilities in a more realistic scenario, I’ve created a test where I run a virtual client and server (not Play Solo) and I visualize the two clocks in two side by side windows. I’ve recorded a video of this, and you can advance through the video frame by frame to observe the accuracy of the system: https://www.youtube.com/watch?v=YGYGRquqi-c&feature=youtu.be

Some extra knowledge on Roblox netcode
In a nutshell, Roblox does not fire a signal between a client and server the instant you fire a remoteevent or function; instead, what happens is Roblox waits a few frames and pools together multiple remote firings into one larger package. This is fine, as it prevents network overload and also guarantees packet ordering and delivery, but unfortunately we have no way of knowing exactly when this package gets sent, making it very difficult to make high precision clock syncing. To make a proper high precision synced clock, you must be able to offset this extra delay, which is exactly what I do. There is special logic that does a very good job at guessing what this unknown delay will be every frame on the client and the server.

22 Likes

Exactly what I needed, I need to add the ElapsedTime amount from the client time sent value and the server received time value when the bullet is created on the server, my formula for all my bullets path depend on time so synchronizing works perfectly if the client and server time are in sync, my current system works OK, but this seems like a more engineering solution and well thought, defintly will use it!

So when the bullet Starts, i’ll just do

Bullet.Position = Bullet.FormulaCallBack(TIMEFROMREMOTECALL)

Well-made resource!
Even though I don’t have a need for this, this was a very interesting read nonetheless.

I have a question, does all roblox servers have same tick() timezone? for example if i was gonna run tick() on a roblox server located on paris and another on tokyo would they be different or same?

Tick() is different for every machine, and that includes different roblox servers. I have not investigated syncing up roblox servers but I assume it could be done with messagingservice or httpservice. This module is designed for syncing roblox clients to a roblox server.

Is there any way that i could use os.time and sync client and server?

os.time can be used to sync a client and server with accuracy of within 1 second. This syncing tech is for purposes that require far greater precision.