Does setting a value nil, in a table, do anything?

Hi, I have been trying to make round based game, where players get swords, which they can use to defend themselves. So I have been trying to make the script repeat wait() until there is only 1 player left but when there is 1 player left, it does nothing. I even tried printing how many players are still left and it says 2 when there is only 1.

At the start of every round I put all players into a table, I remove the player from the table when he/she dies like this:

alive[players[player].Name] = nil

I will only give out code if necessary.

Thanks.

If you iterate through a table with ipairs, it will stop when it finds the nil value.

Why don’t you use table.remove instead?
table.remove(table, index)

which one would be better to use to find player names, ipairs or i = 1, #table loop?

Since lua’s tables are a hybrid of hashtables and arrays, indexing a value or a key has O(1) complexity, you can simply do table[the player's name], without having to iterate through each key and find the one that has the player’s name. I hope I understood your question

you know when a player dies or leaves the game so you would use those events to check the alive table to see if its empty.

local function isEmpty(tbl)
      for _, _ in pairs(tbl) return false end
      return true
end
1 Like

Well, I prefer to do it like:

for _, player in ipairs(alive) do
	--// do nothing

	...
end

I’m not 100% sure if there’s a performance difference between them, but if there is, then it’s probably very minimal. Either would work, but ipairs will stop at a nil value, whereas the other for loop will iterate through the whole table like this:

table = {"player1", nil, "player2", "player3"}
for _, plr in ipairs(table) do
	print(plr)
end

Expected output: player1

table = {"player1", nil, "player2", "player3"}
for i = 1, #table do
	print(table[i])
end

Expected output: player1, nil, player2, player3

I got a problem, So now it detects the player’s death but it only removes the player who joined first’s name, which the player who joined last always wins regardless of who died.

Code:

local players = game:GetService("Players"):GetChildren()
	
		for i =  1, #players do
			
			if players[i].Character ~= nil then
				if players[i].Character.Humanoid ~= nil then
					
					local humanoid = players[i].Character.Humanoid
					local char = players[i].Character
					
					if humanoid.Health > 0 then
					
						table.insert(alive, players[i].Name)
						
						local weapon = SS["Weapons"]["Sword"]:Clone()
						weapon.Parent = players[i].Backpack
						
						char.HumanoidRootPart.CFrame = spawns[math.random(1, #spawns)].CFrame + Vector3.new(math.random(-5, 5), 3, math.random(-5, 5))
					
						DeathDuringRound = humanoid.Died:Connect(function()
							
							for v = 1, #alive do
								if alive[v] == players[i].Name then
									table.remove(alive, v)
								end
							end
							
							local tag = humanoid:FindFirstChild("creator")
								
							if tag ~= nil then
								if tag.Value ~= nil then
									datastore2("points", tag.Value):Increment(10)
								end
							end
						end)
					end	
				end
			end
		end

Just to get into good habits, use :GetPlayers() instead.
local players = game:GetService("Players"):GetPlayers()

You’re iterating through all the players and then looping through all the alive players.

Basically, imagine this.
Player1, Player2
looping through them would mean that Player1 has an index of 1 and Player2 has an index of 2.
Then, when you loop through them again, you’re checking if alive[i] == players[i].Name, etc. which would be just checking their index in the table against their position in the players table.

I’m fairly sure that’s what the program is doing, but correct me if I’m wrong. It would be better to do something similar to what @kingdom5 said, and then you could remove the player from the table and check if there’s only 1 player left.

I am pretty sure this is the cause of the issue but I can’t find exactly where the issue is located in the loop.

  					for v = 1, #alive do
  						print(alive[v])
  						if alive[v] == players[i].Name then
  							table.remove(alive, v)
  						end
  					end

How about something like this?

humanoid.Died:Connect(function()
	for i,v in pairs(alive) do
		if v == Players:GetPlayerFromCharacter(character).Name then
			table.remove(alive, i)
		end
	end
end)

Character wasn’t included in my code snippet, but it was in your original one.

I am still having the same issue. I don’t know why it still doesn’t work.