Hi I am working on a round game with different gamemodes and each gamemode runs on a module script.
I am working on classic gamemode where its basically runners vs killer.
After finishing my script I looked back at it and saw how hard and stressful it would be to add new things to the script. Is there anyway to optimize this script furthermore so anytime I edit it I don’t get a headache?
--] Variables
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Remotes = ReplicatedStorage.Remotes.Classic
local Values = ReplicatedStorage.Values
local Voting = workspace.Lobby.Voting
local Maps = ServerStorage.Maps:GetChildren()
local Choices = Voting:GetChildren()
local TimeFormat = require(ReplicatedStorage.Modules.TimeFormat)
local Settings = {
Round = {
Interval = 15,
RoundTime = 125
};
Strings = {
NotEnoughPlayers = "Waiting for more players...",
Starting = "Starting in: ",
Ending = false,
}
}
local Teams = {
Red = game.Teams.Killer,
Blue = game.Teams.Runner,
Lobby = game.Teams.Lobby
}
local Status = Values.Status
local InRound = Values.InRound
-- declarations
local isAnOption
local randomMap
local chosenMap
local mapClone
local previousKiller
local killer
local BlueCount
local RedCount
local RemainderBlue
local RemainderRed
local Connections = {}
local Playerlist = {}
local Jukebox = {}
Jukebox.__index = Jukebox
-- functions
function CheckIfMenu(Player)
if Player.PlayerGui.Menu.Frame.Visible == true then
return false
else
return true
end
end
function PickRandomMap() -- Self Explanatory
local randomNumber = math.random(1, #Maps)
randomMap = Maps[randomNumber]
return randomMap.CanBeVoted
end
function PickKiller()
for _, player in ipairs(game.Players:GetChildren()) do
if player ~= previousKiller then
if player.PlayerGui.Camera.Enabled == true then
table.insert(Playerlist, player)
end
end
end
print(Playerlist)
local SelectedKiller = Playerlist[math.random(1, #Playerlist)]
previousKiller = SelectedKiller
Playerlist = {}
return SelectedKiller
end
function VoteSystem()
for i, choice in pairs(Choices) do
local name = choice.label.SurfaceGui.TextLabel
local picture = choice.Image.SurfaceGui.ImageLabel
isAnOption = PickRandomMap()
if isAnOption.Value == true then
repeat
isAnOption = PickRandomMap()
until isAnOption.Value == false
name.Text = randomMap.Name
picture.Image = randomMap.Image.Value
randomMap.CanBeVoted.Value = true
else
name.Text = randomMap.Name
picture.Image = randomMap.Image.Value
randomMap.CanBeVoted.Value = true
end
end
end
function RoundChanged()
if InRound.Value == true then -- round is in progress
local Choice1Votes = #Voting.Choice1.button.Votes:GetChildren()
local Choice2Votes = #Voting.Choice2.button.Votes:GetChildren()
local Choice3Votes = #Voting.Choice3.button.Votes:GetChildren()
if Choice1Votes >= Choice2Votes and Choice1Votes >= Choice3Votes then
chosenMap = Voting.Choice1.label.SurfaceGui.TextLabel.Text
elseif Choice2Votes >= Choice1Votes and Choice2Votes >= Choice3Votes then
chosenMap = Voting.Choice2.label.SurfaceGui.TextLabel.Text
else
chosenMap = Voting.Choice3.label.SurfaceGui.TextLabel.Text
end
Status.Value = "Map: ".. chosenMap
for _, map in pairs(Maps) do
if chosenMap == map.Name then
mapClone = map:Clone()
mapClone.Parent = game.Workspace
end
end
for i, choice in pairs(Choices) do
choice.label.SurfaceGui.TextLabel.Text = " "
choice.Image.SurfaceGui.ImageLabel.Image = " "
choice.button.Votes:ClearAllChildren()
Remotes.VoteReset:FireAllClients(choice.button)
end
local BlueTeamCount = {}
local RedTeamCount = {}
local killer = PickKiller()
if killer then
local RedSpawns = mapClone.RedSpawns:GetChildren()
local BlueSpawns = mapClone.BlueSpawns:GetChildren()
for i, plr in ipairs(game.Players:GetChildren()) do
local char = plr.Character
local humanRoot = char:WaitForChild("HumanoidRootPart")
-- picks a random spawn from each team
local randomRedSpawn = RedSpawns[math.random(1,#RedSpawns)]
local randomBlueSpawn = BlueSpawns[math.random(1,#BlueSpawns)]
-- will put the current player into a team with the less amount of players
if plr ~= killer then
plr.Team = Teams.Blue
humanRoot.CFrame = randomBlueSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
plr.CameraMode = Enum.CameraMode.Classic
plr.CameraMaxZoomDistance = 9
table.insert(BlueTeamCount, plr.Name)
elseif plr == killer then
plr.Team = Teams.Red
plr.CameraMode = Enum.CameraMode.LockFirstPerson
plr.CameraMaxZoomDistance = 9
humanRoot.CFrame = randomRedSpawn.CFrame + Vector3.new(math.random(1,3),math.random(1,3),math.random(1,3))
table.insert(RedTeamCount, plr.Name)
end
end
end
else -- not in progress
for _, player in pairs(Players:GetPlayers()) do
local Character = player.Character or player.CharacterAdded:Wait()
if Character then -- just incase
local HumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
HumanoidRootPart.CFrame = (workspace.Lobby.lobbySpawn.CFrame + Vector3.new(0,5,0))
player.Team = Teams.Lobby
if Character.Head:FindFirstChild("Killbrick") then
Character.Head:FindFirstChild("Killbrick"):Destroy() -- destroys the kill brick
end
end
end
-- voting system
if mapClone ~= nil then
mapClone:Destroy()
end
for i, map in pairs(Maps) do
map.CanBeVoted.Value = false
end
for i, choice in pairs(Choices) do
local name = choice.label.SurfaceGui.TextLabel
local picture = choice.Image.SurfaceGui.ImageLabel
isAnOption = PickRandomMap()
if isAnOption.Value == true then
repeat
isAnOption = PickRandomMap()
until isAnOption.Value == false
name.Text = randomMap.Name
picture.Image = randomMap.Image.Value
randomMap.CanBeVoted.Value = true
else
name.Text = randomMap.Name
picture.Image = randomMap.Image.Value
randomMap.CanBeVoted.Value = true
end
end
end
end
-----
function Jukebox.new()
local self = setmetatable({},Jukebox)
return self
end
function Jukebox:Round()
while true do
repeat
Status.Value = Settings.Strings.NotEnoughPlayers
task.wait(1)
until #Players:GetChildren() >= 1
InRound.Value = false
for i = Settings.Round.Interval,0,-1 do
Status.Value = Settings.Strings.Starting..i
task.wait(1)
end
InRound.Value = true
BlueCount = {}
RedCount = {}
for i = Settings.Round.RoundTime,0,-1 do
task.wait(1)
local Time = TimeFormat:Convert(i, "Default", true)
if Settings.Strings.Ending == false then
Status.Value = Time
else
Status.Value = Settings.Strings.Ending..Time
end
local RemainderBlue = {}
local RemainderRed = {}
for _, player in pairs(Players:GetPlayers()) do
if player.Team == Teams.Blue then
if i == Settings.Round.RoundTime then
table.insert(BlueCount,player.Name)
end
table.insert(RemainderBlue,player.Name)
elseif player.Team == Teams.Red then
if i == Settings.Round.RoundTime then
table.insert(RedCount,player.Name)
end
table.insert(RemainderRed, player.Name)
end
end
if #RemainderRed == 0 and i == 0 then -- both teams lost
print("Both lost")
break
end
if #RemainderRed == 0 or i == 0 then -- blue won
print("Blue won")
break
end
if #RemainderBlue == 0 then -- red won
print("Red won")
break
end
end
end
end
-- connections
Values.InRound:GetPropertyChangedSignal("Value"):Connect(RoundChanged)
game.Players.PlayerAdded:Connect(function(Player)
script.Loading:Clone().Parent = Player.PlayerGui -- loads game
Player:GetPropertyChangedSignal("Team"):Connect(function()
local Killbrick = ServerStorage.Assets.Red.KillBrick
if Player and Player.Team == Teams.Red then -- if players red
local character = Player.Character
if character then
Player.CameraMode = "LockFirstPerson"
local kb = Killbrick:Clone()
wait(0)
kb.Parent = character.Head
kb.CFrame = (character.Head.CFrame + Vector3.new(0,0,-2))
kb.Orientation = Vector3.new (90,0,0)
local weld = Instance.new("WeldConstraint")
weld.Parent = character.Head
weld.Part0 = kb
weld.Part1 = character.Head
kb.IsInUse.Value = true
end
Connections[Player] = Player.CharacterAdded:Connect(function(character)
local kb = Killbrick:Clone()
task.wait(0)
kb.Parent = character.Head
kb.CFrame = (character.Head.CFrame + Vector3.new(0,0,2))
kb.Orientation = Vector3.new (90,0,0)
local weld = Instance.new("WeldConstraint")
kb.Name = "Killbrick"
weld.Name = "Weld"
weld.Parent = character.Head
weld.Part0 = kb
weld.Part1 = character.Head
Player.CameraMode = "LockFirstPerson"
kb.IsInUse.Value = true
end)
else
local connection = Connections[Player]
if connection then
connection:Disconnect()
end
local character = Player.Character
if character then
for i,v in pairs(character.Head:GetChildren()) do
if v.Name == ("Killbrick") then
v:Destroy()
end
end
end
end
end)
Player.CharacterAdded:Connect(function(Character)
Character.Humanoid.Died:Connect(function()
Player.Team = Teams.Lobby
Player.CameraMode = Enum.CameraMode.Classic
Player.CameraMaxZoomDistance = 9
end)
end)
end)
-- initilizing gamemode
VoteSystem()
Jukebox:Round()
return Jukebox
Thanks for reading.