✓ Accepted answer
To understand how to take everything out of threads, you have to understand what the Roblox task scheduler is -- the underlying system that's managing which thread to run and when. Keep in mind it's not multithreading in the sense of running code in different computer cores.
None of your script instances are run at the exact same time as they are executed singlethreaded; by one computer core. However, the task scheduler allows them to run right after one another, appearing like they are running in parallel.
As the machine clock updates, the system iterates through all the threads found between the last update timestamp and the new timestamp in the order of appearance and continues their execution. You can think of the task scheduler as an ordered stack where whenever your code yields, the yielding thread is pushed to the stack, position defined by the timestamp (with the wait function sys_time + yield_time). The scheduler steps to the next thread immediately after the one being executed ends or yields.
Each of your script instances (not ModuleScripts as they're used by script instances) are their own thread. However, coroutines allow them to create new, completely separate threads. They still function the exact same. When you execute a coroutine, the caller thread is paused by the task scheduler until the coroutine thread yields or ends, then the caller thread is continued. If the coroutine yields, it is pushed to the corresponding position in the stack.
In simple terms, creating a new thread with coroutines is like creating a new script instance.
The spawn function also uses coroutines. What it does is simply push the new created thread to the next step in the task scheduler -- so pretty much at timestamp sys_time + 1/60.
2 comments
ill explain this tomorrow if i remember as i'm going to bed right now
Thanks. I'll check back then.