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.