Best method to sync client and server time?

I have this script

RunService.Heartbeat:Connect(function(DeltaTime)
	Data.Cash += Data.Cps * DeltaTime --->> Data.Cash = Data.Cash + Data.Cps * DeltaTime
end)

on both the client and the server. The problem is that the script runs a little later than the server something like this(Hopefully I’m allowed to do this.) 0:30 - 3:00 is where I’m having a similar problem.

If you didn’t watch the video then here’s the problem. The client gets a copy of their Data loaded from the server. This data contains things like the amount of Cash the player has and the amount of cash they make per second(Cps) ingame.

When the server is done getting the players Data through DataStore it immediately sends a copy to the client whilst starting the function above. When the client gets the copy of table it runs a copy of that function as well. Except it runs a little later. That means the server could have 300 cash of the player while the player only has 290 cash at a single time.

So I thought maybe I could set a time agreement that the server and client will start their functions at the same time using os.time(). But then I saw a post that said that os.time() should not be used on the client.

Shouldn’t os.time() return the same number on both the client and server? So couldn’t I use that to sync the server and client?. I know Tom Scott says that method still doesn’t work but it’s the best one I know that could sync client and server time.

Is there any other method for this one?

1 Like

Why is the client script running slightly behind the server a problem? Cash doesn’t really seem like a time-sensitive value. Worst case scenario, the player waits a couple of seconds.

Like I’ve shown above with the function, the cash updates every milli seconds. But it wouldn’t do me good if I started to spam the Remote Events just to show the player how much cash they have. In this case I can run a copy of the function on the client so that it doesn’t lag them.

And yes, it’s important to me that the player see how much cash they really have but not like in decimals.

Server → “Hey, the cash I’m holding on is 512.0591820938”

Client → “Ok well the function I have shows me that player has 512.9539, but i’ll show them 512 since it’s close enough.”

Server → “Hey I processed the transaction the player sent through Remote Function and now the player has 346 cash”

Client → “That’s not right, I processed the transaction and it’s telling me that that the player has 371 cash”

Server → " …"

Client → “…maybe you missed a Remote Function call?”

Server → “I’m not going back and doing that again, I’m saving what the player really has.”

Client → “Well dang, what am I gonna do if the player finds out they have less cash when they join back in?”

Server → “Not my fault”

You can simply just have a GetPropertyChangedSignal connection on the client for a NumberValue that holds how much cash you have. This way, you don’t need the server to tell you how much cash you have through a remote.

Don’t try to synchronize the server and client like this.

Instead, don’t run the loop on the client in the first place.

Run the cash loop on the server. Send the amount that the player has to the client a few times a second. Now the client always sees a late state. When you do a transaction, you do it on the server, and the client doesn’t assume anything about its cash until the server said “yup that transaction went through and your cash is now X”

It would be pretty obvious if they clicked buy and their money didn’t go through. I need the cash loop for something else.

By the way, I was spamming the remote events on this one. Which was very inefficient.

So putting a NumberValue in ReplicatedStorage would be faster than Remote Events?

Yes, this way you don’t need to run another function to receive data on the client or whatnot and it will make sure they both have the same value at all times.

I didn’t think of this… what I had been setting up right now was flashing the server cash 120 seconds ahead of time. And then saving the client cash if it’s less than the server cash through datastore.

This seems more secure and easier to understand.

1 Like