Rounds System Framework

Hi, new scripter here. What would be the easiest way to make a rounds system that loads a minigame and keeps track of player count?

1 Like

Well do you have any start on the problem?

I was thinking about loading in maps for the minigames by cloning it to the Workspace from ReplicatedStorage, then a script that checks what map has been loaded and performs a function from there. Not sure how I would do a player count and get everyone teleported in though!

Well do you have designated spawns in each map?

That could be easily added, yeah. But the lobby also has spawns so I’m not sure how to control which one players spawn at.

So you have spawnlocations in each map right? I wouldn’t use spawnlocations in the maps, I would just use a regular parts and teleport the players to them.

You should learn about tables and how to remove, add and index things within them. Keep track of players in a table and when its empty / only one is left, the round is over.
You can use humanoid.Died to keep track of when someone is out and proceed to remove them from the playing team. I suggest using a for loop to keep track of time, as they are easy to stop and it’s easy to keep track of how much time is left.
Then you should make functions for starting the rounds and for when a round has ended, include map loading in the start round part and unload when it ended.

1 Like

Yeah, that could be possible. How would the script keep track of how many players are still alive and know when to start a new game?

This is great, I’ll definitely try this.

You create a variable with the number of the active players. At the start of each round, loop through all the players and add +1 to the variable, also listening for them to die, and remove -1 from the variable when they do, also checking if the variable is below the minimum player count, if it is then end the round.

You have to create sequence, first of all make script collect all players, then count those players and set specific value, you can keep track of them by checking if they reset, if yes then player count would decrease, if player count is 1 then this player is a winner

Loading map should look like that:

  • Map is loaded from Server Storage
  • Script checks which map is it
  • Specific module for this specific map is called
  • Module executes functions
  • When round is ended, remove map and stop all functions connected to it

Made this simple round system, you can use this as a reference if you want to. Some things might not be the best way of doing stuff but this is a basic working round system that selects a random map and moves players to a random spawn on the map. It ends if all players die or if the time runs out.
You obviously don’t have to use it or do anything like it, just thought I’d post it because it’s what this topic is about and could help.

local players = game:GetService("Players")

local playing = {}
local maps = {}

local roundActive = false
local roundTimer = 0
local currentMap

-- // this is just because I don't have a map, you could store your maps in a folder and then use :GetChildren() to have the same effect
do
	local map = Instance.new("Model")
	local spawns = Instance.new("Folder", map)
	local _spawn = Instance.new("Part", spawns)
	_spawn.Anchored = true
	spawns.Name = "Spawns"
	table.insert(maps, map)
end

local function loadMap()
	local map = maps[math.random(1, #maps)]:Clone()
	currentMap = map
	map.Parent = workspace
	return map:FindFirstChild("Spawns"):GetChildren()
end

local function roundEnded()
	if (roundActive) then return end -- // In order to prevent roundEnded from being called multiple times
	
	print("Round over!")
	
	roundActive = false
	if (#playing > 0) then
		local winners = {}
		for _, player in next, playing do table.insert(winners, player.Name) end -- // Had to do this because roblox is stupid
		print("Winners are:", table.concat(winners, ", "))
	else
		print("No one won!")
	end
	
	for _, player in next, playing do
		player:LoadCharacter() -- // You could also just move them back to the lobby
	end
	
	if (currentMap ~= nil) then
		currentMap:Destroy()
		currentMap = nil
	end
end

local function startRound()
	print("starting round!")
	table.clear(playing) -- // Just to make sure
	
	local spawns = loadMap()
	
	for _, player in next, players:GetPlayers() do
		-- // Adding every player with a character and a humanoid that is alive
		local character = player.Character
		if (not character) then continue end
		
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if (not humanoid or humanoid:GetState() == Enum.HumanoidStateType.Dead) then continue end
		
		table.insert(playing, player)
		
		humanoid.Died:Once(function()
			table.remove(playing, table.find(playing, player))
		end)
		
		character:PivotTo(spawns[math.random(1, #spawns)].CFrame)
	end
	
	roundActive = true
	roundTimer = 3
	for i = roundTimer, 1, -1 do
		if (not roundActive or #playing == 0) then break end
		task.wait(1)
		roundTimer -= 1
		print(roundTimer)
	end
	
	roundEnded()
	
	return "round over!" -- // Returning something so that the while loop yields while the round is active
end

while (task.wait(2)) do
	startRound()
end

Try learning promises, i think promises really good for Round System’s or looped things. Best Game-Round System - #12 by des_oeufs