Is there a better way to make a loop for a timer

i’m trying to make a timer for a microwave, but the problem is that i don’t know how to make it stop immediately, like whenever someone opens the door(you don’t want them to get cooked too)

while loop and for loop are out of the question also repeat until(its almost pretty much the same as a while loop) because mainly 1 problem and that is, it has to wait until conditional in order to be stopped

problem:

local counting = true

local timer = 0 --timer variable

while true do
	timer += 1 --increase timer by 1
	print(timer) --prints the time into the output
	wait(10) --has to wait
	if not counting then return end --until it gets to condition
end

it becomes more noticeable when you increase the wait time, it won’t stop waiting immediately after you try to stop it

and also i’ve been testing out run service, not sure if should either use heartbeat, stepped, or rendered steppe for a timer on the server

idk what to use, but should i use tick or modulus operator for the cool down?
also i dont really know what they do exactly, i’ve only been experimenting with them each
tick

local tickk = 0

local function cook()
	if tick() >= tickk then --look its tick
		if minutes > 0 and seconds <= 0 then
			minutes -= 1
			seconds = 59
		else
			seconds -= 1
		end
		task.wait()
		tickk = tick() + 1
		if minutes <= 0 and seconds <= 0 then print("done!") return end
	end
end

or modulus operator

local dbounce += 1

local function cook()
	dbounce += 1
	if dbounce % 60 ~= 0 then return end--look its modulus operator
	if minutes > 0 and seconds <= 0 then
		minutes -= 1
		seconds = 59
	else
		seconds -= 1
	end
	task.wait()
	if minutes <= 0 and seconds <= 0 then print("done!") return end
end

please help, which one is faster or better

also here is the model if you wanna mess around with it
microwaveahh.rbxm (11.4 KB)

2 Likes

I couldn’t really understand what you are trying to achieve. Are you trying to stop the while loop? If so then use break

i would use a while loop, but trying to stop it from outside of it, it’s not really the easiest

Well i think you are having the following problem. You start the loop but then you aren’t able to change the counting variable because the loop is running and the code doesn’t continue. To solve this problem run the loop in a coroutine like this.

local counting = false

coroutine.wrap(function()
    while counting do
        --do stuff here
        task.wait()
    end
end)() --The brackets are used to run the coroutine as coroutine.wrap returns a function

even:Connect(function()
    counting = true
end)

otherEvent:Connect(function()
    counting = false
end)

would that necessarily stop the coroutine? by changing the variable?

The corouting won’t stop, the loop will just not run while counting is false or nil. The coroutine is used just to run the while loop in a separate thread and not stop the code when it starts running

This actually helped me, I was having the same trouble yesterday

1 Like

coroutine.wrap is just waste of memory.
Try this:

local counting = true

local timer = 0 --timer variable
local lastTick = tick()

while wait() do
	if tick() - lastTick > 10 then
        timer += 1 --increase timer by 1
	    print(timer) --prints the time into the output
        lastTick = tick()
    end
	if not counting then return end --until it gets to condition
end

If you don’t use it code that is written after the while loop won’t run.

The loop will, but the next command dont.

That’s what i said so he wouldn’t be able to change the variable unless he sets up the event before the loop

But he can put commands before loop.


local counting = false

even:Connect(function()
    counting = true
end)

otherEvent:Connect(function()
    counting = false
end)

while counting and wait() do
    if tick() - lastTick > 10 then
        timer += 1 --increase timer by 1
	    print(timer) --prints the time into the output
        lastTick = tick()
    end
 end

That is litterally what i just said…

Yeah but running new unnecessary threads will consume more memory.

You could run your timer within a Heartbeat event and then when if you want to stop the timer prematurely you just disconnect the heartbeat event.

local timerLength = 10 --10 seconds
local timerStartTime = tick()
local stopTimer = false
local timerHeartbeat

timerHeartbeat = game:GetService("RunService").Heartbeat:Connect(function()
     local timeElapsed = tick() - timerStartTime --How much time has passed since the timer started
     
     if timeElapsed >= timerLength or stopTimer then
         timerHeartbeat:Disconnect() --Stops the timer
     end
end)

With this code you can set stopTimer to true and that should disconnect the timerHeartbeat and stop the timer. Alternatively you could just call timerHeartbeat:Disconnect() to stop the timer

You can just use a while loop. (I know they said they can’t have one, but keep reading)

This while loop would be in script 1.
In script 2 you could make it so whenever the door opens, you can call a function. This function will disable script 1.

If you need script 1 again, just enable it.

If you need me to explain more, I can!

i don’t think disabling the script would work

It does, actually. I use this method for my flashlight. :slight_smile:

wait really? i thought disabling script does nothing, and disabling it only works prior before playing the game