Text label duplicates twice

I made this example of the logic that I think you should go with. I’ll now send the place file so that you can look at it and extrapolate what I was trying to explain. You could’ve kept the For Loop and the fireall clients, it was just because you weren’t checking if the frame already existed or not.

Here’s the example place file using your for loop fireallclients method:
PlayerListExample.rbxl (62.9 KB)

PS: I suggest you try running a 3 player team test and make one person leave then check the other clients so you can see.

I made a 3 player team test and here is what I found with your file.

  • When one player leaves, two text labels get destroyed
  • When the second player leaves, no text labels get destroyed

Also in my game its not the player joining the game, its when the player joins a ui server that I made.
They can create a server

  • Then join the server with a ServerID (a 5 number randomized code)
  • Then it shows who’s in the server with the textlabels

Also for this line:

local function HandlePlayerJoin(playerName : string)

What does the colon do between playerName and string?

I understand the logic is differently and is held strictly through UI, but the concept should be the same. Let me show you what I would do instead. Sorry for the late responses I’m working on something

That’s for typechecking the inputted variable

It is fine, take your time!!!

This is the version I would do:
I would fire the updated list of players for all the people that just join / join in lately, and also fire the direct client update for the singular player

And only fire the singular player while updating the leaving.

place file:
PlayerListExampleMyWay.rbxl (63.0 KB)

1 Like

Make sure you didn’t left Player1 and/or Player2 TextLabels in the UI before cloning them to add new players.

So how would I do this to my 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)

@BamzOfficial

Are you here??
reply to my post above

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

-- UI and Debounce
local PlayerNameText = script.Parent.PlayerNameText
local debounce = false

-- Server Variables
local myServerName
local InServer = false
local playerTable = {}

-- Player Joining
local function HandlePlayerJoin(plrName)
    if not script.Parent:FindFirstChild(plrName) and not table.find(playerTable, plrName) then
        local playerTextClone = PlayerNameText:Clone()
        playerTextClone.Text = plrName
        playerTextClone.Name = plrName
        playerTextClone.Parent = script.Parent
        table.insert(playerTable, plrName)
    end
end

-- Player Leaving
local function HandlePlayerLeave(plrName)
    if script.Parent:FindFirstChild(plrName) and table.find(playerTable, plrName) then
        local playerTextClone = script.Parent:FindFirstChild(plrName)
        playerTextClone:Destroy()
        table.remove(playerTable, table.find(playerTable, plrName))
    end
end

-- Join Server Event
ReplicatedStorage.JoinServers.JoinServerPlayer.OnClientEvent:Connect(function(currentPlayers)
    if not debounce then
        debounce = true
        task.wait(1)
        debounce = false

        InServer = true

        for _, plrName in ipairs(currentPlayers) do
            HandlePlayerJoin(plrName)
        end
    end
end)

-- Server Name Update
ReplicatedStorage.ServerNames.OnClientEvent:Connect(function(_, serverName)
    print(serverName .. "PLAYERS SCRIPT")
    myServerName = serverName
end)

-- Create Server Player
ReplicatedStorage.CreateServers.CreateServerPlayer.OnClientEvent:Connect(function(plr)
    HandlePlayerJoin(plr.Name)
    InServer = true
end)

-- Handle Player Names
ReplicatedStorage.PLRNames.OnClientEvent:Connect(function(plrName)
    if InServer then
        task.wait(0.1)
        HandlePlayerJoin(plrName)
    else
        print("Player is not in server")
    end
end)

-- Leave Server Event
ReplicatedStorage.CloseFunction.LeaveServer.OnClientEvent:Connect(function(plrName)
    if Players.LocalPlayer.Name == myServerName then
        print("PlayerNameText is not getting destroyed because the player is the server creator")
    else
        HandlePlayerLeave(plrName)
        InServer = false
    end
end)

And then for the server side:

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"

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

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 = ServerNames
	
	for _, receivePlayer in ipairs(game.Players:GetPlayers()) do
		ReplicatedStorage.ServerNames:FireClient(receivePlayer, player.Name, ServerName.Value)
	end
	
	player.AncestryChanged:Connect(function()
		if not player.Parent then
			local playerServerID = ListOfIds:FindFirstChild(player.Name .. " 's Server")
			if playerServerID then
				playerServerID:Destroy()
			end
			
			local playerServerName = ServerNames:FindFirstChild(player.Name)
			if playerServerName then
				playerServerName:Destroy()
			end
			
			ReplicatedStorage.CloseFunction.LeaveServer:FireAllClients(player)
		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)
			
			for _, otherPlayer in ipairs(game.Players:GetPlayers()) do
				ReplicatedStorage.PLRNames:FireClient(otherPlayer, player.Name)
			end
			
			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)
1 Like

I’ve got this error on line 42
18:47:01.932 Players.Player1.PlayerGui.ServerGUI.Server.Players.PlayersScript:42: invalid argument #1 to ‘ipairs’ (table expected, got nil) - Client - PlayersScript:42
Line:

for _, plrName in ipairs(currentPlayers) do

Loop:

for _, plrName in ipairs(currentPlayers) do
			HandlePlayerJoin(plrName)
		end

So currentPlayers is nil

Because remember I mentioned how you needed to store the players that join the “Server” in that table. You would use table.insert(tableNameHere, playerName) You’ll also need to change the client code to handle a nil value. I have 0 idea how you’re testing any of this and code support isn’t as simple as copy pasting what I send, you’ll need to modify some of it to work with your current system, I was just giving you tips on how I would reformat the current handling of joining and leaving.

I made a table but still got that error.

Local script:

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

-- UI and Debounce
local PlayerNameText = script.Parent.PlayerNameText
local debounce = false

-- Server Variables
local myServerName
local InServer = false
local playerTable = {}

-- Player Joining
local function HandlePlayerJoin(plrName)
	if not script.Parent:FindFirstChild(plrName) and not table.find(playerTable, plrName) then
		local playerTextClone = PlayerNameText:Clone()
		table.insert(playerTable, tostring(plrName))
		playerTextClone.Text = tostring(plrName)
		playerTextClone.Name = tostring(plrName)
		playerTextClone.Parent = script.Parent
		
	end
end

-- Player Leaving
local function HandlePlayerLeave(plrName)
	if script.Parent:FindFirstChild(plrName) and table.find(playerTable, plrName) then
		local playerTextClone = script.Parent:FindFirstChild(plrName)
		playerTextClone:Destroy()
		table.remove(playerTable, table.find(playerTable, plrName))
		ReplicatedStorage.PlayerNamesFolder.PlayerNamesClient:FireServer(plrName)
	end
end

-- Join Server Event
ReplicatedStorage.JoinServers.JoinServerPlayer.OnClientEvent:Connect(function(currentPlayers)
	if not debounce then
		debounce = true
		task.wait(1)
		debounce = false

		InServer = true

		for _, plrName in ipairs(currentPlayers) do
			HandlePlayerJoin(plrName)
		end
	end
end)

-- Server Name Update
ReplicatedStorage.ServerNames.OnClientEvent:Connect(function(_, serverName)
	print(serverName .. "PLAYERS SCRIPT")
	myServerName = serverName
end)

-- Create Server Player
ReplicatedStorage.CreateServers.CreateServerPlayer.OnClientEvent:Connect(function(plr)
	HandlePlayerJoin(plr)
	InServer = true
	
	ReplicatedStorage.PlayerNamesFolder.PlayerNamesClient:FireServer(plr)
end)

-- Handle Player Names
ReplicatedStorage.PLRNames.OnClientEvent:Connect(function(plrName)
	if InServer then
		task.wait(0.1)
		HandlePlayerJoin(plrName)
	else
		print("Player is not in server")
	end
end)

-- Leave Server Event
ReplicatedStorage.CloseFunction.LeaveServer.OnClientEvent:Connect(function(plrName)
	if Players.LocalPlayer.Name == myServerName then
		print("PlayerNameText is not getting destroyed because the player is the server creator")
	else
		HandlePlayerLeave(plrName)
		InServer = false
		print(plrName)
	end
end)

Server Script

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"

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

local playerTable = {}

ReplicatedStorage.PlayerNamesFolder.PlayerNamesClient.OnServerEvent:Connect(function(player)
	table.insert(playerTable, #playerTable + 1, player)	
end)

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 = ServerNames

	for _, receivePlayer in ipairs(game.Players:GetPlayers()) do
		ReplicatedStorage.ServerNames:FireClient(receivePlayer, player.Name, ServerName.Value)
	end

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

			local playerServerName = ServerNames:FindFirstChild(player.Name)
			if playerServerName then
				playerServerName:Destroy()
			end

			local remote = ReplicatedStorage.CloseFunction.LeaveServer:FireAllClients(player.Name)
			if remote then
				for i = 1, #playerTable do
					if playerTable[i] == player.Name then
						print(playerTable[i])
						table.remove(playerTable, i)
						print(playerTable[i])
					end
				end
			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, table.find(playerTable, player.Name))

			for _, otherPlayer in ipairs(game.Players:GetPlayers()) do
				ReplicatedStorage.PLRNames:FireClient(otherPlayer, player.Name)
			end

			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)

Is the JoinServerPlayer remote event correct?

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, table.find(playerTable, player.Name))

			for _, otherPlayer in ipairs(game.Players:GetPlayers()) do
				ReplicatedStorage.PLRNames:FireClient(otherPlayer, player.Name)
			end

			return true
		end
	end
	warn(player.Name .. " failed to join server with ID:", ServerID)
	return false
end

@BamzOfficial
Reply to the reply above if you are here.

Well no, remember I said I’m not sure how you’re tracking your players in each “Virtual server” you will need to do a loop through the people in the server not the entire game. It’s currently using PlayerService:GetPlayers() but you’ll need to track your players per server per table.

Can you give me a code example of looping through the players in the server please? :blush::blush::blush::blush: