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))
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