How would I sync these timers exactly?

Hello devforum, I want to sync up timers in order to give a player money after a certain time no matter the amount of lag and that time is displayed on gui’s. My problem is the timers desync after each cycle usually by a matter of 3-5 seconds so the “time until money” gui is not accurate after about 2-3 cycles.

Here is my current code:

local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit)


local money = Knit.CreateController { Name = "money" }

function money:KnitInit()
	print("ran money system")
end

function money:KnitStart()
	
	
	local Time = 0
	local TimeUntil = 300

	local function onChange()
		if TimeUntil == 0 then
			TimeUntil = 300
		end
	end


local function Format(Int)
	return string.format("%02i", Int)
end

local function convertToHMS(Seconds)
	local Minutes = (Seconds - Seconds%60)/60
	Seconds = Seconds - Minutes*60
	local Hours = (Minutes - Minutes%60)/60
	Minutes = Minutes - Hours*60
	return Format(Hours)..":"..Format(Minutes)..":"..Format(Seconds)
end

	game:GetService("RunService").RenderStepped:Connect(function()
		pcall(function()
			game.Players.LocalPlayer.PlayerGui.TimePlayed.Frame.TimeInServer.Text = "Time in Server: " .. tostring(convertToHMS(Time))
			game.Players.LocalPlayer.PlayerGui.TimePlayed.Frame.TimeUntilMoney.Text = "Time until SadRocks: " .. tostring(convertToHMS(TimeUntil))
		end)
	end)

	

	--only make it work when player is not on menu in future
	print("init")
	task.spawn(function()
		while task.wait(300) do
			game:GetService("ReplicatedStorage").Remotes.Data:FireServer("Mone", 25)
		end
	end)
	task.spawn(function()
		while task.wait(60) do
			game:GetService("ReplicatedStorage").Remotes.Data:FireServer("Time", 1)
		end 
	end)

	while task.wait(1) do
		onChange()
		Time += 1
		TimeUntil -= 1
	end 
	
	print("money staryed")
end

return money

Any help is greatly appreciated!

3 Likes

I’m not sure if I fully understand what you mean, but you could try using os.clock().

Example
local awardInterval = 10 -- Seconds
local timeLastRewarded = os.clock()

while task.wait() do
    if os.clock() - timeLastRewarded >= awardInterval then
        -- Do stuff
        timeLastRewarded = os.clock()
    end
end

I will try this solution when I get home, I figured it might have been something with os.clock but I never really used it before

Sorry for such a late response, os.clock() was key in doing this, thank you!

1 Like

I have just realized that the timers are still desynced. After about a cycle, the money will give itself a second or two earlier and will continue to be desynced.

code:

local Knit = require(game:GetService("ReplicatedStorage").Packages.Knit)


local money = Knit.CreateController { Name = "money" }

function money:KnitInit()
	print("ran money system")
end

function money:KnitStart()

local function Format(Int)
	return string.format("%02i", Int)
end

local function convertToHMS(Seconds)
	local Minutes = (Seconds - Seconds%60)/60
	Seconds = Seconds - Minutes*60
	local Hours = (Minutes - Minutes%60)/60
	Minutes = Minutes - Hours*60
	return Format(Hours)..":"..Format(Minutes)..":"..Format(Seconds)
end

local osclock = os.clock()
local moneyInterval = 300
local moneyLastRewarded = osclock
local timeInterval = 60
local timeLastRewarded = osclock
local Time = 0
local TimeUntil = 300


game:GetService("RunService").RenderStepped:Connect(function()
	pcall(function()
		game.Players.LocalPlayer.PlayerGui.TimePlayed.Frame.TimeInServer.Text = "Time in Server: " .. tostring(convertToHMS(Time))
		game.Players.LocalPlayer.PlayerGui.TimePlayed.Frame.TimeUntilMoney.Text = "Time until Money: " .. tostring(convertToHMS(TimeUntil))
	end)
end)

while task.wait(1) do
	Time += 1
	TimeUntil -= 1
	if os.clock() - timeLastRewarded >= timeInterval then
		timeLastRewarded = os.clock()
		game:GetService("ReplicatedStorage").Remotes.Data:FireServer("Time", 1)
	end
	if os.clock() - moneyLastRewarded >= moneyInterval then
		TimeUntil = 300
		moneyLastRewarded = os.clock()
		game:GetService("ReplicatedStorage").Remotes.Data:FireServer("Money", 25)
	end
end
end

return money

(Any help is very appreciated)

no way bro :rofl: :rofl: :rofl:
just use a remote event from the server (because the server is the one awarding the money)
server just tells the client to update the timer every second (or maybe every few seconds it just resyncs the timer so that it isnt lagging because of too many remote events)

this was my attempt at doing it server sided instead, it still desyncs no matter what i do. What i am attempting to do is sync the timers so the player will see synced up when they will receive the money and also how much time they have spent in the server. No matter what i do after about 1 or two cycles they always desync.

game:GetService("Players").PlayerAdded:Connect(function(player)
	
	
	
	local function Format(Int)
		return string.format("%02i", Int)
	end

	local function convertToHMS(Seconds)
		local Minutes = (Seconds - Seconds%60)/60
		Seconds = Seconds - Minutes*60
		local Hours = (Minutes - Minutes%60)/60
		Minutes = Minutes - Hours*60
		return Format(Hours)..":"..Format(Minutes)..":"..Format(Seconds)
	end

	local osclock = os.clock()
	local moneyInterval = 300
	local moneyLastRewarded = osclock
	local timeInterval = 60
	local timeLastRewarded = osclock
	local Time = 60
	local TimeUntil = 300


local futuretime = osclock+300
local futuretime2 = osclock+60
local timeleft = futuretime
local timeleft2 = futuretime2


	
		

	while task.wait(1) do
		player.PlayerGui:WaitForChild("TimePlayed").Frame.TimeInServer.Text = "Time in Server: " .. tostring(convertToHMS(os.clock() - osclock))
		player.PlayerGui:WaitForChild("TimePlayed").Frame.TimeUntilMoney.Text = "Time until Money: " .. tostring(convertToHMS(timeleft))
		timeleft = math.abs(futuretime - os.clock())
		timeleft2 = math.abs(futuretime2 - os.clock())
			futuretime2 = os.clock()+60
			timeLastRewarded = os.clock()
			player.leaderstats.Time.Value += 1
		end
		if os.clock() - moneyLastRewarded >= moneyInterval then
			--TimeUntil = 300
			futuretime = os.clock()+300
			moneyLastRewarded = os.clock()
				player.leaderstats.money.Value += 25 * 2
			elseif player:WaitForChild("gamepass")["2xmoney"].Value == false then
				player.leaderstats.money.Value += 25
			end
		end
		--pcall(function()

		player.PlayerGui:WaitForChild("TimePlayed").Frame.TimeInServer.Text = "Time in Server: " .. tostring(convertToHMS(os.clock() - osclock))
		player.PlayerGui:WaitForChild("TimePlayed").Frame.TimeUntilMoney.Text = "Time until Money: " .. tostring(convertToHMS(timeleft))

		--end)
	end
end)

I need a ton of help because I do not know what to do from this point forward.
(Very sorry for reopening this constantly, Im just worried as this issue is pretty big)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.