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