How to make a Timer from 0.00 seconds

I am doing a Timer that starts from 0.00 seconds and that maximum can reach up to 50.00 but it is getting a bit complicated.

I’ve done this script for the Timer, it works fine, but I guess there’s a better way that I’m not realizing how to do it …

Does someone tell me if I leave it the way I am doing it or do I recommend doing it another way?

function module:StartTimer()
	
	local endNumber = 0
	local ActualNumber = 0
	
		for i = 0, 10, 0.01 do
			
			local longitud = string.len(i)
			local number = string.sub(i, 1, 4)
	
			if longitud > 0 then
				if longitud == 3 then
					ActualNumber = number .. "0"
				elseif longitud == 1 then
					ActualNumber = number .. ".00"
				else
					ActualNumber = number
				end
			end
			
			print(ActualNumber)
			wait()
		end
		
   delay(0.0, function()
		for i = 10, 50, 0.01 do
				
			local longitud = string.len(i)
			local number = string.sub(i, 1, 5)
				
			if longitud > 0 then
				if longitud == 2 then
					ActualNumber = number .. ".00"
				elseif longitud == 4 then
					ActualNumber = number .. "0"
				else
					ActualNumber = number
				end
			end
			print(ActualNumber)
			wait()
		end
    end)
end
4 Likes

To my knowledge, there are two better ways to make a timer, and that is using wait or one of RunService's events, like Heartbeat or RenderStepped, and adding the numbers returned from the function, and not just adding something arbitrary like a for loop does:

function module.StartTimer()
	local Finish = 50
	local i = 0

	while i < Finish do
		i = i + wait() -- or + RunService.Heartbeat:Wait()

		-- clamp between 0 and Finish
		i = math.clamp(i, 0, Finish) 

		print(string.format("%0.2f", i))
	end
end

The other method is just subtracting os.clock instead of using waits if you are just aiming for a way to keep track of a duration:

module.Start = os.clock()

function module.StartTimer()
	module.Start = os.clock()
end

function module.StopTimer()
	local Finish = os.clock()

	local duration = Finish - module.Start
	print(string.format("%0.2f", duration))
end
4 Likes

goldenstein64 makes some good points, but there is more I want to add with some extra background info.


Don’t do this! The decimal part of numbers are stored in binary by approximating it using a sum of fractions in the form of 1/2^n, where n is an integer. So 0.625 would be 0.5 + 0.125 = 1/2 + 1/8. A number like 0.01 cannot be accurately represented using this approach, so it might be just a bit lower than 0.01. This might cause the for-loop to loop one too many times! Of course it’s not a big deal in your case, but keep this in mind for other situations when it might become a problem.


Another problem is the use of wait(). This will stop the code from running until at least the next step (which should be about 1/30th of a second), but it might also wait longer if there is other code that has to be run! The Lua code is run in a single thread, so if one function is being run, other code has to wait, even if they are in different scripts! After many of those waits, your timer might end up running for half a second too much because of the accumulated delays. A better approach would be to register when the timer started, and use that timestamp for each iteration.


Additionally, you can use string formats to easily round numbers to two decimals, which should eliminate the need for the whole delay function:

local n = 12.4387634
print(string.format("%0.2f", tostring(n)))

This should print 12.44.


With all that being said, here’s how I would rewrite the timer:

function module:StartTimer()
    local secondsToRun = 50
    local startTime = tick() -- float representing when the timer was started
    while tick() < startTime + secondsToRun do -- run until 'secondsToRun' seconds have passed
        game:GetService("RunService").Heartbeat:Wait() -- this waits until the heartbeat event is triggered, which happens 60 times a second
        local timeSinceStart = tick() - startTime
        local numberText = string.format("%0.2f", tostring(timeSinceStart)) -- 0.2 represents two decimals
        print(numberText)
    end
end

I haven’t tested this code, so if you see any issues let me know.

7 Likes

Thanks, I suppose it will serve me too much, I have to wait for the roblox wiki to load me … Another thing I do not understand very well about the “Tick ()” I know its definition but I do not understand its use many times I see that Ticks remain but I do not understand it at all