Hello, I was wondering how I could make the client display a timer gui thats in sync with the server.
I was using using a number value under Replicated Storage and a .Changed event on my client to update the timer but apparently I heard this is a bad practice.
So I decided to do a remote event. For example, when the stage changes, I will fire the client telling them to count down from x amount and have it update the timer.
The issue is, if the client receives the signal late, the timer will be out of sync with the server.
How do other games solve this? Honestly, this seems like a very simple and petty issue but I just cant seem to find a solution to this.
There’s always Quenty’s timer that’s synced on both the client and the server. I don’t know the link for it, though.
Honestly, I just say to hell with it and use a NumberValue in ReplicatedStorage. Bad practice or not, it works perfectly fine, is as synced as the client isn’t laggy, and lets me do clever things such as instantly cancelling whatever timer I have just by setting its Value to 0.
NumberValues barely account for any of your bandwidth. I’ve never had any problems in the two years I’ve been using them. Again though, the way you’d do it without it is to have a synced clock on both the client and the server, something Quenty’s Nevermore has but that I don’t know where to find it.
I believe the standard practice is to tell the clients via a remote to start a timer for the given number of seconds and let the client handle it. The worst case scenario is that the timer ends a little too soon or too late on a client’s end.
Typically, the client receiving the remote signal late will not be a big deal. The difference is typically a very small amount of time, and it takes roughly the same amount of time for the servers update to be received when the timer ends.
For example:
Server starts countdown to explosion.
Client notified to start timer 0.25 seconds later.
Server creates the explosion.
Client receives update of the explosion 0.25 seconds later, at roughly the same time as the timer ends.
It’s not immediately synced. It’s synced after the remote event is first fired. I can’t say I’ve ever had any experience with his module, but that’s what the code looks like.
What I like to do is:
Instead of having a value ticking down, I just store the tick() in a NumberValue and then have the client do the math locally to find the time remaining
Also, sometimes the difference between the SaveClock:GetTime() and the Time Stamp (Time Stamp is MasterClock:GetTime() before firing the client) is negative. What do I do in that case?
It takes a round-trip for TimeSyncManager to synchronize. This is the player’s ping. You may use TimeSyncManager:IsSynced() to determine if it’s synced.
In general, just use TimeSyncManager:GetTime() and it’ll work.
Sometimes the difference between slave and master will be negative. This is expected behavior (if the client (i.e. slave clock), is an hour ahead (in the event of TimeZones), you’ll get a negative offset)). Note that before it’s synced, it may offset by -1. I’ve updated the code so this won’t occur any longer.
That method is as precise as your internet. Quenty’s method is always precise, since it doesn’t rely on the server every time you want to check the time.
This uses significantly less bandwidth and still maintains high frequency. When you read from a NumberValue on the server you get a low and uneven update rate. This, especially on 60 FPS animations, will lead to time-differences being 0 and division by zero. This is bad.
For @ninja900500’s case of doing stage timers, it’s not too big of a deal. You can probably get away with a number value that just counts down on the server. It’s what I did for a few years. However, if you’re trying to synchronize bullets or other high frequency time sensitive events you need something like this.