How to prevent events from stacking?

I have multiple events in my scripts that kinda ‘stack’, meaning if I loop it and then play the event, multiple results appear. How can I ‘reset’ the event everytime so it only sends one result?

local function ChooseTarget() -- This function will be called multiple times.
	MaxActivationDistance(100) -- Ignore this. Nothing important.
	for i,v in pairs (Enemies) do
		v.Model.BattleInfo.Click.ClickDetector.MouseClick:Connect(function() -- This mouse event will stack, because of calling the function multiple times.
			print(1)
			WhichAttack.Attacker = Player.Character
			WhichAttack.Target = v
			game.ReplicatedStorage.BattleModules.BattleSystem.PlayerSendAttack:FireServer(WhichAttack) -- Eventually it will send multiple results than needed.
			MaxActivationDistance(0)
		end)
	end
end

Create references to the old events and then call a :Disconnect() function on the variable. For example:

local connection = game:GetService("RunService").RenderStepped:Connect(function() ... end)

connection:Disconnect();
2 Likes

Would a debounce help too? Or does that only lag my game more the more the event stacks?

No because the event is still called. My solution here would be creating a global table (outside of the loop’s scope) and then inserting each connection into that array. From there, just make sure to disconnect each array value before making a new connection.

Could you explain me how to make a global table/variable/function? It never works for me those things :confused:.

Sure thing. All you have to do is the following:

local globalVariable = {}; -- Variable outside the function's scope

local function ChooseTarget() -- This function will be called multiple times.
	MaxActivationDistance(100) -- Ignore this. Nothing important.
	for i,v in pairs (Enemies) do
		v.Model.BattleInfo.Click.ClickDetector.MouseClick:Connect(function() -- This mouse event will stack, because of calling the function multiple times.
			print(1)
			WhichAttack.Attacker = Player.Character
			WhichAttack.Target = v
			game.ReplicatedStorage.BattleModules.BattleSystem.PlayerSendAttack:FireServer(WhichAttack) -- Eventually it will send multiple results than needed.
			MaxActivationDistance(0)
		end)
	end
end

It took awhile to figure out this puzzle, but it works! No more stacking events.

I assume I shouldn’t use :Disconnect() on things like RemoteEvents?

It’s possible I’m wrong, but I would think you should still be able to. It wouldn’t make sense to not allow the use of Disconnect() there.

EDIT: Also, if you could go ahead and mark a solution above so others don’t see that this topic is ongoing, that’d be great. Thanks!

It kinda broke my whole script when I disconnected a OnServerEvent:Connect(). But I guess this one doesn’t loop in my script.

Sometimes things will take some code restructuring. Best advice I can give is to go back and make sure everything works with the new system.