Thinking about it more, you don’t need to anything special if betterSpawn
is to behave like spawn
(minus the delay). Within an engine-owned thread, calling coroutine.yield
basically kills the thread; the engine does nothing, and wont make any attempt to resume it later. betterSpawn
, wanting to behave like spawn
, can apply this behavior as well, which simplifies the implementation back down to what you already had in the OP. Only if you wanted to have coroutine.yield
do things like resume the thread later, would you have to get into complicated things with sentinel values and whatnot.
My only gripe then is that betterSpawn
returns the error. It implies that the caller will always have control over the thread, and that betterSpawn
will somehow always return the error even if it occurs after yielding to the engine, instead of just after the first resume. This sort of thing is something that confuses a lot of people, which is why coroutine.resume
gets misused so often. That was another part of the reason why I originally ruled out a debug-error
-like solution.
Interestingly, implementations that are almost exactly the same as betterSpawn
have been written over and over again. Here’s me with one last year:
And here’s another one sometime later:
And another all the way from 5 years ago: