Modules using coroutine.yield cannot return

If a module required in a coroutine calls coroutine.yield() and is resumed, the original require call will never return and the thread will be killed once the module returns.

I’m handling dependencies using a function I wrote to have modules wait until other modules have been required before resuming. The modules are required inside a coroutine so that they can be yielded if necessary and then resumed after their dependencies all exist. When they call coroutine.yield(), though, they can no longer return after they are resumed. They finish running as they normally would, but the require call itself never returns. The status of the coroutine after the module finishes is “dead” even though the function that required it never finished.

Here’s an example:

Script in ServerScriptService:

print("script running")
require(game.ServerScriptService.ModuleScript)
print("script finishing")

ModuleScript in ServerScriptService:

print("ModuleScript running")
local thread = coroutine.running()
coroutine.wrap(function()
	wait(1)
	coroutine.resume(thread)
	wait(1)
	print(coroutine.status(thread))
end)()
print("ModuleScript yielding")
coroutine.yield()
print("ModuleScript resumed")
return true

Output:
script running
ModuleScript running
ModuleScript yielding
ModuleScript resumed
dead

The code after the require call never runs and the coroutine is terminated.

4 Likes

According to Woot3, this actually isn’t related to coroutine.yield:

I can confirm this is a known issue. When I get the chance I’m going to dive into it further but for now you may be better off using a BindableEvent.

1 Like