How To Cancel task.delay & Function?

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)
3 Likes

When you leave the task.wait you can have a bindable function that checks if the game is still running.

1 Like

What if the “Rise_Lava” function runs and right after that there is no more players in round how would one stop the function?

1 Like

What am I exactly checking for tho?

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.

Here is how I use this:

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.

I still think there is simpler approach for my situation, I also have nothing to do with client since this is serverside issue