Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Getting this error about coroutines when I call `wait`?

Yo! I'm developing a stand game with a team, I have a function in a Utilities module to reload the character and teleport them back to where they were. This has worked in the past, but when I call it using my quick and dirty admin, it produces this error: - attempt to yield across metamethod/C-call boundary and then it says: cannot resume non-suspended coroutine only 50 milliseconds later. The errors specifically points me to the wait in the ReloadChar function.

This is my code:

-- Reload character
function Utilities.ReloadChar(Player)
	if (not Player.Character) then return end;
	local Location = Player.Character.HumanoidRootPart.CFrame;
	Player:LoadCharacter();
	wait()
	Player.Character.HumanoidRootPart.CFrame = Location;
end

And this is where I'm calling it:

-- Utilities.GetPlayers just returns a table based on the input.
self:AddCommand("GiveStand", Command.new("GiveStand", function(Player, ...)
	if (not Player.Character) then return end;
	
	local Args = {...}
	local Who = Args[1]
	local NameId = Args[2] -- Could be the name or id.
	local StandId = StandIds.GetId((NameId)) or StandIds.Ids[tonumber(NameId)];
	local Found = Utilities.GetPlayers(Player, Who)
	if (StandId and Found) then
		if (type(StandId) == 'table') then StandId = tonumber(NameId) end; -- If it's the stand table, reset it to the id.
		
		table.foreach(Found, function(_,PLAYER)
			SavedDataService:SetPlayerValue(PLAYER, "Stand", StandId);
			Utilities.ReloadChar(PLAYER);
		end)			
		
	end
end))

2 answers

For more context visit here

That's because converts threads into Roblox threads so You cannot pause a function with a coroutine so for example you cannot use the function :Wait() this will yield an error to fix this there are to possible ways to fix this 1st you can use coroutine.yield this will suspended/stop the function from running the second way is to use a Bindable event Bindable events work similarly to remote events but you can pause it using something like event:Wait although I'm not particularly sure.

To pause a coroutine / resume here's a example

coroutine.yield -- stop s a function
coroutine.resume -- resumes a function

table.foreach doesn't support yielding within the function passed to it. wait involves yielding, which is a problem there. Luckily a different way of iterating over a table supports yielding: for loops. They're also recommended over table.foreach (table.foreach is very outdated!). Here's an example of how easy converting it can be:

table.foreach(Table, function(Key, Value)
	print("Key", Key, "Value", Value)
end)

can be rewritten as

for Key, Value in pairs(Table) do
	print("Key", Key, "Value", Value)
end

This discussion is preserved as it was. New answers, comments, and votes are closed.