How would i break this kind of for loop?

So im tryna making a for loop with some property changed in it, What i want is to make the for loop break once the property change returns true.

The problem here is that “Break statement must be put inside a loop”

code:

for i,v in ipairs(Hours) do
		
		worksGameFold:SetAttribute("Hour",tonumber(v))
		worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)
		
		worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
			if worksGameFold:GetAttribute("Gameover") == true then
				break -- THIS LINE YIELD 'Break statement must be put inside a loop'
			end
		end)
		
		task.wait(HourTime)
		
		if i == 7 then
			break
		end
		
	end

This should work, but still a probably unnecessary coroutine.

local c = coroutine.create(function()
	for i,v in ipairs(Hours) do

		worksGameFold:SetAttribute("Hour",tonumber(v))
		worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)

		worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
			if worksGameFold:GetAttribute("Gameover") == true then
				coroutine.yield()
			end
		end)

		task.wait(HourTime)

		if i == 7 then
			coroutine.yield()
		end

	end
end)

Also only just recently learned about coroutines.

under the code there’s a code that just stops the entire game and then it’ll move to the next night so wont putting a coroutine just skip the for loop?

Forgot to mention that, let me code something to fix this.

debounce

local debounce:boolean = false

for---
if debounce==true then break end

worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
			if worksGameFold:GetAttribute("Gameover") == true then
				debounce=true
			end
		end)

end

char limitaaaaa

Think you have to do this. To be fair, this is overcomplicating this a lot (also messy, stupid :cold_face:), but i don’t know a way to break the for loop any other way.

local function gameOver()
	-- code below
end

local c = coroutine.create(function()
	for i, v in ipairs(Hours) do
		worksGameFold:SetAttribute("Hour",tonumber(v))
		worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)

		worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
			if worksGameFold:GetAttribute("Gameover") == true then
				coroutine.yield()
			end
		end)

		task.wait(HourTime)

		if i == 7 then
			coroutine.yield()
		end

	end
	gameOver()
end)

Probably should do something else. :man_shrugging:

1 Like

You are overthinking too much also yielded coroutine has a chance to not get gced properly

local c:Thread
c = coroutine.create(function()
	for i,v in ipairs(Hours) do

		worksGameFold:SetAttribute("Hour",tonumber(v))
		worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)

		worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
			if worksGameFold:GetAttribute("Gameover") == true then
				coroutine.close(c)
			end
		end)

		task.wait(HourTime)

		if i == 7 then
			coroutine.close(c)
		end

	end
end)

That a double closure tho
It can be collapsed to be a singular closure using corutine.running() in a beggining of function for c referance

Just actually thought and realized that this is the most stupid answer :sob:.
This will NOT work. Sorry for the bad answer.

Tbh i dont think db would work cuz the code have to run everytime like a while loop/changed events and when it does it’ll check the val, if it true then it break.

My guess? coroutines + while loop, but im aware if its unoptimized

This should actually work, and not be stupid, hopefully:

for i,v in ipairs(Hours) do
	local valid = true -- dont know what else to call it

	worksGameFold:SetAttribute("Hour",tonumber(v))
	worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)

	worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
		if worksGameFold:GetAttribute("Gameover") == true then
			valid = false
		end
	end)

	task.wait(HourTime)
	
	if valid == false or i == 7 then
		break
	end
end

in coroutines you can avoid closures if you do coroutine.running() to get current thread.
You can disconnect event fire
also you can just move it out of loop anyway

local db:boolean = false
worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function():()
	if worksGameFold:GetAttribute("Gameover") == true then
		db=true
	end
end)
for i,v in Hours do
		if db==true break end
		worksGameFold:SetAttribute("Hour",tonumber(v))
		worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)
		
		
		
		task.wait(HourTime)
		
		if i == 7 then
			break
		end
		
	end

It does work but you’ll have to wait until the task.wait(h) is done

That literally a programming warcrime.
Allocating memory for a variable inside every new scope :skull:

Then put the wait below it. :man_shrugging:

charcharcharchar

the “if” wont run like forever it’ll run only once

why not add the Game over attribute check before the loop main code?
if Gameover is true then loop will break thus the rest of loop code will not run

for i,v in ipairs(Hours) do
	
	if worksGameFold:GetAttribute("Gameover") == true then
		break 
	end
	
	
	worksGameFold:SetAttribute("Hour",tonumber(v))
	worksGameFold:SetAttribute("EnemyLvl",NightMod[tostring(v)].Enemies)

	task.wait(HourTime)
	if i == 7 then
		break
	end
end
1 Like
local stop = false

worksGameFold:GetAttributeChangedSignal("Gameover"):Connect(function()
	if worksGameFold:GetAttribute("Gameover") == true then
		stop = true
	end
end)

for i, v in ipairs(Hours) do
	if stop then break end

	worksGameFold:SetAttribute("Hour", tonumber(v))
	worksGameFold:SetAttribute("EnemyLvl", NightMod[tostring(v)].Enemies)

	task.wait(HourTime)
	if i == 7 then break end
end
1 Like

Might be the stupidest of all solutions but what about putting the loop into a function and replacing break with return nil

Nevermind, rescripted

local hour = 0 -- or 1 idk

while hour < 7 and not worksGameFold:GetAttribute("Gameover") do
    hour += 1
    -- your attribute adding stuff and task.wait() i'd copy and paste but im on my phone so its janky
end
hour = nil -- so garbage collector gets rid of this now useless global scope variable
1 Like