Requiring a module numerous times with connections in it cause those conenctions to run multiple times as well

I basically have a module that I require everyime I create a new UI element for this thing.

return function()
    local Character = Player.Character or Player.CharacterAdded:Wait()
	local Humanoid = Character:WaitForChild('Humanoid')
	
	local Frame = script.Parent

    local Carry = script:WaitForChild('Carry')
	
	-- Load Carry animation
	local CarryAnimation = Humanoid:LoadAnimation(Carry)

    local function PlayerLeft(leftPlayer)
		print("Player left")
		-- Currently being carried, put them down							
		for _, v in pairs(Humanoid:GetPlayingAnimationTracks()) do
			v:Stop()
		end
	end

    -- Extra code down here (not relevant to the question)

    Players.PlayerRemoving:Connect(PlayerLeft)
end

So if I had this required 8 times, then when a player leaves I get ‘Player left’ printed 8 times. How can I prevent this from happening?

The point of this is to stop an animation that gets played further down in the script.

Have a connection variable that will be used as an upvalue in the returned function.

local connection

return function()
    if connection then
        connection:Disconnect()
        connection = nil
    end
    -- stuff
    connection = Players.PlayerRemoving:Connect(PlayerLeft)
end

Although, not sure why you need an entire module when everything can just be in a server script or something. But, I am not going to assume how your project works so there is that.

1 Like

Either require it only once, or don’t return a function. Just return nil, or don’t call the function that gets returned.

I can’t just require it once tho, as I’m cloning a UI and copy and pasting it into the playergui, like so

-- Quick write as example
local UI = script:WaitForChild('UI')

local UIClone = UI:Clone()
require(UIClone.UIControl)()
UIClone.Parent = PlayerGui

And this UI gets destroyed/re-added to the player a mountain of times

The code that only needs to be run once should not be passed in a function to the script calling require.

I still get a ton of prints

local CurrentPlayerInteraction = nil

local function PlayerLeft(player)
	if player ~= CurrentPlayerInteraction then return end
	
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local Humanoid = Character:WaitForChild('Humanoid')
	
	print("Player left")
	for _, v in pairs(Humanoid:GetPlayingAnimationTracks()) do
		print(v.Animation.Name)
		if v.Animation.Name == 'Carry' then
			v:Stop()
		end
	end
end

Players.PlayerRemoving:Connect(PlayerLeft)

return function(player)
  CurrentPlayerInteraction = player
  -- Do ui code stuff
end

Output
Player left

Carry

Animation1

Player left

Carry

Animation1

Player left

Carry

Animation1

Player left

Carry

Animation1

Player left

Carry

Animation1