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)
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?
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
Think you have to do this. To be fair, this is overcomplicating this a lot (also messy, stupid ), 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)
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)
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
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
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
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