While loop keeps running even when using break

Have you tried the fix that I suggested right below that part?

1 Like

Slightly confused as to what you mean by this tho??

1 Like

Instead of doing

UpdateMood:FireServer(true, 'Energy')

do

UpdateMood:FireServer({}, 'Energy')

(don’t change false) and see if it fixes the loop running more than once. If it does, you will know that the issue is that normally your boolean is set back to true before the loop notices it’s false.
Also make sure to change your loop’s condition to while active == Updating do

1 Like

Might be overkill and it sounds like you have a more fundamental problem somewhere, but this will prevent more than 1 loop running at once.

I also suggest putting a wait before you call the loop, and then any subsequent waits at the end of the loop to prevent the scenario where updating goes false, but the loop still runs as you’re caught in the 3 second wait window.

local loopId = 0
local updating = false

function yourLoop( active )
    if active == updating then
        return
    end

    updating = active

    if updating then
        local identifier = loopId + 1
        loopId = identifier
        
        wait( 3 )
        while updating and loopId == identifier do
            -- your stuff here
            wait( 3 )
        end
    end
end
1 Like

Hmmm, it still does it. But it’s like not reliant. So I spammed the function a dozen times or so, stopped, and let it print, and it would print 1 every 3 seconds. Then when I did it another 10 times, it would do the usual print 1 multiple times in that 3 second span

1 Like

What’s probably happening is that because you don’t have the loop in a separate thread, it’s preventing any further execution of code. Even if it does not, the function update references a new scope every time. That means every time you call it, it starts a new while loop and uses the arguments you pass to update for it’s conditional statement.

2 Likes

This code may suffice:

--[[
spawn the loop in a separate thread for each player
to guarantee that there aren't any duplicate loops.
--]]
local Updating = false
local UpdatingMood
game.Players.PlayerAdded:Connect(function(player)
	-- this doesn't have to be a coroutine,
	-- but it will help with my explanation at the bottom.
	coroutine.wrap(function()
		while player:IsDescendantOf(game.Players) do
		-- keeping players in a {[player] = bool} table is also a good idea,
		-- with Players.PlayerRemoving removing them from the table.
			if Updating and UpdatingMood then
				print(1)
				if User.Moods[UpdatingMood] < 100 then
					User.Moods[UpdatingMood] = User.Moods[UpdatingMood] + 5
					getMood(player)
				end
			end
			wait(3)
		end
	end)()
end)

--[[
make `update` a setter for Updating and UpdatingMood
instead of also starting loops
--]]
local function update(player, active, mood) --Player, bool, string
	Updating = active
	UpdatingMood = mood
end

This is how you would prevent duplicate loops, by not allowing update to start them, but it is probably not the best way to structure your loop if there are multiple loops for moods that have to be updated, in which case you would iterate through an entire table of moods instead.

This does not account for what will happen when multiple players are in your game; Updating and UpdatingMood, as well as User, are not player-specific variables, and there will probably have to be some kind of change in architecture to achieve this.

However, if this all happens to be in a giant game.Players.PlayerAdded connection, you would probably want to make sure update is referring to the right player, and that the coroutine connected to PlayerAdded in my function is by itself.

2 Likes

Rather than start a new logic loop for each player that joins, I think you should take a task-scheduling approach. Essentially, you have an array of ‘tasks’ that a singular while-loop executes periodically. Whenever a player joins the game, you then schedule that new task. This allows you to better manage your system, reduce spaghetti-code, and improve performance by reducing the amount of overhead required for each player’s own routine.

Ok I believe this works :smiley: :smiley: Well I tested it a few times and it seemed to look good :smiley:

Much appreciated :smiley: :smiley:

2 Likes