I need help with a Round System

I’m sorry for making this post, I know this is not a place to ask for something like this, but at the moment I have no one else to help me, and this round system is practically the last thing I need to publish my game.

Well… This will be complicated to explain, basically i need a round system, however, the game has a character selection system whenever the player spawns, so it would be necessary for the round system to check if at least 2 players are ready to enter the match. The last player alive would win a reward, and at the end of each game the map would receive a Destroy() since before starting the game, a map would be randomly chosen.

I don’t even know what’s not working, it’s just giving me a headache. Much of what I said above I was not able to make it work.

I tried a lot of alternatives, I’ve been researching for 2 or 3 days, I’m starting to get desperate looking at this script, and now it got to the point where I looked at it and didn’t understand what I’m doing anymore, I was going to redo it all again, but really I don’t know where to start this time, but I was using folders to store BoolValues ​​with the names of the players who were in the match or in the lobby:
Screenshot_14

I don’t think this script is going to be useful, but here’s the mess I’ve made so far:

local roundLength = 5
local gameStartingLength = 5
local intermissionLength = 10
local InRound = game.ReplicatedStorage.InRound
local Status = game.ReplicatedStorage.Status

local Folder = game.ReplicatedStorage.InGame
local inGame = Folder:GetChildren()

local Folder2 = game.ReplicatedStorage.InSpawn
local inSpawn = Folder2:GetChildren()

Folder.ChildRemoved:Connect(function()
	if #inGame == 1 then
		local winner = Folder:IsA("BoolValue")
		local dataWinner = game.Players:FindFirstChild(winner.Name):WaitForChild("Data")
		dataWinner.Coins.Value = dataWinner.Coins.Value + 800
		dataWinner.PowerLevel.Value = dataWinner.PowerLevel.Value + 1600
		winner:Detroy()
	elseif #inGame == 0 then
		InRound.Value = false
	end
end)

InRound.Changed:Connect(function()
	if InRound.Value == true then
		for _,v in pairs(game.ReplicatedStorage.InSpawn:GetChildren()) do
			wait()
			local char = workspace:FindFirstChild(v.Name)
			local ArenaSpawn = workspace.Maps.Map.Spawn
			
			v.Parent = game.ReplicatedStorage.InGame
			
			char.HumanoidRootPart.CFrame = ArenaSpawn.CFrame * CFrame.new(math.random(-50, 50), 0, math.random(-50, 50))
		end
	end
end)

local function intermissionTimer()
	for i = intermissionLength, 0, -1 do
		wait(1)
		if InRound.Value == false then
			if #inSpawn >= 1 then
				Status.Value = "Intermission: "..i.." seconds left!"
			end
		else
			return
		end
	end
	local players = game.ReplicatedStorage.InSpawn:GetChildren()
	
	if #players >= 1 then
		Status.Value = "Preparing The Arena"
		local x = game.ReplicatedStorage.Assets.Maps.Map:Clone()
		x.Parent = workspace.Maps
		wait(1)
		for i = gameStartingLength, 0, -1 do
			wait(1)
			if InRound.Value == false then
				if #inSpawn >= 1 then
					Status.Value = "Game Starts in "..i.." seconds"
				else
					Status.Value = "2 Players or more are required for the start..."
				end
			else
				return
			end
		end
		InRound.Value = true
	else
		Status.Value = "2 Players or more are required for the start..."
		wait(3)
	end
end

local function roundTimer()
	for i = roundLength, 0, -1 do
		wait(1)
		if InRound.Value == true then
			if #inGame == 1 then
				local winner = Folder:IsA("BoolValue")
				local dataWinner = game.Players:FindFirstChild(winner.Name):WaitForChild("Data")
				dataWinner.Coins.Value = dataWinner.Coins.Value + 800
				dataWinner.PowerLevel.Value = dataWinner.PowerLevel.Value + 1600
				winner:Detroy()
			elseif #inGame == 0 then
				InRound.Value = false
			else
				Status.Value = "Game: "..i.." seconds left!"
			end
		else
			return
		end
	end
end

while wait() do
	if InRound.Value == false then
		intermissionTimer()
	else
		roundTimer()
	end
end

Sorry again, and thank you very much for your attention!

Are there any errors and for future reference when something isn’t working you can use prints between every 5 lines or so to find out what specifically isn’t working.

1 Like

I’m not very good with scripting, but I’ve found a lot of good tutorials on YouTube. By the looks of it you already know how to use functions and variables, so you might be able to tweak these tutorials:

and this
How To Make A Roblox Game - 2022 Beginner Tutorial! - YouTube
I hope this helped!

3 Likes

I’ve already watched all the tutorials on this, but I’m still a bit far from achieving what I need

1 Like

there is no errors, I fixed all that appeared. This is really complicated to explain, I think I will have to redo everything, but I needed some advice to know at least what I should do

It might be just because you’re using a loop with functions without a coroutine or spawn function. I mean just off a general look thats what I would attempt first.
I assume you don’t know how to do it so here.

local roundLength = 5
local gameStartingLength = 5
local intermissionLength = 10
local InRound = game.ReplicatedStorage.InRound
local Status = game.ReplicatedStorage.Status

local Folder = game.ReplicatedStorage.InGame
local inGame = Folder:GetChildren()

local Folder2 = game.ReplicatedStorage.InSpawn
local inSpawn = Folder2:GetChildren()

Folder.ChildRemoved:Connect(function()
	if #inGame == 1 then
		local winner = Folder:IsA("BoolValue")
		local dataWinner = game.Players:FindFirstChild(winner.Name):WaitForChild("Data")
		dataWinner.Coins.Value = dataWinner.Coins.Value + 800
		dataWinner.PowerLevel.Value = dataWinner.PowerLevel.Value + 1600
		winner:Detroy()
	elseif #inGame == 0 then
		InRound.Value = false
	end
end)

InRound.Changed:Connect(function()
	if InRound.Value == true then
		for _,v in pairs(game.ReplicatedStorage.InSpawn:GetChildren()) do
			wait()
			local char = workspace:FindFirstChild(v.Name)
			local ArenaSpawn = workspace.Maps.Map.Spawn
			
			v.Parent = game.ReplicatedStorage.InGame
			
			char.HumanoidRootPart.CFrame = ArenaSpawn.CFrame * CFrame.new(math.random(-50, 50), 0, math.random(-50, 50))
		end
	end
end)

local function intermissionTimer()
	for i = intermissionLength, 0, -1 do
		wait(1)
		if InRound.Value == false then
			if #inSpawn >= 1 then
				Status.Value = "Intermission: "..i.." seconds left!"
			end
		else
			return
		end
	end
	local players = game.ReplicatedStorage.InSpawn:GetChildren()
	
	if #players >= 1 then
		Status.Value = "Preparing The Arena"
		local x = game.ReplicatedStorage.Assets.Maps.Map:Clone()
		x.Parent = workspace.Maps
		wait(1)
		for i = gameStartingLength, 0, -1 do
			wait(1)
			if InRound.Value == false then
				if #inSpawn >= 1 then
					Status.Value = "Game Starts in "..i.." seconds"
				else
					Status.Value = "2 Players or more are required for the start..."
				end
			else
				return
			end
		end
		InRound.Value = true
	else
		Status.Value = "2 Players or more are required for the start..."
		wait(3)
	end
end

local function roundTimer()
	for i = roundLength, 0, -1 do
		wait(1)
		if InRound.Value == true then
			if #inGame == 1 then
				local winner = Folder:IsA("BoolValue")
				local dataWinner = game.Players:FindFirstChild(winner.Name):WaitForChild("Data")
				dataWinner.Coins.Value = dataWinner.Coins.Value + 800
				dataWinner.PowerLevel.Value = dataWinner.PowerLevel.Value + 1600
				winner:Detroy()
			elseif #inGame == 0 then
				InRound.Value = false
			else
				Status.Value = "Game: "..i.." seconds left!"
			end
		else
			return
		end
	end
end

spawn(function()
     while wait() do
	     if InRound.Value == false then
		     intermissionTimer()
	     else
		     roundTimer()
	     end
     end
end)

Using loops like this is often bad practice tbh its best to learn to avoid it from the start.

1 Like

so there’s multiple errors with the code; first of all you are calling :Detroy() which im assuming is supposed to be :Destroy().
also at the start of the code you have stuff like

local Folder = game.ReplicatedStorage.InGame
local inGame = Folder:GetChildren()

local Folder2 = game.ReplicatedStorage.InSpawn
local inSpawn = Folder2:GetChildren()

the inGame and inSpawn variables will both hold 0 forever. since when you call the variable the folder and folder2 both have 0 children (im assuming). to fix this you would most likely have to update the inSpawn and inGame variables everytime a child is added/removed from the Folder and Folder2.

also i recommend you try to move the stuff from replicatedstorage to serverstorage since exploiters will have harder time accessing it…

2 Likes

I’ll remember that, thanks you

I still hadn’t received any error about it, as the game started with only 1 player and no one had been removed. Thanks for that, I’ll redo everything and add ChildAdded too

Try add breakpoints and debugging.

1 Like

I researched about it now, so far I still didn’t know it. Thanks!

I’ve made an unfinished round system which is taken through an object-oriented programming approach, and I’m willing to share it for other people.

default.project.json (1.3 KB) main.lua (6.5 KB) round.server.lua (1.9 KB) roundVotes.server.lua (252 Bytes)

(ignore the default project json part. I coded this in visual studio code using Rojo.)

In order to open these (since these are lua files), you’ll have to right click on them and press on “Open With”, and then select any text editor.

.server.lua - server script
.lua - module script
.client.lua - client script/local script

1 Like

I’m going to reread everything in a more concentrated way, but with a quick reading it already looks good, and helped me to better understand how a module works (I was having a hard time about it). Thanks you so much!

I didn’t understand two things about your Module Script.

Starting at line 41, it has a statement that regardless of the condition, returns the function:

if self.StartedRound then
	return
else
	break
end

PrtSc:

The other question is about line 75, I didn’t understand the reason for the existence of this function:

local function sleep(n)
	local start = os.time()
	repeat wait() until os.time() > time + n
end

This function isn’t mentioned anywhere else and I didn’t understand its purpose there.

You had said that it’s an unfinished system, I was wondering if this is why it’s like this. Thanks for your attention once again!

SORRY FOR THE LATE REPLY, I WAS BUSY WITH A LOT OF PROJECTS.

(sorry for looking aggressive up above, I was just disappointed in myself at how I didn’t put much attention in to this)

Anyways, the sleep part, I was in Visual Studio Code, so I thought I was making a Lua program again, so I was making my own wait() function, since it isn’t a built-in function that comes packaged with the regular Lua.

Anyways, I don’t really remember why I did that, but I guess just in case the loop still ran, so you should just keep it like this:

And it should all be fine.