How do i detect when a player dies or leaves the game in my round based game

hello all! I have this script that I’ve been working on for ages now, it seems very simple but I can’t figure it out. I believe I narrowed it down though to the portion when the player dies/leaves. characterremoving doesn’t seem to be firing when the player dies, which hence doesn’t allow the player count to go below the minimum threshhold which then keeps the game running forever and ever. How would I set it up so that whenever a player dies or leaves while they are in game their player gets removed from the table

local minPlayerCount = 2
local repStorage = game.ReplicatedStorage
local inGame = repStorage.inGame
local intermissionTime = 10
local intervalTime = 100
local spinner = game.Workspace.spinner
local Players = game:GetService("Players")

while true do
	wait(5)
	local currentPlayers = {}
	local multi = 1
	inGame.Value = true
	if #Players:GetChildren() >= minPlayerCount then
for i,v in pairs(Players:GetChildren()) do
			table.insert(currentPlayers,i,v)
			v.Character.HumanoidRootPart.CFrame = game.Workspace.startPos.CFrame
			v.CharacterRemoving:Connect(function(character)
				print( character.."died")
				if Players:GetPlayerFromCharacter(character) then

					table.remove(currentPlayers, table.find(currentPlayers, Players:GetPlayerFromCharacter(character)))
				if #currentPlayers:GetChildren() <= 1 then
					inGame.Value = false
					v.Character.HumanoidRootPart.CFrame = game.Workspace.SpawnLocation.CFrame + Vector3.new(0,5,0)
					end
				end
			end)
		end
		if inGame.Value == true then
			for i = intermissionTime, 1, -1 do
				repStorage.gameStatus.Value = "Time remaining in intermission: "..i
				wait(1)
			end
			while inGame.Value == true do
				for i = intervalTime, 1, -1 do
					spinner.CFrame = spinner.CFrame*CFrame.fromEulerAnglesXYZ(0,(0.1*multi),0)
					wait(.01)
				end
				local multi = multi*2
				end
		end
	end
end

player.Humanoid.Died:Connect(function()
-- player died
end)

i am sorry if its not correct because im new to devforum :slight_smile:

I’m pretty sure humanoid.died only fires when the humanoid dies, so if a player were to leave mid game it is very likely that the game would be stuck with only one person, or cause an error because #currentPlayers will return as nil

Loop through the table and remove and players that cant be found in the player list anymore is the best I can come up with

Check if they are in the round when they:

  1. Leave the game
  2. Die

Then you can remove them from the round table (if they are in it).
Hopefully you are keeping track on who’s in the current round (EDIT: Which you already did).

ie use playerremoving and humanoid.died seperately?

Yes. This would be the best way, because I’m pretty sure you have a PlayerRemoving event already, since you are probably saving data when they leave, etc.

awesome! I will set that up and give her a test right now

1 Like

forgive me for the stupid question but how would I put those functions in.
I tried putting the function in before the while loop and then calling the function in the loop when a play dies, but I feel like thats completely wrong. whats the best way for doing this?

To remove a player from the table, use:

table['remove'](ArrayOfPlayers, table['find'](ArrayOfPlayers, Player['Name']))

(Just an example).

More information for the events:
https://developer.roblox.com/en-us/api-reference/event/Humanoid/Died
https://developer.roblox.com/en-us/api-reference/event/Players/PlayerRemoving

yeah I have that down, But what I did was move that whole of removing players from the table and changing the ingame value to a function outside of the overarching while loop, and attempting to call it
by using

Players.PlayerRemoving:Connect(removeplayers())
v.Character.Humanoid.Died:Connect(removeplayers())

and then outside the while loop I have this

local removeplayers = function (player)
	if player.Character then
		print(player.Name.." died")
		table.remove(currentPlayers, table.find(currentPlayers, player))
	else
		table.remove(currentPlayers, table.find(currentPlayers, Players:GetPlayerFromCharacter(player)))
	end
		if #currentPlayers:GetChildren() <= 1 then
			inGame.Value = false
			player.Character.HumanoidRootPart.CFrame = game.Workspace.SpawnLocation.CFrame + Vector3.new(0,5,0)
		end
	
end

but it’s not really working the way I want it to

Just store their name, then remove them from the table with the name as well.
You don’t need to check if their character exists.

table['insert'](Array, PlayerName)
table['remove'](Array, table['find'](Array, PlayerName))

ok but my big problem is that because it’s outside the while loop, it isn’t returning the table to the rest of the code or there is some other big problem happening

Define the table outside, that way you can access it whenever you want, regardless.

Why are you using [] for table functions? Isn’t it way clearer to do.

table.insert(Array, name)
table.remove(Array, table.find(Array, name))
1 Like

Preference.
I wouldn’t mind what you do with your functions either.

this is what I currently have. when I run it in game it only teleports one person and then breaks

local minPlayerCount = 2
local repStorage = game.ReplicatedStorage
local inGame = repStorage.inGame
local intermissionTime = 10
local intervalTime = 100
local spinner = game.Workspace.spinner
local Players = game:GetService("Players")
local currentPlayers = {}





while true do
	wait(5)
	local currentPlayers = {}
	local multi = 1
	inGame.Value = true
		local removeplayers = function (player)
			if player.Character then
				print(player.Name.." died")
				table.remove(currentPlayers, table.find(currentPlayers, player))
				if #currentPlayers:GetChildren() <= 1 then
					inGame.Value = false
					player.Character.HumanoidRootPart.CFrame = game.Workspace.SpawnLocation.CFrame + Vector3.new(0,5,0)
				end
			end
		end
	if #Players:GetChildren() >= minPlayerCount then
for i,v in pairs(Players:GetChildren()) do
			table.insert(currentPlayers,i,v)
			v.Character.HumanoidRootPart.CFrame = game.Workspace.startPos.CFrame
			
			Players.PlayerRemoving:Connect(removeplayers())
			v.Character.Humanoid.Died:Connect(removeplayers())
			end
		if inGame.Value == true then
			for i = intermissionTime, 1, -1 do
				repStorage.gameStatus.Value = "Time remaining in intermission: "..i
				wait(1)
			end
			while inGame.Value == true do
				for i = intervalTime, 1, -1 do
					spinner.CFrame = spinner.CFrame*CFrame.fromEulerAnglesXYZ(0,(0.1*multi),0)
					wait(.01)
				end
				local multi = multi*2
				end
				end
		end
	end


Don’t put events inside of events, keep them outside.
The only thing you can keep (but outside of the loop) is the Humanoid['Died'] event.

when I change the values in a table from outside of the loop does it even change inside of it?

It doesn’t matter where you change it in the script, the changes will apply once you modify the table.
I just prefer to keep my variables outside of any scopes, so I can access them at all times (most of them, depends though).