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

Callbacks cannot yield?

I have this money giving system and it bases how much money they receive on what team they are on. I keep getting the error that callbacks cannot yield. I'm quite confused as I don't get this error if I remove those "ifs" regarding whether they're on a specific team or not.

local DS = game:GetService("DataStoreService"):GetDataStore("CoB_Money3")

x = 50

game.Players.PlayerAdded:connect(function(plr)
	while x <= 50 and x > 0 do
		wait(1)
		x = x - 1
		plr.PlayerGui.Menu_UI.Main.Wait.Text = x.."s"
		if x == 0 then
			x = 50
			DS:UpdateAsync("user_"..plr.userId, function(o)
				local n = o or 0
				if plr.TeamColor == BrickColor.new("Smoky grey") and not plr:IsInGroup(2634853) then -- If they're not in Broadview
					return n + 10
				elseif plr.TeamColor == BrickColor.new("Smoky grey") and plr:IsInGroup(2634853) then -- If they're a citizen of Broadview
					return n + 15
				elseif plr.TeamColor == BrickColor.new("Deep blue") then -- If they're on the BPD team
					return n + 20
				elseif plr.TeamColor == BrickColor.new("Persimmon") then -- If they're on the BFD team
					return n + 20
				end
			end)
		end
	end
end)

1 answer

✓ Accepted answer

Breaking down the error

Callback

A callback is a function you give away hoping that it will be called later. In this case, it's the function(o) that you give to UpdateAsync

yield

A yield occurs when the script pauses. wait() is the most common way that happens.

In this case, the yield is actually caused by :IsInGroup -- ROBLOX has to pause because it needs to spend time asking the website if you're in a given group.

UpdateAsync requires that this doesn't happen, so you can't use :IsInGroup inside of this function.


Solution

The solution is to compute plr:IsInGroup(2634853) before the callback. It could look something like this:

		if x == 0 then
			x = 50
			local inGroup = plr:IsInGroup(2634853)
			DS:UpdateAsync("user_"..plr.userId, function(o)
				local n = o or 0
				if plr.TeamColor == BrickColor.new("Smoky grey") and not inGroup then -- If they're not in Broadview
					return n + 10
				elseif plr.TeamColor == BrickColor.new("Smoky grey") and inGroup then -- If they're a citizen of Broadview
					return n + 15
				elseif plr.TeamColor == BrickColor.new("Deep blue") then -- If they're on the BPD team
					return n + 20

Cleanup

I notice that the condition of your while loop isn't really necessary -- x will always be between 0 and 50. I recommend writing ranges out in order, by the way: 0 < x and x <= 50. It makes it much easier to understand.

The way you check, decrease, and reset x is a little clunky -- a for loop would get that for you for free. I recommend shaping it like this:

local DS = game:GetService("DataStoreService"):GetDataStore("CoB_Money3")

game.Players.PlayerAdded:connect(function(plr)
	while true do
		for t = 50, 0, -1 do
			plr.PlayerGui.Menu_UI.Main.Wait.Text = t .. "s"
			wait(1)
		end
		local inGroup = plr:IsInGroup(2634853)
		DS:UpdateAsync("user_" .. plr.userId, function(o)
			local n = o or 0
			if plr.TeamColor == BrickColor.new("Smoky grey") and not inGroup then -- If they're not in Broadview
				return n + 10
			elseif plr.TeamColor == BrickColor.new("Smoky grey") and inGroup then -- If they're a citizen of Broadview
				return n + 15
			elseif plr.TeamColor == BrickColor.new("Deep blue") then -- If they're on the BPD team
				return n + 20
			elseif plr.TeamColor == BrickColor.new("Persimmon") then -- If they're on the BFD team
				return n + 20
			end
		end)
	end
end)

1 comment

0

I really appreciate the answer-I did not realize that IsInGroup was the function yielding this. Thanks!

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