For loop for timer is skipping 1 second (ex: 15, 14, 12, 11, etc.)

Hello,

I’m currently writing a timer function for my game. However, my timer is always skipping 1 second. I’ve tried to floor (i,) but it still skips. I’ve used a different timer method, and it still skips. Any ideas? Here’s my code:

function startTimer(startVal, endVal) -- startVal defaults to 60, endVal defaults to 0
	if startVal == nil then startVal = 60 end
	if endVal == nil then endVal = 0 end
	
	timerVal = startVal
	
	for i = startVal, endVal, -1 do
		if i == endVal then break end
		timerVal = math.floor(i)
		task.wait(1)
	end
	
	return true
end

Use case example:

startTimer(20, 0)

Any ideas?

Thanks,
pos0.

1 Like

Maybe try a repeat instead of a for loop

	repeat
		timerVal -= 1
		task.wait(1)
	until timerVal <= endVal
2 Likes

The issue persists. Any more ideas?

Not sure, it might be an issue somewhere else in your code, maybe try some printing the values inside the loop to see whats going on

2 Likes

Yup, seems like it’s something with my client code. Thanks!

1 Like

I have a few notes on your code aside from the main issue you’ve raised.

First, these two lines can be shortened using short circuit evaluation.

if startVal == nil then startVal = 60 end
if endVal == nil then endVal = 0 end

Equivalent to

startVal = startVal or 60
endVal = endVal or 0

You can also use the tonumber() cast function for added security.

startVal = tonumber(startVal) or 60
endVal = tonumber(endVal) or 0

Second, this line in the for loop is redundant as the for loop already breaks when i is equal to the limit variable.

if i == endVal then break end

Now as to your main issue- I don't see anything in the code you posted that would cause that behaviour. So, either you are mistaken or that's not the complete code.

I’ve recreated a sample script that I’ve verified works if you would like to test it yourself.

function startTimer(startVal, endVal) -- startVal defaults to 60, endVal defaults to 0
	startVal = tonumber(startVal) or 60
	endVal = tonumber(endVal) or 0
	
	for i = startVal, endVal, -1 do
		print(i)
		task.wait(1)
	end
end

startTimer(20, 0)
1 Like
function startTimer(startVal, endVal)
	if tonumber(startVal) then
		startVal = math.round(startVal)
	else
		startVal = 60
	end
	if tonumber(endVal) then
		endVal = math.round(endVal) --math.round ensures integers only so that the later for loop cant iterate forever
	else
		endVal = 0
	end
	
	timerVal = startVal --should timerVal be local or global here?

	for i = startVal, endVal, -1 do --you dont need the return break end statement itll cause the loop to break one iteration cycle early
		timerVal = i --math.floor no longer necessary here
		task.wait(1)
	end

	return true
end

The math library function tonumber() allows decimal numbers (double float precision numbers) which could result in a never ending for loop.

1 Like

The for loop checks if the control variable is out of bounds, not just if i == range.

You can try this for yourself:

for i = 19.34287, 5.64, -1 do 
    print(i) 
end

Outputs 19.34287, 18.34287 … 6.34287