I'm pretty sure I have the differences between the two understood, but correct me if I'm wrong:
Basically a faster way to create a coroutine, along with calling coroutine.yield
before it executes.
Same as coroutine.create(f)
except you can call it like a normal function each time you want to resume the thread.
So my question is, which is generally better to use? Are there any specific situations where one may be favorable over the other? Is there any behind the scenes work going on that I should know about? Also, how many of these threads could I have running at once before it starts causing performance deficiencies?
Sorry for the barrage of questions, but if anyone can help I sure would appreciate it.
spawn
If your code does not use coroutine.yield
, you do not have business using the coroutine
library.
Use spawn
.
Lua is single-threaded. Only one piece of code runs at a time.
A coroutine can signal to its runner that it is going to take a break using coroutine.yield
. ROBLOX uses wait()
as the opportunity to yield. This makes the current script stop running. ROBLOX then picks another script and lets it run, until the next wait()
.
spawn
tells ROBLOX about a new function to schedule. It puts it into the queue so that it can be picked later when the current script is done working.
coroutine.resume
and coroutine.wrap
are a pure Lua concept; they don't actually have to do with different tasks running. Because ROBLOX uses coroutines to implement tasks, you can actually just wait()
within a new coroutine, and that coroutine will start being scheduled.
While this does appear to work, it doesn't work when you actually use coroutines as coroutines (because ROBLOX has taken them over). This can get confusing fast; this is why it is easy to recommend spawn
: it means what it does and does only what it means.
There is one small practical difference between spawn
ing a new task and explicitly creating a coroutine.
coroutine.resume(coroutine.create(f))
will run f()
immediately.
spawn(f)
will just queue up f()
to be run later.
print("before") coroutine.wrap(function() print("now") wait(1) print("later") end)() print("after") --> before --> now --> after --> later print("before") spawn(function() print("now") wait(1) print("later") end) print("after") --> before --> after --> now --> later
This has little practical consequence, since if you really need some code to finish before you can move on, you shouldn't be doing it in a different task anyway.