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

How could i remove a player from a Table when he died or disconnected?

So this is kinda complicated to explain but im just gonna give you my whole Script so you might be able to understand what i did here. So i got a District System going like the Hunger games and i know how to check, how many Players are alive. But my major problem is to make a "Death/Leave" Script so it updates the Table when a player dies or disconnects. The Problem here is that If i want to check how many Players are alive i use

if #Players == 0 then
			print("Everybody died")
			break
		end

which is the only way i believe in this code. If i want to use _G.Districts it wont work. #Players gives me an Number of how many are in the table i believe.

So Is there a better way to write this script? Is there even a way to get my Death/Leave script working? Im so confused by now and my head hurts.

Here is my Whole Script + my attempt to write a Death and Leave Script. Basicly what i wanna know is how to make a death and leave script and make it comportable with mine. Thanks alot if you're still reading <3

DEATH AND LEAVE SCRIPT

game:GetService("Players").PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		character:WaitForChild("Humanoid").Died:Connect(function()
		local Update = {}
		for i, v in pairs(_G.Districts) do
		    if v ~= player.Name then
			   table.insert(Update,1,v)
		    end
		end
	_G.Districts = Update
		end)
	end)
end)

game:GetService("Players").PlayerRemoving:Connect(function(player)

	local Update = {}
	for i, v in pairs(_G.Districts) do
		if v ~= player.Name then
			table.insert(Update,1,v)
		end
		
	end
	_G.Districts = Update
end)

MAIN SCRIPT

--//Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

--//Remotes
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
	local Names = Remotes:WaitForChild("Names")
	local Round = Remotes:WaitForChild("Round")
	
--//Variables 
local Tributspawn = workspace:WaitForChild("Tribut")

--//Functions
	function Shuffle(Table)
    local Size = (#Table)
    for i = Size, 1, -1 do
        local RandomObject = Random.new():NextInteger(1, Size)
        Table[i], Table[RandomObject] = Table[RandomObject], Table[i]
   		end
    return Table
end	
	
--//Main
while true do
	wait(3)
	_G.Districts = {}
local Players = (Shuffle(game:GetService("Players"):GetPlayers()))
 
for i = (1),(math.ceil(#Players/2)) do
    _G.Districts[#_G.Districts + 1] = {}
end

for Player = (1),(#Players) do
    local DesiredDistrict = (math.ceil(Player/2))
    table.insert(_G.Districts[DesiredDistrict], Players[Player])
Names:FireAllClients(DesiredDistrict,Players[Player])
wait(2)
end
	print("Round starts")
		for t = 10,0,-1 do
		wait(1)
			print(t)
			if #Players == 0 then
			print("Everybody died")
			break
		end
	end
end

1 answer

✓ Accepted answer

You should avoid using _G as any scripts are able to read / make changes to this. Instead I would use a module script to manage this task.

There are a lot of ways this can be done but for this example I will show a self contained process which will return a round object. The idea behind this is so you would then be able to expand the functionality of what a round is.

-- module script code
local f = {}
local plrServ = game:GetService("Players")

-- vars
local curRound = nil

-- returns the cur round object or nil
function f:GetCurRound()
	return curRound
end

-- roundTime, the time for this round
function f:NewRound(roundTime)
	-- example validation for rounds
	if curRound then error("round is active cannot make a new round") end

	local round = {} -- our new round object
	local conObj = {} -- active event connections
	local endTime = tick() + roundTime -- cal total time of round
	local totalPlayers = 0 -- player count for round
	local plrList = {}
	
	-- to avoid duplication of code
	local function rmPlayerFromList(plr)
		if plrList[plr] then -- if plauer is in the list
			plrList[plr] = nil -- remove player
			totalPlayers = totalPlayers - 1 -- dec player count
		end
	end
	
	for _, plr in pairs(plrServ:GetPlayers()) do
		if plr.Character then -- check for a players model ?
			local hum = plr.Character:FindFirstChild("Humanoid")

			-- check humanoid is not dead
			if hum and hum:GetState() ~= Enum.HumanoidStateType.Dead then

				-- add this valid player to the list
				conObj[#conObj+1] = hum.Died:Connect(function()
					rmPlayerFromList(plr)
					print(plr.Name, " died")
				end)
				
				totalPlayers = totalPlayers + 1 -- inc player count
				plrList[plr] = true -- the value is just a place holdder
			end
		end
	end

	-- add the player removing 
	conObj[#conObj+1] = plrServ.PlayerRemoving:Connect(function(plr)
		rmPlayerFromList(plr)
		print(plr.Name, " left")
	end)

	-- returns the player count for the round
	function round:GetPlayerCount()
		return totalPlayers 
	end

	-- returns true if the round is still active
	function round:IsActive()
		return tick() < endTime 
	end

	-- ends the round and curRound variable
	function round:End()
		for _, con in pairs(conObj) do
			con:Disconnect()
		end
		
		-- cleanup
		conObj = nil
		totalPlayers = 0
		plrList = nil
		curRound = nil
	end
	
	-- returns an array of players in theround
	function round:GetPlayers()
		local lst = {}
		for _, plr in pairs(plrList) do
			lst[#lst+1] = plr
		end
		return
	end
	
	-- set this as the active round
	curRound = round
	return round -- return round object
end

return f -- return our table of functions 

Example script

local round = require(script.Parent.ModuleScript)

while true do
	local newRound = round:NewRound(10)

	while newRound:IsActive() do
		print(newRound:GetPlayerCount(), "Players in round")
		wait(1)
	end

	print("round end")
	newRound:End()
end

I know this is a lot to work with at first but the round object returned is safe to use in other scripts. Please comment if there are parts of this code you do not understand and I will add additional info below.

Usefull links

OOP in Lua

OOP in Lua dev forum

RBXScriptConnection

Hope this helps.

2 comments

0

I see you did a lot of work there, sadly my knowledge is not good enough for this kind of code. I never invented time into ModuleScripts etc also sadly i dont know how to make it comportable with mine. Still you did a great job, i tested it in a new game and it works well :)

0

You can do a lot of things with modules. A module script will only run once upon using the function require. It helps lead to better code design by reusing code and making for better code strucures ie one thing does one task.

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