Hi,
My round system is very messy and long. I have a feeling it can be shortened drastically. I need help making this more readable:
--> services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local SoundService = game:GetService("SoundService")
--> folders
local Source = ReplicatedStorage.Source
local Dependencies = Source.Dependencies
local ServerDependencies = ServerScriptService.Source.Dependencies
local Assets = ReplicatedStorage.Assets
local Background = SoundService.Master.Background
--> requires
local Settings = require(Dependencies.GameSettings)
local BridgeNet2 = require(Dependencies.BridgeNet2)
local DataManager = require(ServerDependencies.Data)
local Knit = require(ReplicatedStorage.Packages.Knit)
local PlaySound = require(Source.Util.playSound)
--> variables
local Values = Source.Values
--> remotes
local UpdateStats = BridgeNet2.ReferenceBridge("UpdateStats")
--> tables
local Participants = {}
local Data = {}
local GameService = Knit.CreateService{
Name = "GameService",
Client = {},
};
--> constants
local isStart = nil
local isBreak = nil
local previousSeeker = nil
local function timeFormat(s)
return string.format("%02i:%02i", s/60, s%60)
end
function updateData()
for _, p in pairs(Players:GetPlayers()) do
local playerData = DataManager:GetData(p)
if Data[p.Name] then
continue
end
Data[p.Name] = playerData
end
UpdateStats:Fire(BridgeNet2.AllPlayers(), Data)
end
function onDeadPlayerAdded(player: Player)
table.insert(Participants, player)
updateData()
-- isStart = intermission started
if isStart then
return
end
if #Participants >= Settings.MinimumPlayers then
isBreak = false
-- intermission
for seconds = Settings.Intermission, 1, -1 do
if isBreak then
Values:SetAttribute("Status", Settings.MinimumPlayersStatus)
isBreak = true
isStart = false
break
end
Values:SetAttribute("Status", "starting in: "..seconds.." seconds")
isStart = true
task.wait(1)
end
if isBreak then -- not enough players to start
isStart = false
return
end
-- set began = handles maps in another module.
Values:SetAttribute("Began", true)
-- small delay before teaming and teleporting
task.wait(3)
local map = Assets.Maps[Values:GetAttribute("Map")]
-- 1-3 = 1 seekers, 4-6 = 2 seekers, 7-9 = 3 seekers.
local seekerCount = math.ceil(#Participants / 3)
-- handle spawning
local RedSpawns = map:FindFirstChild("RedSpawns"):GetChildren()
local GreenSpawns = map:FindFirstChild("GreenSpawns"):GetChildren()
local randomRedSpawn = RedSpawns[math.random(1,#RedSpawns)]
local randomGreenSpawn = GreenSpawns[math.random(1,#GreenSpawns)]
-- choose seeker(s).
for i = seekerCount, 1, -1 do
local random = math.random(1, #Participants)
local playerPicked = Participants[random]
if seekerCount == 1 then -- variety in small servers.
if previousSeeker and playerPicked == previousSeeker then
repeat
random = math.random(1, #Participants)
playerPicked = Participants[random]
until playerPicked ~= previousSeeker
end
previousSeeker = playerPicked
end
playerPicked.Team = Settings.Red
local humanoid = playerPicked.Humanoid
humanoid.HealthDisplayDistance = Settings.RunnerNameDistance
humanoid.NameDisplayDistance = Settings.RunnerNameDistance
local root = playerPicked.Character.HumanoidRootPart
root.CFrame = randomRedSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
table.remove(Participants, random)
end
-- put rest in runners.
for _, player: Player in pairs(Participants) do
player.Team = Settings.Green
local root = player.Character.HumanoidRootPart
root.CFrame = randomGreenSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
local humanoid = player.Character.Humanoid :: Humanoid
humanoid.Died:Connect(function()
player.Team = Settings.Dead
end)
end
local function win()
-- sfx
PlaySound(Background.Victory)
PlaySound(Background.Applause)
-- delay before winner gets teleported to spawn.
task.wait(Background.Victory.TimeLength + 1)
Values:SetAttribute("Began", false)
isStart = false
for _, player in next, Players:GetPlayers() do
player.Team = nil -- makes it so you need to press play to participate again.
if player.Character then
local humanoid = player.Character.Humanoid
local root = player.Character.HumanoidRootPart
root.CFrame = workspace.Lobby.SpawnLocation.CFrame * CFrame.new(0,10,0)
humanoid.HealthDisplayDistance = 50
humanoid.NameDisplayDistance = 50
end
end
end
-- tables stay the same
local runners = Settings.Green:GetPlayers()
local seekers = Settings.Red:GetPlayers()
-- game start
for seconds = Settings.TimeLength, 1, -1 do
local time = timeFormat(seconds)
Values:SetAttribute("Status", time)
-- updated tables
local greenCount = Settings.Green:GetPlayers()
local redCount = Settings.Red:GetPlayers()
if #greenCount == 0 then -- seekers win / all runners dead
Values:SetAttribute("Status", Settings.SeekerWinStatus)
for _, runner: Player in pairs(runners) do
local runnerData = DataManager:GetData(runner)
if not runnerData or not runnerData.Statistics then -- player left the game
continue
end
runnerData.Statistics.Loses += 1
end
for _, seeker: Player in pairs(seekers) do
local seekerData = DataManager:GetData(seeker)
if not seekerData or not seekerData.Statistics then
continue
end
seekerData.Statistics.Wins += 1
seekerData.Statistics.Coins += Settings.SeekerWinCoins
end
win()
break
end
if seconds == 0 or #redCount == 0 then -- runners win / game ended
Values:SetAttribute("Status", Settings.RunnerWinStatus)
for _, runner: Player in pairs(greenCount) do
local runnerData = DataManager:GetData(runner)
if not runnerData or not runnerData.Statistics then -- player left/ +1 lose regardless
continue
end
runnerData.Statistics.Wins += 1
runnerData.Statistics.Coins += Settings.RunnerWinCoins
end
for _, seeker: Player in pairs(redCount) do
local seekerData = DataManager:GetData(seeker)
if not seekerData or not seekerData.Statistics then -- player left / +1 lose regard
continue
end
seekerData.Statistics.Loses += 1
end
win()
if #redCount == 0 then -- seeker left, end game.
break
end
end
task.wait(1)
end
end
end
function onDeadPlayerRemoved(player: Player)
--/ remove player from queue.
if table.find(Participants, player) then
table.remove(Participants, table.find(Participants, player))
end
--/ if participants less than minimum after leave, stop intermission.
if #Participants < Settings.MinimumPlayers and not Values:GetAttribute("Began") then
isBreak = true
Values:SetAttribute("Status", Settings.MinimumPlayersStatus)
end
end
function gamePresync()
Settings.Dead.PlayerAdded:Connect(onDeadPlayerAdded)
Settings.Dead.PlayerRemoved:Connect(onDeadPlayerRemoved)
end
function GameService.KnitStart()
gamePresync()
end
return GameService