Function multiplying whenever it's ran

i was making a boss for my game, and I use a module script for organizing it’s attacks, and I use a script for firing them.

On one attack, it would run a function for every player in the game, and it’s supposed to throw a bomb at them, and it works fine until I started noticing that every time the function fires, the amount in the for loop is multiplied. And also hitboxes are spawning out of thin air, even though there isn’t any bombs there.

My module works weirdly, but I’ve never encountered this. It has a function that spawns bombs with the parameter of the players humanoid root part, and it fires for every player.

If anyone could tell my why this happens, please do.

Edit: I will provide screenshots (of my messy code) (and the bug) later, as it’s almost midnight and I’m going to sleep. I will check this as soon as possible.

1 Like

Remote event (or bindable events) behave like coroutines. From your description, it sounds like “multiple” of your function is running at the same time.

One way to mitigate this is before the module start running, the server check wether it is already running.

Does your attack have a cooldown? perhaps have the function disconnect itself the moment it start, and reconnect when it stops?

1 Like

Heres my code:

Server Script:

local atkModule = require(script.Parent.Attacks)
local cd = 0

local function slashes()
	atkModule.Slashes.attackEvent()
end

local function bombs()
	atkModule.Bombs.attackEvent()
end

wait(5) --start time

while wait(cd) do
	bombs()
	cd = 7
end

Module script:

local ts = game:GetService("TweenService")
local debris = game:GetService("Debris")
local boss = workspace["boss fite"]["Guardian of Starlight"]
local hitboxes = require(game.ReplicatedStorage.Hitboxes)
local anims = {
	slashes = boss.Humanoid:LoadAnimation(script.slashes),
	bombs = boss.Humanoid:LoadAnimation(script.bombs),
}
for _, v:AnimationTrack in pairs(anims) do
	v.Priority = Enum.AnimationPriority.Action4
end
local module = {
	["Slashes"] = {
		attackEvent = function()
			local parts = {}
			local function slashes()
				spawn(function()
					local x = 0
					for i = 1, 20 do
						x = x + 18
						local beam = Instance.new("Part")
						local vfx = script.Beams:Clone()
						vfx.Parent = beam
						beam.CanCollide = false
						beam.CanQuery = false
						beam.Anchored = true
						beam.Size = Vector3.new(500, 0.2, 0.2)
						beam.Position = boss.HumanoidRootPart.Position
						beam.Material = Enum.Material.Neon
						beam.Color = Color3.new(0.537255, 0.129412, 0.792157)
						beam.Orientation = Vector3.new(0, x, 0)
						beam.CFrame = beam.CFrame * CFrame.new(0, 0, -5)
						beam.Parent = workspace
						table.insert(parts, beam)
						debris:AddItem(beam, 5)
						
						task.wait(0.02)
					end
				end)
			end
			delay(0, function()
				boss.Humanoid.WalkSpeed = 0
				anims.slashes:Play()
				task.spawn(function()
					slashes()
				end)
				task.wait(1)
				boss["Currupted Galaxy Sword"].grip.mid.Attachment.lines:Emit(10)
				boss["Currupted Galaxy Sword"].grip.mid.Attachment.cricle:Emit(3)
				task.wait(0.4)
				task.spawn(function()
					for i, v in pairs(parts) do
						task.spawn(function()
							v.Size = Vector3.new(500, 1.5, 1.5)
							v.Beams:Emit(150)
							local info = TweenInfo.new(.5, Enum.EasingStyle.Linear)
							local props = {Size = Vector3.new(2048, 0, 0), Transparency = 1}
							local tween = ts:Create(v, info, props)
							tween:Play()
							local hitbox = hitboxes.CreateHitbox()
							hitbox.CFrame = v.CFrame
							hitbox.Size = v.Size
							local params = OverlapParams.new()
							params.FilterType = Enum.RaycastFilterType.Exclude
							params.FilterDescendantsInstances = {boss}
							hitbox.OverlapParams = params
							hitbox.Visualizer = false
							hitbox.Touched:Connect(function(hit, hum)
								if not hit.Parent:IsA("Tool") and hum then
									hum:TakeDamage(15)
								end
							end)
							hitbox:Start()
							task.wait(0.1)
							hitbox:Stop()
						end)
					end
				end)
			end)
			return
		end,
	},
	
	["Bombs"] = {
		attackEvent = function()
			local function bombThrow(plr)
				spawn(function()
					local bombs = {}
					boss.Humanoid.WalkSpeed = 0
					anims.bombs:Play()

					anims.bombs:GetMarkerReachedSignal("shoot"):Connect(function()
						for _, plr in pairs(game.Players:GetPlayers()) do
							for i = 1, 3 do
								task.spawn(function()

									local part = Instance.new("Part")
									table.insert(bombs, part)
									part.CanCollide = false
									part.Anchored = true
									part.CanQuery = false
									part.CastShadow = false
									part.Position = boss["Left Arm"].LeftGripAttachment.WorldPosition
									part.Size = Vector3.new(2, 2, 2)
									part.Shape = "Ball"
									part.Color = Color3.new(0.537255, 0.129412, 0.792157)
									part.Material = "Neon"

									for _, v in pairs(script.bombs:GetChildren()) do

										local c = v:Clone()
										c.Parent = part
										c.Enabled = true

									end

									local info = TweenInfo.new(.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
									local props = {Position = Vector3.new(plr.Character.HumanoidRootPart.Position.X + math.random(-100, 100), part.Position.Y, plr.Character.HumanoidRootPart.Position.Z + math.random(-100, 100))}
									local tween = ts:Create(part, info, props)
									part.Parent = workspace
									debris:AddItem(part, 5)
									tween:Play()
								end)
							end
						end
					end)
					
					anims.bombs:GetMarkerReachedSignal("explode"):Connect(function()
						for _, v:Part in pairs(bombs) do
							task.spawn(function()
								local exp = script.bombsExp.explosion:Clone()
								local slashes = script.bombsExp.slashes:Clone()
								exp.Parent = v
								slashes.Parent = v
								v.Transparency = 1
								exp:Emit(1)
								slashes:Emit(2)

								local hitbox = hitboxes.CreateHitbox()
								hitbox.Shape = Enum.PartType.Ball
								hitbox.CFrame = v.CFrame
								hitbox.Size = 30
								local params = OverlapParams.new()
								params.FilterType = Enum.RaycastFilterType.Exclude
								params.FilterDescendantsInstances = {boss}
								hitbox.OverlapParams = params
								hitbox.Visualizer = true
								hitbox.Touched:Connect(function(hit, hum)
									if not hit.Parent:IsA("Tool") and hum then
										hum:TakeDamage(20)
									end
								end)
								hitbox:Start()
								task.wait(1)
								hitbox:Stop()
							end)
						end
					end)
				end)
			end
			task.spawn(function()
				bombThrow()
			end)
			return
		end,
	},
}
		
return module

I will change a lot of how this is set up, due to how messy it is, but it just keeps multiplying the bomb function whenever its ran.

I would imagine it’s because you connect a new anims.bombs:GetMarkerReachedSignal("explode") event every time you call the bombs() function. Since you never actually disconnect your old events every call will run the connected code one additional time when the events fire.

I’ll try to fix that now, I never used GetMarkerReachedSignal(), thanks!

Thanks, I moved both the signals to be outside of the function, and I cleared the table each time it runs, now it works. Thanks again!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.