For loop repeating itself multiple times?

local A = game.ReplicatedStorage.Abnormalities
local LOA = game.ReplicatedStorage.Abnormalities:GetChildren()
local CA = math.random(#LOA)
print(LOA[CA])
local Abnorm
for i,RA in pairs(LOA) do
	if LOA[CA] == RA then
		print("Successful find!")
		RA.Parent = workspace
		Abnorm = RA
	end
end

I think this is the part of the code which creates the problem. it works fine the first two times but then it runs twice, then three times, then it jumped to 96 times. why is this happening?

1 Like

You can use the function break though to stop the loop.

1 Like
script.AData.Event:Connect(function(NName,NIntro,NATime,NRank,NPic)
	print(NATime)
	print(NName)
	print(NIntro)
	print(NRank)
	game.ReplicatedStorage["RFs&REs"].MD:FireAllClients(NName,NIntro,NRank,NPic, GM)
		

		repeat
		wait(1)
		NATime = NATime - 1
		print(NATime)
		game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(NATime)
		until NATime == 0
		Abnorm.Parent = game.ReplicatedStorage.Abnormalities
		game.ServerScriptService.GameSorting.GameEnd:Fire()
		workspace.BGS:Destroy()
	end)
end)

this part is what’s being repeated multiple times, i honestly don’t know what’s going on anymore

it’s only meant to print once yet it prints multiple times

1 Like

this makes no change to the issue

1 Like

Did you add a while do? Because its impossible for it to print alot of times if its just
print(LOA[CA])
And also
In
local CA = math.random(#LOA)
I don’t think there’s a point in using math.random because the script can only choose 1 number. So the script will just do local CA = #LOA

2 Likes

i did for a few other things. this is the entire script:

game.ServerScriptService.GameSorting.GameChange.Event:Connect(function()	
print("Getting the gamemode")
local GML = {"Original","Omega's Call","Clone","Power Outage"}
local SGM = math.random(#GML)
local GM = GML[SGM]

print("Getting the model")
local A = game.ReplicatedStorage.Abnormalities
local LOA = game.ReplicatedStorage.Abnormalities:GetChildren()
local CA = math.random(#LOA)
print(LOA[CA])
local Abnorm
for i,RA in pairs(LOA) do
	if LOA[CA] == RA then
		print("Successful find!")
		RA.Parent = workspace
		Abnorm = RA
		end	
end

script.AData.Event:Connect(function(NName,NIntro,NATime,NRank,NPic)
	print(NATime)
	print(NName)
	print(NIntro)
	print(NRank)
	game.ReplicatedStorage["RFs&REs"].MD:FireAllClients(NName,NIntro,NRank,NPic, GM)
		

		repeat
		wait(1)
		NATime = NATime - 1
		print(NATime)
		game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(NATime)
		until NATime == 0
		Abnorm.Parent = game.ReplicatedStorage.Abnormalities
		game.ServerScriptService.GameSorting.GameEnd:Fire()
		workspace.BGS:Destroy()
	end)
end)

(this script is also used to manage time and it’s also being repeated but i don’t know why)

-- first intermission
local ATime = 8
while ATime > 0 do
	wait(1)
	ATime = ATime - 1
	print(ATime)
	game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(ATime)
end

game.ServerScriptService.GameSorting.GameEnd.Event:Connect(function()
	local ATime = 8
	while ATime > 0 do
		wait(1)
		ATime = ATime - 1
		print(ATime)	
		game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(ATime)
		if ATime == 0 then
			game.ServerScriptService.GameSorting.GameChange:Fire()
		end
	end	
end)

it might be the bindable events, if not then i have no idea of what’s causing this effect to happen
image
(you can see the “x2” next to the numbers, implying that they’re running twice somehow, which is what i want to stop)

I believe i found it!
Its because you have 2 while do script with a timer to 8 to 1 seconds and it prints the same time.

but then why would it repeat more than 2 times after this? at one point it even got to 96
image

So, this typically occurs when you’re creating multiple loops through an event.

For example, let’s say you placed a while loop inside of the PlayerAdded event.

local calls = 0
game.Players.PlayerAdded:Connect(function(plr)
	while true do
		calls += 1
		print("Calls:",calls)
		wait(1)
	end
end)

… when one player joins the game, this loop will start adding 1 to calls every second
… when a second player joins, another loop will be created - so another 1 is added to calls every second

eventually this spirals the more players join the game.

That is the concept.

For you now, you need to two 3 things.

  1. Create meaningful print code
    – In a few cases, you simply print out the value without including an identifier - this makes it extremely difficult to keep track of which values contribute to which variables.
    For example
	print(NATime)
	print(NName)
	print(NIntro)
	print(NRank)

would be much better as

	print("NATime:", NATime, "NNName:", NName, "NIntro:", NIntro, "NRank:", NRank) -- reduces lines written to console and suggests which each value means.
  1. Track down which loops are multiplying
    – By using prints correctly, you should find it much easier to identify which of your loops are spiralling and to correct them.

  2. Format your code correctly
    – a lot of your code has odd formatting, making it difficult to read, for example;

script.AData.Event:Connect(function(NName,NIntro,NATime,NRank,NPic)
	print(NATime)
	print(NName)
	print(NIntro)
	print(NRank)
	game.ReplicatedStorage["RFs&REs"].MD:FireAllClients(NName,NIntro,NRank,NPic, GM)
		

		repeat
		wait(1)
		NATime = NATime - 1
		print(NATime)
		game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(NATime)
		until NATime == 0
		Abnorm.Parent = game.ReplicatedStorage.Abnormalities
		game.ServerScriptService.GameSorting.GameEnd:Fire()
		workspace.BGS:Destroy()
	end)
end)

this would look much better like this…

script.AData.Event:Connect(function(NName,NIntro,NATime,NRank,NPic)
	print(NATime)
	print(NName)
	print(NIntro)
	print(NRank)
	game.ReplicatedStorage["RFs&REs"].MD:FireAllClients(NName,NIntro,NRank,NPic, GM)

	repeat  					-- Correct and easily read indentation
		wait(1)
		NATime = NATime - 1
		print(NATime)
		game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(NATime)
	until NATime == 0

	Abnorm.Parent = game.ReplicatedStorage.Abnormalities
	game.ServerScriptService.GameSorting.GameEnd:Fire()
	workspace.BGS:Destroy()
end)

Doing these 3 things will help you to debug your code more effectively now and in the future.

2 Likes

i don’t exactly get what you mean, my loops aren’t infinite and they end at specific times

Thank you for this! i’ll try and impliment these it into my code so it’s easier to read

I don’t exactly know how to describe it fully, because it works normally the first two times but then it just spirals after those two times, and it’s everything after script.AData.Event:Connect(function(NName,NIntro,NATime,NRank,NPic) that get multiplied

this will be your problem then - like the PlayerAdded example I mentioned, I think this Event is being called multiple times somewhere while your for loop is running.

You could try adding a Debounce to the start of this event to check if your code is already running;

local CountDownRunning = false -- debounce
script.AData.Event:Connect(function(NName,NIntro,NATime,NRank,NPic)
	if (CountDownRunning == true) then return end -- if running, exit this event early
	CountDownRunning  = true

	print("NATime:", NATime, "NNName:", NName, "NIntro:", NIntro, "NRank:", NRank)
	game.ReplicatedStorage["RFs&REs"].MD:FireAllClients(NName,NIntro,NRank,NPic, GM)

	repeat 
		wait(1)
		NATime = NATime - 1
		print(NATime)
		game.ReplicatedStorage["RFs&REs"].Timer:FireAllClients(NATime)
	until NATime == 0

	Abnorm.Parent = game.ReplicatedStorage.Abnormalities
	game.ServerScriptService.GameSorting.GameEnd:Fire()
	workspace.BGS:Destroy()
	CountDownRunning = false -- only set false when everything has finished.
end)

Granted, this is only a patch to your problem - if this works for you, you should really look at where you’re calling this script.AData.Event event to prevent unnecessary calls.

1 Like

applying debounces didn’t change anything sadly.

It’s only being called once in another script which has no relevant loops.

data = game.ServerScriptService.GameSorting.AData
AnoName = "[TESTING CUBE]"
AnoIntro = "This one's a first. Literally! meet the first Abnormality introduced, Say hello to the TESTING CUBE!!!"
AnoTime = 10
AnoRank = "Literally Impossible"
AnoPic = "rbxassetid://7196200157"
Monaetr = script.Parent
Plrs = game.Players
print(Plrs)
wait(3)


if script.Parent.Parent == workspace then
	print("In workspace")
	   BGS = game.ReplicatedStorage.Abnormalitymusic["Song"]:Clone()
	   BGS:Play()
	   BGS.Name = "BGS"
	   BGS.Parent = workspace
	data:Fire(AnoName, AnoIntro, AnoTime, AnoRank, AnoPic)

	if not script.Parent.Parent == workspace then
		repeat wait()
		until script.Parent.Parent == workspace
	end
end

I didn’t really read much as I just woke up, but this is usually caused by events as it can create multiple executions of the same code (nearly) simultaneously. This is usually what you want to happen, except under particular situations. In those situations, you’ll want to disconnect the event event:Disconnect() once you’re done with it. Alternatively, you might not even want to attach a function to an event. You may just want to yield until the event has fired just once via event:Wait().

how would i use :Disconnect? i haven’t exactly used it before and the developer hub isn’t that clear to me

As a “real-world” example, I’ve found myself needing to have a loop run until the player or some other humanoid has died. It would look something like this:

(assuming ‘Character’ is already defined)

local dead
local died
died = Character:WaitForChild('Humanoid').Died:Connect(function()
	died:Disconnect()
	dead = true
end)
repeat
	task.wait()
	--some code
until dead

This in particular isn’t entirely necessary as the died event will only fire once per humanoid. However, I prefer to keep my code clean and not have an event indefinitely listening for an event that will never occur again.

2 Likes

It finally works, thank you so all much for your help!
I will be sure to use your information in future scripts too :smiley:

1 Like