Text label duplicates twice

Hello!

In my local script it duplicates a text label twice on a specific screen. While on any other screen it is normal.
Specific screen:
Screenshot 2025-01-06 095912
Other screen:

Local script:

local Players = game:GetService("Players")
local PlayerNameText = script.Parent.PlayerNameText

local myServerName
local InServer = false
local PlayerName = ""

game:GetService("ReplicatedStorage").JoinServers.JoinServerPlayer.OnClientEvent:Connect(function()

	InServer = true

	for i, player in pairs(game.Players:GetPlayers()) do

		if not script.Parent:FindFirstChild(player.Name) then

			local playerTextClone = PlayerNameText:Clone()
			playerTextClone.Text = player.Name
			playerTextClone.Parent = script.Parent
			playerTextClone.Name = player.Name
			-- PlayerName = plrname -- Don't understands what is this for
			-- InServer = false

		end
	end

	print(InServer)
end)

game:GetService("ReplicatedStorage").ServerNames.OnClientEvent:Connect(function(player, ServerName)
	-- Invokes in ServerIDHandler
	print(ServerName .. "PLAYERS SCRIPT")

	myServerName = ServerName


end)

game.ReplicatedStorage.CreateServers.CreateServerPlayer.OnClientEvent:Connect(function(plr)

	local label = PlayerNameText
	label.Text = plr.Name
	label.Parent = script.Parent
	InServer = true
end)

game.ReplicatedStorage.PLRNames.OnClientEvent:Connect(function(plrname) 
	task.wait(0.1)
	if InServer == true then
		print(tostring(plrname)) 
		local playerTextClone = PlayerNameText:Clone()
		playerTextClone.Text = tostring(plrname)
		playerTextClone.Parent = script.Parent
		playerTextClone.Name = plrname
		PlayerName = plrname
	
		-- InServer = false
	else
		print("Player is not in server")
	end


end)

game.ReplicatedStorage.CloseFunction.LeaveServer.OnClientEvent:Connect(function(player)

	if Players.LocalPlayer.Name == myServerName then
		print("PlayerNameText is not getting destroyed because the player is the server creator")
	else
		local PlayerTextClone = script.Parent:FindFirstChild(Players.LocalPlayer.Name)
		InServer = false
		PlayerTextClone:Destroy()
	end


end)
2 Likes

Sorry for bump up, but I haven’t got a reply in almost 30 minutes

1 Like

I couldn’t really understand your code, but have you tried disconnecting your event or adding a debounce so it doesn’t clone twice?

1 Like

How would I add a debounce, and what part of the script?

1 Like

Well I see you have two events connected to a function that clone UI objects. You’re also doing it inside a for loop, which the for loop will activate once for the client that was already in the game with the newly gained 2 player server, aka firing twice. Let me see the server script where you fire these events to the client.

Personally I would take the cloning outside of a for loop and just fire an event for each time someone joins and leaves so I know which person to add or delete instead of complicating it with every player.

1 Like

Note that in these server scrips some sections are for different remotes
MaxPlayers:

local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local MaxPlayersFolder = ServerScriptService.MaxPlayers.MaxPlayersFolder

ReplicatedStorage.MaxPlayers.OnServerInvoke = function(player)
	
	local MaxPlayersValue = Instance.new("NumberValue")
	MaxPlayersValue.Parent = MaxPlayersFolder
	MaxPlayersValue.Value = 1
	MaxPlayersValue.Name = player.Name .. " 's Server"
	
	print(player)


	
	if MaxPlayersValue then
		return true
	else
		return false
	end


end 

ReplicatedStorage.JoinServers.JoinServerServer.OnServerEvent:Connect(function(player)
	ReplicatedStorage.PLRNames:FireAllClients(player.Name)
	local MaxPlayerValue = MaxPlayersFolder:FindFirstChild(player.Name .. " 's Server")
	if MaxPlayerValue then
		MaxPlayerValue.Value = MaxPlayerValue.Value + 1
		
		if MaxPlayerValue.Value >5 then
			print("more than five players")
		end
	end
end)

ReplicatedStorage.CloseFunction.CloseServerUI.OnServerEvent:Connect(function(player)
	local MaxPlayerValue = MaxPlayersFolder:FindFirstChild(player.Name .. " 's Server")
	if MaxPlayerValue then
		MaxPlayerValue.Value = MaxPlayerValue.Value - 1
	end
end)local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local MaxPlayersFolder = ServerScriptService.MaxPlayers.MaxPlayersFolder

ServerIDHandler

local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local ServerIDHandler = ServerScriptService:FindFirstChild("ServerIDHandler") or Instance.new("Folder", ServerScriptService)
ServerIDHandler.Name = "ServerIDHandler"

local ListofIds = ServerIDHandler:FindFirstChild("ListofIds") or Instance.new("Folder", ServerIDHandler)
ListofIds.Name = "ListofIds"

ReplicatedStorage.CreateServers.CreateServer.OnServerInvoke = function(player)
	 
	print("CreateServer")
	
	local ServerID = tostring(math.random(10000, 99999))
	local ServerEntry = Instance.new("StringValue")
	ServerEntry.Value = ServerID
	ServerEntry.Name = player.Name .. " 's Server"
	ServerEntry.Parent = ListofIds
	

	local ServerName = Instance.new("StringValue")
	ServerName.Name = player.Name
	ServerName.Value = player.Name.. "'s SERVER"
	ServerName.Parent = ServerScriptService.ServerIDHandler.ServerNames
	-- set the parent as the last property because it's more optimized

	for _, ReceivePlayer in ipairs(game.Players:GetPlayers()) do
		game:GetService("ReplicatedStorage").ServerNames:FireAllClients(ReceivePlayer, player.Name, ServerName.Name)
		print("for loop")
	end
	
	


	player.AncestryChanged:Connect(function()
		if not player.Parent then
			local playerServerID = ListofIds:FindFirstChild(player.Name .. " 's Server")
			if playerServerID then
				playerServerID:Destroy()
			end
		end
	end)

	return ServerID
end

ReplicatedStorage.JoinServers.JoinServer.OnServerInvoke = function(player, ServerID)
	
	for _, server in ipairs(ListofIds:GetChildren()) do
		if server.Value == ServerID then
			print(player.Name .. " successfully joined server with ID:", ServerID)
			
			ReplicatedStorage.JoinServers.JoinServerPlayer:FireClient(player)
			
			return true
		end
	end
	warn(player.Name .. " failed to join server with ID:", ServerID)
	return false
end



ReplicatedStorage.CreateServers.CreateServerServer.OnServerEvent:Connect(function(player)
	ReplicatedStorage.CreateServers.CreateServerPlayer:FireAllClients(player)
end)

ReplicatedStorage.CloseFunction.CloseServerUI.OnServerEvent:Connect(function(player)
	ReplicatedStorage.CloseFunction.LeaveServer:FireAllClients(player)
end)

I have updated the script so it debounces, but it still duplicates the player who joined the server’s text label

Local script:

-- Create a wait variable to debounce the cloning of the text label
local debounce = false

local Players = game:GetService("Players")
local PlayerNameText = script.Parent.PlayerNameText

local myServerName
local InServer = false
local PlayerName = ""

game:GetService("ReplicatedStorage").JoinServers.JoinServerPlayer.OnClientEvent:Connect(function()

	if not debounce then
		debounce = true
		wait(1)
		debounce = false

		InServer = true

		for i, player in pairs(game.Players:GetPlayers()) do

			if not script.Parent:FindFirstChild(player.Name) then

				local playerTextClone = PlayerNameText:Clone()
				playerTextClone.Text = player.Name
				playerTextClone.Parent = script.Parent
				playerTextClone.Name = player.Name
			end
		end
	end
end)

-- 

game:GetService("ReplicatedStorage").ServerNames.OnClientEvent:Connect(function(player, ServerName)
	-- Invokes in ServerIDHandler
	print(ServerName .. "PLAYERS SCRIPT")

	myServerName = ServerName


end)

game.ReplicatedStorage.CreateServers.CreateServerPlayer.OnClientEvent:Connect(function(plr)

	local label = PlayerNameText
	label.Text = plr.Name
	label.Parent = script.Parent
	InServer = true
end)

game.ReplicatedStorage.PLRNames.OnClientEvent:Connect(function(plrname) 
	task.wait(0.1)
	if InServer == true then
		print(tostring(plrname)) 
		local playerTextClone = PlayerNameText:Clone()
		playerTextClone.Text = tostring(plrname)
		playerTextClone.Parent = script.Parent
		playerTextClone.Name = plrname
		PlayerName = plrname
	
		-- InServer = false
	else
		print("Player is not in server")
	end


end)

game.ReplicatedStorage.CloseFunction.LeaveServer.OnClientEvent:Connect(function(player)

	if Players.LocalPlayer.Name == myServerName then
		print("PlayerNameText is not getting destroyed because the player is the server creator")
	else
		local PlayerTextClone = script.Parent:FindFirstChild(Players.LocalPlayer.Name)
		InServer = false
		PlayerTextClone:Destroy()
	end


end)

You’re using :FireAllClients inside a for loop, FireAllClients already fires to everyone’s client take this out and try again

Do I take the loop out and replace it with?

game:GetService("ReplicatedStorage").ServerNames:FireAllClients(ReceivePlayer, player.Name, ServerName.Name)

This will mean you’ll have to store the names another way, or use the method I suggested and only fire once per player joining and once per player leaving and just FireAllClients with the person’s name as the index, so the clients know which person to add or destroy from the UI.

But would it removing the loop fix it, or would it be unnecessary?

I believe it would fix your issue.
For example if you were to put a fireallclient inside a for loop getting the table of players, its going to FireAllClients to every single client for the amount of players in the game as the count of Event fires.

Would I need to replace :FireAllClients to :FireClient?
Like this:

for _, ReceivePlayer in ipairs(game.Players:GetPlayers()) do
		game:GetService("ReplicatedStorage").ServerNames:FireClient(ReceivePlayer, player.Name, ServerName.Name)
		print("for loop")
	end

Just replace it with

 game:GetService("ReplicatedStorage").ServerNames:FireAllClients(player.Name, ServerName.Name) 

AKA taking it out of the loop

Let me know if this works for you at all

1 Like

Nope it still did the same thing:
Server Creator: (player 2)

Person who joined the server: (player 1)
Screenshot 2025-01-06 130920

Is it because of the debounce in the local script?

-- Create a wait variable to debounce the cloning of the text label
local debounce = false

local Players = game:GetService("Players")
local PlayerNameText = script.Parent.PlayerNameText

local myServerName
local InServer = false
local PlayerName = ""

game:GetService("ReplicatedStorage").JoinServers.JoinServerPlayer.OnClientEvent:Connect(function()

	if not debounce then
		debounce = true
		wait(1)
		debounce = false

		InServer = true

		for i, player in pairs(game.Players:GetPlayers()) do

			if not script.Parent:FindFirstChild(player.Name) then

				local playerTextClone = PlayerNameText:Clone()
				playerTextClone.Text = player.Name
				playerTextClone.Parent = script.Parent
				playerTextClone.Name = player.Name
			end
		end
	end
end)

-- 

game:GetService("ReplicatedStorage").ServerNames.OnClientEvent:Connect(function(player, ServerName)
	-- Invokes in ServerIDHandler
	print(ServerName .. "PLAYERS SCRIPT")

	myServerName = ServerName


end)

game.ReplicatedStorage.CreateServers.CreateServerPlayer.OnClientEvent:Connect(function(plr)

	local label = PlayerNameText
	label.Text = plr.Name
	label.Parent = script.Parent
	InServer = true
end)

game.ReplicatedStorage.PLRNames.OnClientEvent:Connect(function(plrname) 
	task.wait(0.1)
	if InServer == true then
		print(tostring(plrname)) 
		local playerTextClone = PlayerNameText:Clone()
		playerTextClone.Text = tostring(plrname)
		playerTextClone.Parent = script.Parent
		playerTextClone.Name = plrname
		PlayerName = plrname
	
		-- InServer = false
	else
		print("Player is not in server")
	end


end)

game.ReplicatedStorage.CloseFunction.LeaveServer.OnClientEvent:Connect(function(player)

	if Players.LocalPlayer.Name == myServerName then
		print("PlayerNameText is not getting destroyed because the player is the server creator")
	else
		local PlayerTextClone = script.Parent:FindFirstChild(Players.LocalPlayer.Name)
		InServer = false
		PlayerTextClone:Destroy()
	end


end)

I think it’s because of the amount of redundant For Loops you have

Which ones do i need to remove?

You also have some UI Cloning that doesn’t even check if they exist or not. In your JoinServerPlayer and PLRNames connections, the script clones and creates a new text element for each player without validating whether it already exists. You’re using a boolean which doesn’t get updated yet.
Example being PLRNames:

local playerTextClone = PlayerNameText:Clone()
playerTextClone.Text = tostring(plrname)
playerTextClone.Parent = script.Parent
playerTextClone.Name = plrname

Here’s the logic I think you should have:
Player Joins Server (Using PlayerAdded signal we can connect it on the server to fire the player’s name to everyone’s client) → Our Clients receive this Event and only fire a function once per player join → if the player leaves fire another FireAllClients event telling everyone that this person left the server and destory their name if needed on the UI elements.

is the logic for this local script only? Or is it for the other server scripts too?

Also InServer is a boolean that is true when the player is in the server.