I have a Round System script and need to cancel a task.delay and a function after all players are not in the round anymore but if they are they can continue normal operation.
This is just a part of the script, the whole script is inside a while loop.
Lmk If more info is needed, I’ve written which parts need to be canceled
Keep in mind that I need the function to cancel too, if to say that it ran and there is no more players in round right after it will cause errors from previous experiments
SERVER SCRIPT:
--- [ Incoming Lava Map Effects ] ---
task.delay(CatalogIntermission.To_TotalSeconds(Chosen_Map.Settings.BeginEffects_In.Value), function() -- NEED TO CANCEL THIS
if MapEffects[Chosen_Map.Name] and (type(MapEffects[Chosen_Map.Name]["Incoming_Lava"]) == "function") then -- If Effect And Function For Map Exists
MapEffects[Chosen_Map.Name].Incoming_Lava(Chosen_Map) -- NEED TO CANCEL THIS
print(EventThread.Incoming_Lava)
end
end)
-- Rise Lava --
task.delay(CatalogIntermission.To_TotalSeconds(Chosen_Map.Settings.RiseLava_In.Value), function() -- NEED TO CANCEL THIS
CatalogIntermission.Rise_Lava(Chosen_Map) -- NEED TO CANCEL THIS
end)
--- [ Keeps Round Alive Until No Player Playing ] ---
repeat
task.wait(3)
until CatalogIntermission.AmountOf_PlayingPlayers(Playing) == 0
-------- CANCEL THREAD NEEDS TO BE HERE, As Repeat Loop Ends Right After There Is No Players
task.delay returns a thread object, and you can use task.cancel on it to stop the thread.
For example:
local riseLavaThread = task.delay(CatalogIntermission.To_TotalSeconds(Chosen_Map.Settings.RiseLava_In.Value), function() -- NEED TO CANCEL THIS
CatalogIntermission.Rise_Lava(Chosen_Map) -- NEED TO CANCEL THIS
end)
-- Repeat loop
task.cancel(riseLavaThread)
What im doing currently is I have one Remote that tells all the clients the current game time and what state the game is in. Any process that should only happen during the game checks if this state is “Ingame”, and if not they exit their loops.
The problem is that even if to say a new round began, the function will continue to run and cause errors and glitches, this is why I need to cancel it.
I think if you come up with strong rules for when certain parts of the script will run you’ll be able to find a way to guarantee they have all stopped before a new round starts. I know thats not a great answer but sometimes you just gotta draw stuff and look at it.
In my system, I would have the exact issue you’re saying, but only if any process could run for longer than the “Pregame” state lasts in between rounds, in which case it could miss the state which cancels it. For that reason I just have the rule that no process is allowed to wait.
function HarvestThread(player : Player, beamer, object)
--Make this beamer busy
beamer.active = true
--Handle "killable" effects
local id = math.random()
local beamid = Remotes.Effects.SetHarvestBeam:FireAllClients(beamer.instance, object, id)
--Keep harvesting as long as its possible
--Stops if out of range or resources are empty
while true do
--Sync to game clock
local state, sequencetime = Remotes.ServerGameStateClock.Event:Wait()
--This sould also stop if the game stops
if state ~= "Ingame" then
break
end
print("Harvest...")
--Do the actual harvesting gameplay action
end
Remotes.Effects.KillBeam:FireAllClients(id)
--Unbusy
beamer.active = false
end
The remote ServerGameStateClock sends a state name, either “Ingame” or “Pregame”, and the current time in that phase which counts down. If the game enters the Pregame phase, the actual gameplay-critical action will not be done (the map could be gone!) but everything after the loop is guaranteed to fire. Additionally, my round control script always sends out this ServerGameStateClock event before anything else, so it is guaranteed that all scripts will do their “exit” condition before the round script starts cleaning up the map.