Client Timer In Sync

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.

Any help appreciated, thank you.

4 Likes

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.

4 Likes

Is there anyway to keep it in sync without using a number value? Idk why, but I keep hearing Changed is bad practice.

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.

3 Likes

In which cases is will using data objects possibly adversely affect your client/game/whatever?

I’m assuming when the client actually depends on it to do core things, rather than simply just displaying a number on your screen?

1 Like

It’s a bit hard to answer, and I am by no means an expert. Just don’t do things that are purely visual with them, I suppose.

2 Likes

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.

5 Likes

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.

If you need a lot of precision though, you could use something like Quenty’s TimeSyncManager mentioned by @Kampfkarren

9 Likes

I got it to work.

I’m guessing this isn’t just used specially for client gui timers and much more things, correct?

Also, how do I fix it not being in sync when the game first starts?

Will moving this line do the trick?

It is in sync when the game first starts.

2 Likes

I’m guessing it takes at least 5 seconds to sync up with the server?

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.

2 Likes

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

1 Like

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?

Again, I’ve never used that module before, so I have no idea. You’d have to ask @Quenty, sorry.

2 Likes

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.

https://github.com/Quenty/NevermoreEngine/blob/version2/Modules/Time/TimeSyncManager.lua

Edit: See TimeSyncService: https://github.com/Quenty/NevermoreEngine/blob/version2/Modules/Shared/TimeSync/TimeSyncService.lua

6 Likes

Whats the difference between this and just reading a number value on the serve called “Current Time” or whatever from the client?

That method also gets it somewhat precise, correct?

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.

4 Likes

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.

Edit: Sniped by Kampfkarren!

11 Likes

Thought so.

I was about to say it would be kind of negligible in a scenario of stage timers.

Thanks man.

1 Like