Do functions yield the whole script?

I have a script with most of my main functions for a game in it, it also have a multitude of events connected to these functions, if two of these events fire, two functions are now running, will they run simultaneously or do they run one after the other? If one of these functions had a while loop and was triggered right before the other function, would the other function be yielded until the while loop is broken?

1 Like

Functions connected to events will run simultaneously

1 Like

Unless you are using parallel lua, two pieces of code will not be able to run at exactly the same time, it will instead run one after the other.
A while loop will prevent code lower down from running, but it wont prevent other “tasks” (or threads) from running.

Roblox has the task scheduler which basically manages all the tasks/threads. When a task yeilds (task.wait(), .Event:Wait(), asynchronous functions, etc), another task will be ran.
Lets say you have a task.wait() in your while loop. When task.wait() is reached, the task scheduler will run another task/thread, like an other script. On the next frame, the task scheduler will resume the task and the while loop will run again, until the code yeilds again.

If you have a while loop that never yeilds, it will prevent other code from running (like other connected events, and your events do not run at exactly the same time, unless you use :ConnectParallel). In the case of a while loop that never yeilds, well, it will probably crash studio (or cause the timeout error), or if it does a very heavy workload that takes 3 seconds, nothing else will be running in those 3 seconds.

can’t you use corountines to run other code while a loop is running?

1 Like

Yes, coroutines create other threads, though they aren’t managed by the task scheduler. Similarly to task.wait() and stuff, coroutine.yeild() pauses the thread to allow you to run another one, but you can’t run another thread without yeilding
Technically, the while loop isn’t running at that point

If any of your functions has a function which yields the thread (e.g. task.wait()),
then the rest of the function will wait. I use task.spawn(function()) to create the function in a separate thread:

task.spawn(function()
        print("Hello, World!")
      end
end)

There is a devhub article for task.spawn() as well.

1 Like

pauses? I have a spawning/despawning system that uses a corountine, but it doesn’t feel like the spawn pauses when the despawn is happening below. :thinking:
I mean there are task.waits in both functions, so they can’t really wait for the other to yield without making the spawning delayed, no?

The different threads all run one after the other, without any delay (other than the time it takes for the cpu to do the math)
You can put something like this in your script

print("Running task spawning")
print(os.clock()) -- Returns a high precision time from the cpu

What you should see is all the tasks being printed one after the other, with the precise time. None of the task will have a time that is in between two prints of one task (that doesn’t yeild)

When a task.wait() is reached, it doesn’t “wait”, what it does is run other tasks, and on the next frame (or after a couple, if you set a wait time), it will resume the task

1 Like

Lets say I have two parts, in a single script I specify each part and connect a function that does print(“part1”) and does wait(15) to part1, for part2 I put just print(“part2”), if part1 gets touched and then part2 gets touched, since their functions are in the same script will the print(“part2”) run after 15 seconds? or will it run simultaneously?

I actually just tested this:
image

The functions don’t run simultaneously but it doesn’t get yielded by 15 seconds which is what I thought would happen lol
image

This is really interesting to me cuz I didn’t know about this, task.wait() gives time for other scripts to run? what are the advantages of utilizing other threads in games?

Yep, that thread stops running and is resumed on the next frame

When you connect to an event, that’s a new thread. Basically, the event is fired, all the connected functions are ran.
It would be possible to not have new threads when firing events, through a custom event implementation. How those work is that when the event is fired, the thread that fired the event runs the connected events directly without making a thread (which has performance benefits). However, this has the downside that if a connected function yeild, it will yeild the whole thread, which includes, connected functions that have yet to be ran, and the part of the script that fired the event

Threads are just something that happen, managed by Roblox (or you could make your own implementation with coroutines I guess). You don’t really think about them, they just exist.

task.spawn() can be used to create a thread that will run right away (it will pause the current thread to run task.spawn(), before resuming it)
task.defer() can be used to create a thread that will run after the current one (I think, maybe other threads are ran before). But the thread will be ran in the same frame
task.delay() can be used to create a thread that will run on another frame