Making a stopwatch?

Hello Devs! I’ve been working on a racing game recently and I want a system where the player is able to see their own time even in decimals.

I’ve got a basic script set up

local rs = game:GetService("ReplicatedStorage")
local stopwatchEvent 

local ts = game:GetService("TweenService")

local stopwatch = script.Parent.Time

local info = TweenInfo.new(
	999,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.InOut
)

local stopwatchTween = ts:Create(stopwatch, info, {Value = 999})

local function FormatTime(seconds)
	return string.format("%d:%.02d.%.03d", seconds/60, seconds%60, seconds*1000%1000)
end

script.Parent.Timer.Text = FormatTime(stopwatch.Value)

stopwatch.Changed:Connect(function()
	script.Parent.Timer.Text = FormatTime(stopwatch.Value)
end)

wait(1)

stopwatchTween:Play()
1 Like

try using runservice.renderstepped I believe that could help!

Instead of .changed? I will try this and get back to you

This still results in the same thing. The timer is working perfectly fine but there are just no decimals for it.

Tweening a number value for a timer isn’t the best approach. Tweens don’t guarantee perfect accuracy, and your formatting math is also off: seconds/60 gives a float, and % on floats won’t give correct minutes/seconds breakdowns.

For a racing timer, you want frame-accurate, delta-based timing, not a tween.

Here’s a simple and accurate way to handle it:

local RunService = game:GetService("RunService")

local startTime = tick()

RunService.RenderStepped:Connect(function()
    local elapsed = tick() - startTime
    script.Parent.Timer.Text = string.format(
        "%d:%02d.%03d",
        math.floor(elapsed / 60),
        math.floor(elapsed % 60),
        math.floor((elapsed % 1) * 1000)
    )
end)
1 Like

Thank you for giving me this information! I was trying to follow an old dev forum tutorial but I can see now that it was a bit faulty. Though would there be a way to start/stop and restart this stopwatch? because if i define the startTime at the beginning it starts from there