I’m trying to create a round system alike to the one in the game Color Block on Roblox.
The problem is, whenever a player wins, I want the round to restart but the times I’ve tried implementing this I’ve tried recursion which I think has given me the error “Script exhausted allowed execution time”.
The main reason I created this post was to ask some questions to solve this problem.
How can I restart a loop/round system when a player wins?
Is recursion usable for round systems?
Can I utilize coroutines to make this round system?
To restart the round, would I just disconnect the current round? How could I basically delete everything that happened before and restart it back to square one when a player wins.
Whenever a player wins, I want the round to restart, just like any other mini-game on Roblox.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local Remotes = ReplicatedStorage.Remotes
local ServerBinds = ServerStorage.ServerBinds
local ROUND_START = 100
local ROUND_END = 0
local ROUND_UPDATE = 15
local START_TIME = 15
local END_TIME = 0
local MINIMUM_PLAYERS = 1
local VOTING = false
local InRound = require(script.InRound)
local PlayerRemover = require(script.PlayerRemover)
local MapHandler = require(script.MapHandler)
local Colors = require(script.Colors)
local BrickColors = require(script.BrickColors)
local Ending = require(script.Ending)
local ServerStatus = ServerStorage.ServerStatus
local CurrentMap = ServerStorage.CurrentMap
local MapChoices = {
FlatColorMap = 0,
}
local RoundCounter = 0
local playersInRound = {}
local playersVoted = {}
local playersWhoHaveDied = {}
local STOP = false
local Core = {}
function Core.Init()
repeat
task.wait(1)
until #Players:GetPlayers() >= MINIMUM_PLAYERS
Remotes.YieldCoroutine.Event:Connect(function()
coroutine.yield()
end)
ServerStatus.Value = "Intermission"
Remotes.Voting:FireAllClients("TurnOn",true)
VOTING = true
for i,player in Players:GetPlayers() do
player.CharacterAdded:Connect(function(character)
if VOTING == true then
task.wait()
Remotes.Voting:FireClient(player,"Respawn",true)
end
end)
end
Remotes.Voting.OnServerEvent:Connect(function(player,vote)
if typeof(vote) ~= "string" then return end
if playersVoted[player] and playersVoted[player] == vote then return end
for i,v in MapChoices do
if vote == tostring(i) then
if playersVoted[player] then
MapChoices[playersVoted[player]] -= 1
end
playersVoted[player] = vote
MapChoices[i] += 1
Remotes.Voting:FireAllClients("VoteCount",tostring(MapChoices[i]),tostring(i))
end
end
end)
for i = START_TIME,END_TIME,-1 do
if STOP == true then break end
Remotes.ShowStatus:FireAllClients("Intermission: " .. tostring(i))
task.wait(1)
end
Remotes.Voting:FireAllClients("TurnOff",false)
VOTING = false
playersVoted = {}
for i,player in Players:GetPlayers() do
table.insert(playersInRound,player)
end
local ChosenMap,Pos,MapVal = MapHandler:Start(MapChoices)
local FirstColors = BrickColors:Roll(3)
Colors:ColorMap(ChosenMap,FirstColors)
Colors:Update(ChosenMap,FirstColors)
InRound:Init(playersInRound,Pos)
CurrentMap.Value = MapVal
ServerStatus.Value = "Round"
for i,runner in playersInRound do
local character = runner.Character or runner.CharacterAdded:Wait()
character.Humanoid.Died:Connect(function()
PlayerRemover:Die(runner,playersInRound,playersWhoHaveDied)
if #playersInRound <= 1 then
Ending:Win(Remotes.Ending,playersInRound,playersWhoHaveDied)
Remotes.YieldCoroutine:Fire()
STOP = true
Core:Reset()
task.spawn(function()
wait(3)
return "Yes"
end)
return "No"
--[[
repeat
print(#playersInRound)
if #playersInRound ~= 0 then continue end
if ServerStatus.Value == "Intermission" then break end
STOP = true
task.wait(3)
self:Reset(ChosenMap)
self:Init()
task.wait(1)
return
until #playersInRound == 0
--]]
end
end)
end
for i = ROUND_START,ROUND_END,-1 do
if STOP == true then break end
RoundCounter = i
if RoundCounter % ROUND_UPDATE == 0 then
if RoundCounter ~= ROUND_UPDATE then
local BrickColorsTable = BrickColors:Roll(3)
Colors:Update(ChosenMap,BrickColorsTable)
elseif RoundCounter <= ROUND_START - ROUND_UPDATE then
Colors:Update(ChosenMap,FirstColors)
end
end
Remotes.ShowStatus:FireAllClients("Round: " .. tostring(i))
task.wait(1)
end
ServerStatus.Value = "Intermission"
for i,player in Players:GetPlayers() do
if STOP == true then break end
if table.find(playersInRound,player) then
PlayerRemover:Init(playersInRound,player)
end
end
Remotes.DestroyMap.Event:Connect(function()
ChosenMap:Destroy()
end)
Core:Reset(ChosenMap)
end
function Core:Reset(map)
Remotes.UpdateInfo:FireAllClients("Restart","Color: ","Mode: ",Color3.fromRGB(127, 128, 128))
ServerStatus.Value = "Intermission"
RoundCounter = 0
CurrentMap.Value = ""
Remotes.DestroyMap:Fire()
playersInRound = {}
playersWhoHaveDied = {}
end
return Core
-- Script breaks
-- Keeps moving forward even though someone has already won
-- Slight delay in voting intermission and status changes
You don’t need anything complicated like recursion or coroutines
Its a simple vote, start game, and repeat
Just add some functionality to reset the game after the game ends
You could do this by cloning a map each time the game starts, using that map for the game, then deleting it after
edit:
The script already has most of this
The game is continuing because the for loop at the end isn’t affected when the round ends
You can put that in a coroutine and stop it when the game ends
But how am I gonna make the round restart when a player wins. If the player wins, everyones gonna be waiting for the round to end because the color tiles are continue looping and every player is just gonna be waiting until the next intermission.
I’m getting the errors like “Script exhausted allowed execution time”, players being spawned to the map consecutively, and overlapping rounds.