Removing a player from a table when they leave

I’m making a game that will require a table of all connected players to function. While I have the function for adding players to the table, removing them when they leave has proven to be much more difficult. In my current script (provided with post), I try to use table.remove, but this doesn’t work as I can’t find a string that no longer exists. Any help with this would be greatly appreciated.

local Player = game:GetService("Players")

local playersArray = game.ReplicatedStorage.PlayerArray
local getTable = game.ReplicatedStorage.ClientGetTable

local playertable = {}

game.Players.ChildAdded:Connect(function()
	print("Adding player to table.")
	game.Players:GetPlayers(Player)
	local playerName = Player.Name
	table.insert(playertable, playerName)
end)

game.Players.ChildRemoved:Connect(function()
	print("Removing player from table.")
	game.Players:GetPlayers(Player)
	local playerName = Player.Name
	table.remove(playertable, playerName)
end)

getTable.OnServerEvent:Connect(function()
	
	print("Sending current table to client.")
	
	getTable:FireClient(playertable)
end)

well um why would you need a table to store the players? I mean from what you are doing you add em to the table when they join the game, and remove them when they leave, its the same as just using players:GetPlayers().

The game involves a player sending a challenge to another after entering the name of the player to be challenged into a textbox. I need to search the table for the name entered into the the textbox in order to trigger the challenge-sent GUI on the screen of the player being challenged. I’m new to scripting and don’t really know any other way of going about this, so it’s what I’ve been ripping my hair out over for a while now lol.

ok well you can just do players:FindFirstChild(“PLRNAMEHERE”) and then your problem would be solved for getting an single player, where you send the list of players just do:

getTable.OnServerEvent:Connect(function()
	
	print("Sending current table to client.")
	
	getTable:FireClient(players:GetPlayers())
end)

again cause of what you are doing should yield the same results

1 Like

This is honestly much better & easier, thank you. However I did come across another problem where this script will never find the player name despite it being typed into the text box.

fightButton.MouseButton1Down:Connect(function()
	local name = nameTextBox.Text
	local reason = reasonTextBox.Text
	
	if name == Players:FindFirstChild(name) then
		print("Player found.")
	else
		print("Player not found")
	end
	
end)

Script always outputs the else statement, no clue why it can’t find the player name entered into the box.

:FindFirstChild() returns an instance

the name is a string

if Players:FindFirstChild(name) then --counts as true if the player exists, counts as false if they don't and it returns nil

end

you can make it more advanced by checking without caps sensitivity, allowing truncated names, and checking display names

name = string.lower(name)

local foundPlayer

for i = #name, 1, -1 do
  local truncatedName = name:sub(1, i)
  for _, plr in ipairs(game.Players:GetPlayers()) do

    local playerName = string.lower(plr.Name):sub(1, i)
    local displayName = string.lower(plr.DisplayName):sub(1, i)

    if playerName == truncatedName or displayName == truncatedName then
      foundPlayer = plr
      break
    end

  end
end

You’re trying to compare if name (string) is equal to a player. This will always return false, same thing would happen if you’d try to check if “Hello World” is equal to 10.

Didn’t realize that. I’ve redone the function using Players.name instead of FindFirstChild. Despite both name and Players.name being strings, it still yields the same result of no player bring found. When using GetService(“Players”), this is finding all children of game.Players right?

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer

local fightButton = LocalPlayer.PlayerGui.ScreenGui.ChallengeUI.FightButton
local nameTextBox = LocalPlayer.PlayerGui.ScreenGui.ChallengeUI.NameBox
local reasonTextBox = LocalPlayer.PlayerGui.ScreenGui.ChallengeUI.ReasonBox

fightButton.MouseButton1Down:Connect(function()
	local name = nameTextBox.Text
	local reason = reasonTextBox.Text
	
	if name == Players.Name then
		print("Player found")
	else
		print("Player not found")
	end
end)

No, Players.Name is getting the name of the Players service that you see in the Explorer just like Workspace. So Players.Name is equal to Players, the way workspace.Name would be Workspace.

Do this to check if the Player is in the game or not:

if Players:FindFirstChild(name) then
    print("Player found")
else
    print("Player not found")
end

Instance:FindFirstChild() finds the first child of the Instance with the name inside (). In this if statement we check if a Player with the name has been found in the game and print("Player found"), else print("Player not found")

You can check the Official Roblox documentation on :FindFirstChild() here.

2 Likes

This was very well explained and worked, thank you so much!

Didn’t realize this would have functioned the way I wanted it to if I weren’t trying to compare the two, but I’ll get the hang of it eventually. Thank you.

1 Like

You’re welcome! Is your original problem solved tho or do you still need help?

I noticed you’re using Players.ChildRemoved and Players.ChildAdded. While this is good for other services like the Workspace or Replicatedstorage, the Players service has custom events that fire when a Player joins/leaves. These are Players.PlayerAdded and Players.PlayerRemoving. You should be using these instead and you’ll notice that the PlayerRemoving event gives you some extra time before the Player is fully removed from the game.

I’m unsure if I still require tables to get what I need done now that i’ve found this out. Once a player has been challenged by another, an Accept / Deny challenge GUI should appear on their screen. My original plan was to have a table with all the names of the currently connected players within it that would be searched to find if the player challenged existed, and to, from there, show them the Accept / Deny GUI. There is a chance I may still need the table however as the script we’ve been talking about here is a LocalScript within the Challenge button. However, I’m thinking I could use RemoteFunctions to send the server the name of the player to be challenged, and then another remotefunction for the server to send the GUI pop-up to the client.

The only problem with this is that despite passing on a variable to the OnServerEvent statement, I can’t seem to use that variable in the function.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.