In a bit of a dilemma with a round system script I made

Right, so the code I am about the present below, works perfectly fine I know it’s not the most efficient because I’m just starting off but, it works ok. Anyways, I made my script so at the start of each round, all the players that died and got removed from the table last round, got put back into the table the next time the round starts. However, this is where I run into my problem. If a person decides to kill them selves, just before the round starts, the player will still be counted into the Players alive table when the round officially starts, and they will get the coins for the round despite not even being in the round to complete it. I hope this makes sense. Here is my code:

local Players = game:GetService("Players")
local maps = game.ReplicatedStorage.Games:GetChildren()
local LobbySpawns = game.Workspace.LobbySpawn:GetChildren()
local PlayersAlive = {}
-- My Local Variables -- 

game.Players.PlayerAdded:Connect(function(player)-- This will fire when the player first joins the game. 
	local Char = player.Character or player.CharacterAdded:Wait()
	local hum = Char:WaitForChild("Humanoid")
	
	hum.Died:Connect(function()  -- If the player dies, they will be removed from the alive table.
		PlayersAlive[player.Name] = nil
		print(player.Name, "has died!")
		print(PlayersAlive)
	end)
end)

game.Players.PlayerRemoving:Connect(function(player) -- if the player leaves, we want to get rid of their name in the players alive. 
	PlayersAlive[player.Name] = nil
	print(player.Name, "has left the game. We've removed them from alive players table.")
end)



local function RoundInProgress() -- Round in progress function. Handles alive players, 
	for i, player in pairs(game.Players:GetChildren()) do -- Here we will loop through the players in the game and add them to the players alive table.
		PlayersAlive[player.Name] = player
		print(PlayersAlive)
	end
	
	for i = 10, 1, -1 do -- Starting the Round timer.
		wait(1)
		Message.Value = ("Round will end in: " .. i)
		
		if i == 1 then -- When the round is over, we will reward all the players in the playersalive table (Not finished)
			Message.Value = ("Round has ended!")
			for i, PlayerAlive in pairs(PlayersAlive) do
				local HRP = PlayerAlive.Character:FindFirstChild("HumanoidRootPart")
				local RandomLobbySpawn = LobbySpawns[math.random(1, #LobbySpawns)]
				
				PlayerAlive:FindFirstChild("leaderstats").Coins.Value += 1 -- Giving the alive player 1 more coin to their leaderstats.
				HRP.CFrame = CFrame.new(RandomLobbySpawn.Position) -- Teleporting the alive player back to a random spawn in the lobby.
				PlayersAlive[PlayerAlive.Name] = nil -- remove the players from the alive table. The round has finished.
				print(PlayersAlive)
			end 
			game.Workspace.CurrentGame:ClearAllChildren()
		end
	end
end

local function SpawnPlayers() -- Spawns the players to a random spawn on the map.
	for _, SpawnPartModel in pairs(game.Workspace.CurrentGame:GetDescendants()) do
		if SpawnPartModel.Name == "SpawnParts" then
			local SpawnParts = SpawnPartModel:GetChildren()
			
			for _, player in pairs(game.Players:GetChildren()) do
				local Char = player.Character
				local HumRootPrt = Char:FindFirstChild("HumanoidRootPart")
				local randomspawn = SpawnParts[math.random(1, #SpawnParts)]
				
				HumRootPrt.CFrame = CFrame.new(randomspawn.Position)
			end
		end
	end
	Message.Value = "Spawning Players!"
end

local function Loadmap() -- We will randomly select a map from the given location and load it into the given workspace location that we provided. "CurrentGame"
	local chosenmap = maps[math.random(1, #maps)]
	local CurrentMap = chosenmap:Clone()
	
	Message.Value = ("Map Selected: " .. CurrentMap.Name)
	CurrentMap.Parent = game.Workspace.CurrentGame
end

local function Intermission() -- This is just the intermission, it allows players to have a few seconds to use their coins and just chill before the next round.
	for i = 6,1,-1 do
		wait(1)
		Message.Value = ("Intermission: " .. i)
		if i == 1 then
			Message.Value = ("Selecting a random map!")
		end
	end
end

while true do -- This will loop constantly through all of the functions that we've put into it. This will allow everything to run smoothly.
	Intermission()
	wait(1)
	Loadmap()
	wait(1)
	SpawnPlayers()
	wait(1)
	RoundInProgress()
	wait(1)
end ```

The problem lies, not behind my code but, behind my logic. I didn’t think about this current situation. What I was thinking was to allow players to instantly respawn instead of waiting. Because the problem is when a player dies, their character takes a while to respawn. And although the player has still been added to the table of alive players when the round starts their character has not been added to the round because it can not be teleported when they’re dead. But, if they respawned instantly, if they died before the round they’d still be able to participate in it.

However, I have one more minor problem. If the player gets teleported into the round and they’re added to the table. I have a wait(1) period between the player spawning and the round starting… so… if they get teleported into the round, but then die in that 1 second period between both functions they will be respawned out of the round which is what i want, but they will still be added to it.

I mean I could just get rid of the wait(1) but, I wasn’t really sure if i even needed it.

local Players = game:GetService("Players")
local maps = game.ReplicatedStorage.Games:GetChildren()
local LobbySpawns = game.Workspace.LobbySpawn:GetChildren()
local PlayersAlive = {}
-- My Local Variables -- 

game.Players.PlayerAdded:Connect(function(player)-- This will fire when the player first joins the game. 
	local Char = player.Character or player.CharacterAdded:Wait()
	local hum = Char:WaitForChild("Humanoid")
	
    player.CharacterAdded:Connect(function()
          table.insert(PlayersAlive, player.Name)
    end)

	hum.Died:Connect(function()  -- If the player dies, they will be removed from the alive table.
		table.remove(PlayersAlive, player.Name)
		print(player.Name, "has died!")
		print(PlayersAlive)
	end)
end)

game.Players.PlayerRemoving:Connect(function(player) -- if the player leaves, we want to get rid of their name in the players alive. 
	table.remove(PlayersAlive, player.Name)
	print(player.Name, "has left the game. We've removed them from alive players table.")
end)


Why have we changed table[] = something
to table.remove/table.insert ?

Pretty sure that’s an array not a dictionary.

probably my lack of understanding of tables. it was an attempt.

So basically the values in that table are indexed by numbers so you wouldn’t know which is which(Unless you know).

i’ve changed it all to table.insert and table.removed

but still wouldn’t i still have the problem… where players are still being added to it, even if they died before the round started?

Have you got a value that determines if a round is active? If so, add an if not Active then check before the table inserts!

poppy. Changing to table.insert and table.remove messes up my loops…

change it all back, I didn’t look at the whole script and didn’t realise it was meant to be a dictionary