Using DeltaTime as an accurate in-game timer

Hey all,

In my game I had a timer that players would use to benchmark speedruns. They alerted me that the timer was tied to the client’s FPS, therefore the timer would roll slower for lower performance devices than devices running the game at 60 FPS. “Time” would go by at different rates for different devices.

In an effort to combat this I created a timer that uses delta time. And that alone works totally perfect with no hassle.

But as each RenderStep hits, I need the script to convert the delta time into a format (00’00’00) that players can make sense of. So here’s what I came up with:

local RunService = game:GetService("RunService")
local RenderStep = RunService.RenderStepped
local timer = 0
local min = 0
local hour = 0

local function Timer()
	local dt = RenderStep:Wait()
	local sec = math.floor(timer + 0.5)
	timer = timer + (dt * 100)
	if sec >= 100 then
		timer = 0
		min = min + 1
	elseif min == 60 then
		min = 0
		hour = hour + 1
	end
	if sec <=9 and min <=9 and hour<=9 then
		script.Parent.Text = "0"..hour.."'0"..min.."'0"..sec..""
	elseif hour<=9 and min<= 9 then
		script.Parent.Text = "0"..hour.."'0"..min.."'"..sec..""
	elseif hour<=9 then
		script.Parent.Text = "0"..hour.."'"..min.."'"..sec..""
	else
		script.Parent.Text = " "..hour.."'"..min.."'"..sec..""
	end
end

RunService:BindToRenderStep("Timer", Enum.RenderPriority.First.Value, Timer)

Because I introduced the if sec >= 100 then conditional statement into the function, this timer (that used to run exactly as intended) now changes speed depending on if a good or bad device is playing the game. It’s the problem I had before, but to a lesser extent.

But that conditional statement needs to exist somewhere: it’s what allows the players to see their time in a readable format.

Is there a way to have an accurate delta timer and also translate what it spits out without the speed of the delta timer taking a hit?

2 Likes

So performance issues is the problem? You’re saying that the top if else statement is causing the poor performance. Are you sure it’s not the bottom one? Either way, I don’t see how that amount of code could cause the timer to slow down.

1 Like

Yeah, this timer goes slightly slower on devices that don’t run Roblox as good. Performance issue is the problem.

It could very well be the bottom statement as you suggested. In hindsight that seems like the conditional statement most likely to make things hiccup.

I compared the pace of the timer on my computer and a tablet simultaneously. With the 00’00’00 format I coded, the tablet’s timer GUI started noticeably losing pace with the computer’s timer GUI around the 27 second mark.

When I reduced the function to just the following, both the tablet and computer’s timers ran perfectly in sync up to 60 seconds.

local RunService = game:GetService("RunService")
local RenderStep = RunService.RenderStepped
local timer = 0
local min = 0
local hour = 0

local function Timer()
	local dt = RenderStep:Wait()
	local sec = math.floor(timer + 0.5)
	timer = timer + (dt * 100)
	script.Parent.Text = timer
end

RunService:BindToRenderStep("Timer", Enum.RenderPriority.First.Value, Timer)

You would use os.clock() for this

local StartTime = os.clock() --Get the time the script starts at, in seconds

function TimeSinceStart()
    return os.clock() - StartTime --This gives you how many seconds have passed since StartTime
end

--Example
while true do
    wait()
    print(TimeSinceStart())
end
1 Like

Hello again,

Thank you guys for your responses and help. I did some more rigorous testing and collected enough data to conclude that I was messing up by assuming the timers were going off track from each other. My untrained eye was at fault here.

I also managed to create the timer using os.clock() as suggested, so thank you very much for giving me another avenue to explore for creating accurate timers.

My apologies for the thread!

1 Like