Having trouble understanding coroutine.resume

Hi, I’m working with a lot of threads right now in a script and I’m using coroutine.resume() a lot. But I don’t fully understand how it’s return values work. It returns if the coroutine succeeded in running, and the return values that the threads gave back, but if it errors then it returns the error?

And also what is success while the coroutine is running? Does it change? Or is it just the success of starting the function? I don’t understand it.

3 Likes

It works exactly how you described. The results don’t change once they are returned.

1. First returned value: status (boolean)

A coroutine is successfully resumed if its runs successfully without errors until the end of the coroutine or the first yield.

If there is no yield in the function whatsoever, it executes in its entirety and exits in same frame. If the function yields at some point, only the part of the body before the yield will execute during the same resumption.

The yield doesn’t have to be explicit coroutine.yield. It might as well be task.wait(), for example:

local c = coroutine.create(function()
	print("resumed") --> resumed
	task.wait()
	print("resumed again") --> resumed again
    return "exit"
end)
local success, result = coroutine.resume(c)
print(success, result) --> true nil

The task.wait() and the rest of the function is resumed by the task scheduler the following frame.

2. Second returned value: tuple (any) or error message (string)

  • Values returned on function exit.
  • Values passed to coroutine.yield().
local c = coroutine.create(function(message)
	for i=1,3 do
		coroutine.yield(string.rep(message, i))
	end
	return "over"
end)

local success, result = coroutine.resume(c, "echo")
print(success, result) --> true echo
print(coroutine.resume(c)) --> true echoecho
print(coroutine.resume(c)) --> true echoechoecho
print(coroutine.resume(c)) --> true over

Aside from its main purpose, coroutine.yield() can take arguments coroutine.resume() returns after the status code. It might be a tuple of arguments.

  • Error message (failure to resume, failure during execution).

The result may be an error message. However, an error in a coroutine with multiple yields will not affect any resumptions before the erroring part is resumed. Anything beyond cannot run because an error terminates a coroutine.

local c = coroutine.create(function(message)
	print("no troubles") --> no troubles
	coroutine.yield()
	error("OOF")
	coroutine.yield()
	print("cannot print")
end)
print(coroutine.resume(c)) --> true nil
print(coroutine.resume(c)) --> false ServerScriptService.Script:4: OOF
print(coroutine.resume(c)) --> false cannot resume dead coroutine
2 Likes

Ah, this makes sense now. It wouldn’t make sense for that to happens because booleans aren’t pass by reference in Luau, so there would be no way for the value to change.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.