Making multiple functions wait on their own time?

function first()
	spawn(function()
		wait(1)
		print("first")
	end)
end


function second()
	spawn(function()
		wait(2)
		print("second")
	end)
end


function third()
	spawn(function()
		wait(3)
		print("third")
	end)
end

while true do
	wait()
	first()
	second()
	third()
end

I want a while true do loop to constantly fire functions so that they will run again after waiting.
however Im having trouble getting each function to wait before firing again.
I added spawn() because adding wait in a function causes the while loop to stop.
and while the loop does not stop as planned the functions wont wait like they are supposed to. is there something I can do to fix this?

Can you show us the output from the code?

Adding a wait in the functions without spawn() shouldn’t break the loop.

adding wait() without spawn causes the while true do loop to wait until the function finishes which is not wanted.

the output shows all the prints in each function firing fast without waiting.

This is an issue with the way you’ve set up your code. In each iteration, all three of your functions are called. Each time these functions are called, they spawn new pseudothreads. Their waits aren’t associated with other threads.

You should look to make your system more event-based. What specifically are you trying to do that needs this kind of workflow in place?

currently this script is a test script for an npc script. in the npc script, there are several functions that do things like move around, or attack players. it is setup in the same way as this test script. the requirements it needs to meet:

each function needs to wait a certain amount of time before running again.
each function will have its own wait time.
the while true do loop is just there to keep the functions running over and over.

local debounces = {tick() - 1, tick() - 2, tick() - 3}

function first()
    if tick() - debounces[1] >= 1 then
        debounces[1] = tick()
        -- Do the rest of your code for the first function here.
    end
end

function second()
    if tick() - debounces[2] >= 2 then
        debounces[2] = tick()
        -- Do the rest of your code for the first second here.
    end
end
-- So on so forth, but this is probably not the most effective or efficient
-- way of doing the task.

while true do
    first()
    second()
    -- so on so forth.
    wait()
end

wouldnt this be the same as using a bunch of normal debounces? and even if I use debounces the for loop will still yield to functions that wait.

You can split each function into a separate loop. Each function should not use spawn itself, but instead you spawn a loop per function and call each function in each loop. Then each function will wait until being called again.

sounds promising, could you show me an example?

Sure.

Here’s what I mean:

spawn(function() -- Loop one
	while true do
		func1()
		wait(3) -- Every three seconds
	end
end)
spawn(function() -- Loop two
	while true do
		func2()
		wait(2) -- Every two seconds
	end
end)

By spawning multiple loops you can have each loop do separate yields. They all run at the same time so those two loops will run at different speeds. One every three seconds and the other every two seconds.

4 Likes

You’re false on your assumption that those would yield, because those functions aren’t technically waiting, they’re just checking time to run. I’ve done this before when making an NPC and it worked fine. However if it makes you feel more comfortable then you just wrap the function call in spawn; spawn(first)
spawn(second)