Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Making a round script, what is the best way to get the remaining players alive and ending the game?

I'm wondering the best way to check the amount of players remaining in a round. If I do:

hum.Died:connect(function()
	alive[player][1] = false
	checkAlive()
end)

then I'm scared the two players will tie and the game will end twice.. or is the best option to add a game ending debounce?? Here's my script so far:

--// Services
local ws = game:GetService("Workspace");
local pls = game:GetService("Players");
local repstr = game:GetService("ReplicatedStorage");
local ss = game:GetService("ServerStorage");

--// References
local gameFolder = Instance.new("Folder", ws)
gameFolder.Name = ".GameSettings" -- Has . in the beginning because hopefully the player GameSettings doesn't join lol

local alive = {} -- alive[player] = {PLAYING(TRUE/FALSE, KILLS/POINTS}
local playing = {} -- playing[player] = true/false

--// Variables
local vars = {"GameState", "Intermission"}
local varInfo = { -- Value type, default value
	["GameState"] = {"StringValue", ""};
	["Intermission"] = {"IntValue", 0}
};
	
for i = 1,#vars do
	local newValue = Instance.new(varInfo[vars[i]][1], gameFolder)
	newValue.Value = varInfo[vars[i]][2]
end

--// Game functions (intermission, begin, end, etc)

function checkAlive()
	a = 0
	for _,player in pairs(pls:GetPlayers()) do
		pcall(function() -- just incase the player isnt even in the dictionary
			if alive[player][1] == true then
			a = a+1
		end)
	end
	return a
end

function intermission(startTime, gameMode) -- ignore this im finishing this later on cuz ez
	local timerValue = gameFolder:WaitForChild("Intermission")
end

function beginGame(gameMode)
	for _,player in pairs(pls:GetPlayers()) do
		if playing[player] == true then -- if player is marked as playing, then let him join!!
			alive[player] = {true, 0}
			
			player:LoadCharacter()
			repeat wait() until player.Character
			local hum = player.Character:WaitForChild("Humanoid")
			hum.Died:connect(function()
				alive[player][1] = false 
				checkAlive() -- can do the ending after this blablabla
			end)
		end
	end
end

1 answer

Events will not run at the same time so the game will never end twice. But you need to consider that a player may leave the game resulting in the function checkAlive not running at all.

Using a table is a good way to keep track of who is ingame or not but I would remove the players when they die instead.

You also do not need to add a pcall into the checkAlive function as you should be checking if the player is not nil.

Example:-

-- services
local plrServ = game:GetService("Players");

-- vars
local alivePlayers = {}
local playingList = {}

local function checkAlive()
	local i = 0
	for _, _ in pairs(alivePlayers) do
		i = i + 1 -- inc player count
	end
	print('Players alive', i)
	return i
end

local function beginGame()
	
	alivePlayers = {} -- reset data each round to make surre it has no errors

	 for _,plr in pairs(plrServ:GetPlayers()) do
		if playingList[plr] then -- if plr is in the list ie not nil

			alivePlayers[plr] = {true, 0} -- not sure about the data
			plr:LoadCharacter() -- will cause the script to wait (yield)
			
			-- warning player could leave the game or reset befor the script connects
			-- the died event.
			if plr.Character then
				
				-- wait for 10 seconds player could also leave the game
				local hum = plr.Character:WaitForChild('Humanoid', 10) 
				if hum then
					hum.Died:connect(function()
						alivePlayers[plr] = nil -- clear plr from list
						checkAlive()
					end)
				else
					-- needs more checks
				end
			else
				-- no character needs more checks
			end
			
		end
	end
end

plrServ.PlayerRemoving:Connect(function(plr)
	alivePlayers[plr] = nil -- clear the player from the list even if they are not in the list
	playingList[plr] = nil
end)

The main issue is when the script pauses (yeilds, calls a wait function) as players could leave the game reset their character causing your game to go out of sync. I think it would be best to just move the players torso as this will not yield in any way. This means the player setup can be done without being interupted.

I hope this helps please comment if you have any more questions.

This discussion is preserved as it was. New answers, comments, and votes are closed.