Minigame Handler Review- Possibility to optimize code?

I am currently developing a minigame game to further my scripting skills and hone in on what I’ve learned, and I was wondering if there are any further ways to optimize this code. I’ve turned a few of the large blocks of code into functions and took out unnecessary parts, but I can still see some parts that may need revision.

The reason why I have so many waits is because I want to delay the message before the next part begins. You’ll see what I mean once you see the code.

-- // Services \\ --
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local Teams = game:GetService("Teams")
local RunService = game:GetService("RunService")

-- // Variables \\ ==
local status = RS.GameStatus;
local Maps = RS.Maps:GetChildren();
local chosenMap;
local intermissionTime = 15;
local Playing = Teams.Playing;
local Spectating = Teams.Spectating;
local gameLength = 15;

-- // Functions \\ --
local function ChangeGameStatus(newStatus)
	status.Value = tostring(newStatus)
end

local function selectRandomMap()
	if #Maps >= 1 then
		local id = math.random(1, #Maps)
		local map = Maps[id]

		if map then

			local clonedMap = map:Clone()
			clonedMap.Parent = workspace
			return clonedMap, clonedMap.Spawns
		end
	end
end


-- // Loops \\ --
while true do
	wait(1.5 )-- Wait to prevent crashing and to check every 1.5 seconds, might replace while true do & wait with RunService.Heartbeat

	if #Players:GetPlayers() >= 2 then

		ChangeGameStatus("Sufficient players in the game, picking a map!")
		wait(5)
		
		
		local map, spawns = selectRandomMap()
		spawns = spawns:GetChildren()
		wait(3)

		ChangeGameStatus("A new map has been selected: " .. map.Name)
		wait(3)
		ChangeGameStatus("Preparing to teleport players!")
		wait(3)


		for i = 1, intermissionTime, -1 do
			ChangeGameStatus("Teleporting players in " .. i .. " seconds.")
			wait(1)
		end


		ChangeGameStatus("Teleporting...")
		wait(1)

		for _, player in pairs(Spectating:GetPlayers()) do -- Get the players currently spectating and teleport them to a random spawn.
			local character = player.Character or player.CharacterAdded:Wait()
			local hrp = character:FindFirstChild("HumanoidRootPart")
			player.Team = Teams.Playing

			if hrp and character then
				local randomSpawnId = math.random(1, #spawns)
				local randomSpawn = spawns[randomSpawnId]

				hrp.Position = randomSpawn.Position + Vector3.new(0, 10, 0)
			end
		end

		for i = 3, 1, -1 do -- Start the 3, 2, 1 countdown.
			ChangeGameStatus(i .. "...")
			wait(1)
		end

		local spawnProtection = map["Spawn Protection"] -- Destroy the spawn protector that prevents them from leaving early.
		spawnProtection:Destroy()

		for i = gameLength, 1, -1 do -- Countdown from game length.
			ChangeGameStatus(i .. " seconds left!")
			wait(1)
		end


		ChangeGameStatus("Map finished!")
		for _, player in pairs(Playing:GetPlayers()) do -- Get all playing players and teleport them back to spawn. 
			local character = player.Character or player.CharacterAdded:Wait()
			local hrp = character:FindFirstChild("HumanoidRootPart")
			local humanoid = character:FindFirstChild("Humanoid")
			player.Team = Teams.Spectating
			
			if hrp and humanoid and character then
				humanoid.WalkSpeed = 0
				hrp.Position = workspace.Lobby.Spawn.SpawnLocation.Position + Vector3.new(0, 10, 0)
				humanoid.WalkSpeed = 16
			end
		end

		ChangeGameStatus("Restarting game.")

		map:Destroy() -- Destroy the map and restart the loop.
	end
end	

The code works correctly, and I have yet to encounter any problems. Any and all suggestions are appreciated!

1 Like

There’s nothing necessarily wrong with how you are doing your minigame loop now. In terms of optimization, that is not something I would focus on right now. I only optimize code if it truly NEEDS to be optimized in order to run as quickly as possible. In the case of a minigame loop, your focus should be on maintaining readability so it’s easy to make changes later on. I can tell you that, for my minigame loops, I have the main game loop in a while true do loop or a runService.Heartbeat:Wait() loop, but the logic within it (teleporting players, rewarding players, removing and creating maps) is all handled by a module script parented to the minigame loop script. In my opinion, doing it that way looks a lot nicer, but it doesn’t offer any performance benefit.

1 Like