Can I make this PVP Match Runner Script More Efficient?

So I have recreated my new PVP match runner script. The old one was constantly testing if 2 selected players were Dead or have left. I thought this may have been inefficient because if I wanted to have more than 2 players it would instantly become more confusing. So I thought to put all of the selected PVP players into a table, then I just set an rbx script event so that if they leave, or die they are removed from the table, so I would only have to do a repeat wait loop wait until the number of elements(in this case, players) was equal to 1 or less. I do feel like I can make this script better. But how? I also feel it might error if a player leaves or dies at the right time to glitch it. In the case of an event like this, I have it in a pcall function, and if it errors it puts everything back and resets everything. But I still want to make this script have the least amount of bugs as possible. Please tell me if you think there may be a way to improve it.

Heres the code:

local ServerStorage = game:GetService("ServerStorage")
local PlayersService = game:GetService("Players")
local ChatMessageFunction = game:GetService("ReplicatedStorage"):WaitForChild("SytemMessage")
function SystemMessage(Text,Color)
	local SystemMessageEvent = game
	if not Text or not Color then return end
	if not typeof(Text) == "string" and not typeof(Color3) == "Color3" then return end
	ChatMessageFunction:FireAllClients(Text,Color)
end
function RunGame()
	local Maps = ServerStorage:WaitForChild("Maps"):GetChildren()
	local Gears = ServerStorage:WaitForChild("Gear"):GetChildren()
	local HowManyPlayersPerRound = 2 
	if ServerStorage and Maps and Gears then
		local MapNumber = math.random(1,#Maps)
		local GearNumber = math.random(1,#Gears)
		local PlayersList = PlayersService:GetPlayers()
		local PossiblePlayers = {}
		local PVP_Players = {}
		game.Players.PlayerRemoving:Connect(function(Player)
			local Index = table.find(PVP_Players,Player)
			table.remove(PVP_Players,Index)
		end)
		for  _, Player in pairs(PlayersList) do
			if Player:FindFirstChild("IsLoaded") and Player.Character then
				if Player.IsLoaded.Value then
					table.insert(PossiblePlayers,#PossiblePlayers + 1, Player)
				end
			end
		end
		if #PossiblePlayers <= 1 then SystemMessage("Not Enough People To Start Match!",Color3.fromRGB(255,255,0)) return end
		for I = 1, HowManyPlayersPerRound, 1 do
			local PlayerNumber = math.random(1,#PossiblePlayers)
			local SelectedPlayer = PossiblePlayers[PlayerNumber]
			table.insert(PVP_Players, #PVP_Players + 1, SelectedPlayer)
			table.remove(PossiblePlayers,PlayerNumber)
		end
		if #PVP_Players <= 1 then return end
		local Map = Maps[MapNumber]
		local Gear = Gears[GearNumber]
		Map.Parent = workspace.CurrentMap
		local PVP_Spawns = Map.Spawns:GetChildren()
		for _, Player in pairs(PVP_Players) do
			if Player.Parent then
				Player:LoadCharacter()
				if Player.Character.Parent then
					Player.Character.Humanoid.Died:Connect(function()
						local Index = table.find(PVP_Players,Player)
						table.remove(PVP_Players, Index)
					end)
				end
			end
		end
		local PlayerNamesString = ""
		for Index, Player in pairs(PVP_Players) do
			if #PlayerNamesString == 0 then
				PlayerNamesString = PlayerNamesString..Player.Name
			else
				PlayerNamesString = PlayerNamesString.." and "..Player.Name
			end
		end
		SystemMessage("The Selected Map Will Be: "..Map.Name..", The Selected Players Will Be: "..PlayerNamesString..", The Selected Gear will be: "..Gear.Name..".",Color3.new(1,1,1))
		for _, Player in pairs(PVP_Players) do
			if Player and Player.Character then
				if Player.Character:FindFirstChild("Humanoid") and Player.Character:FindFirstChild("HumanoidRootPart") then
					Player.Character.Humanoid.WalkSpeed = 0
					Player.Character:SetPrimaryPartCFrame(PVP_Spawns[1].T.CFrame)
					table.remove(PVP_Spawns, 1)
				end
			end
		end
		wait(5)
		for _, Player in pairs(PVP_Players) do
			if Player and Player.Character then
				if Player.Character:FindFirstChild("Humanoid") and Player.Character:FindFirstChild("HumanoidRootPart") then
					Player.Character.Humanoid.WalkSpeed = 25
					Gear:Clone().Parent = Player.Character
				end
			end
		end
		repeat
			wait()
		until #PVP_Players <= 1
		wait(3)
		local PVP_Winner = PVP_Players[1]
		if PVP_Winner.Parent then
			SystemMessage(PVP_Winner.Name.." Won The Match!",Color3.new(0,1,0))
			PVP_Winner:LoadCharacter()
		end
		Map.Parent = game.ServerStorage.Maps
	end
end
while true do
	local Success, Error = pcall(RunGame)
	if Error then
		SystemMessage("Error While Setting Up Match, Match Cancelled!",Color3.new(1,0,0))
		if workspace.CurrentMap:FindFirstAncestorOfClass("Model") then
			local Map = workspace:FindFirstAncestorOfClass("Model")
			Map.Parent = game.ServerStorage.Maps
		end
		for _, Player in pairs(game.Players:GetPlayers()) do
			if Player.Parent then
				Player:LoadCharacter()
			end
		end
	end
	wait(10)
end
2 Likes