Stopping a function from another function

Is it possible to stop a function from within another function? This is something that I kind of need to do for a script, and I don’t even know if it’s possible. If it is possible, how do you do it? For example, If I have

local function yes()
wait(10)
end

local function no()
--deactivation script
end

What could I put in the function no to deactivate and reset the wait switch in yes?

1 Like

Use coroutines so that you can run a function from a new thread and yield the thread whenever from another function. If it’s something that doesn’t need instantaneous pausing then the method could vary on the situation.

2 Likes

Sorry, I wasn’t very specific. I want to stop and reset the function, so that if it’s called again it doesn’t start from where it left off, instead it starts at the beginning. Is that possible?

Yes then you could yield the thread and then start a new one :slight_smile:

Also found a forum post similary to what you’re looking for here.

2 Likes

Oh, I didn’t realize that… Thanks!

I still cant figure this out… Here’s my code.

local indicator = script.Parent
local prompt = indicator:WaitForChild("L1P2_Prompt")
local breaksender = script.L1P2_Broken
local player = nil
local countdownStopper = nil

local function countdown()
	countdownStopper.running = true
	while countdownStopper do
		wait(10)
		print "Dead"
		prompt.Enabled = false
		prompt.ActionText = "Break"
		breaksender:Fire()
	end
end

countdownStopper = coroutine.create(countdown)

local function countdownDisabler()
	countdownStopper.running = false
end

prompt.Triggered:Connect(function(plr)
	if player ~= plr then
		player = plr
	end
	if prompt.ActionText == "Break" then
		prompt.ActionText = "Fix"
		countdown()
	else
		prompt.ActionText = "Break"
		countdownDisabler()
	end
end)

Does anyone know what’s going on? In the official tutorial website, the running part exists, but I get an error from it every time.

local indicator = script.Parent
local prompt = indicator:WaitForChild("L1P2_Prompt")
local breaksender = script.L1P2_Broken
local player = nil
local countdownStopper = nil

local function countdown()
	coroutine.resume(countdownStopper)
	while coroutine.status(countdownStopper) = "running" do
		wait(10)
		print("Dead")
		prompt.Enabled = false
		prompt.ActionText = "Break"
		breaksender:Fire()
	end
end

countdownStopper = coroutine.create(countdown)

local function countdownDisabler()
	coroutine.yield(countdownStopper)
end

prompt.Triggered:Connect(function(plr)
	if player ~= plr then
		player = plr
	end
	if prompt.ActionText == "Break" then
		prompt.ActionText = "Fix"
		countdown()
	else
		prompt.ActionText = "Break"
		countdownDisabler()
	end
end)

Use this perhaps?

Also, if that doesn’t work, consider using a boolean. So the countdown would only run if that bool is true/false

The first thing didn’t work.

If you mean putting the boolean in a while loop, that doesn’t work. I know this because that was the first thing I tried with the boolean value. Also, I’d rather not have an if statement at the end because, due to the way the game works, someone could press the button 3 times in quick succession and the countdown would not stop. This is because when someone presses the button once, it activates the first function, however, when the button is pressed a second time, it’s supposed to deactivate it. Putting an if statement at the end would just reset it after the countdown finishes, which wouldn’t be good. However, if you did not mean either of these things, I’m not sure I understand what you meant.

I meant something like:

local running = false

local function PrintOk()
	running = true
	while running == true do
       wait(1)
       print("ok")
	end
end

PrintOk()

-- and then you would turn running to false somewhere else in your script to make the countdown stop

That’s the first thing I tried, but it didn’t stop the function when the boolean I used instead of running was changed to false.

Can you please describe the use case of the system you are trying to create, or is this just a theory test?

1 Like

There is a huge machine. There are also two teams, the Breakers and the Fixers. The Breakers must reach the panels located around the machine and break their circuits, while the Fixers must undo their actions. Basically, someone from the Breaker team will break the panel, and if a Fixer doesn’t repair it within 10 seconds, the panel breaks. Once all panels are broken, the game enters sudden death, where the core of the machine must be destroyed. At this point, the Breakers have pretty much won. However, if time runs out in either section, the Fixers win. The reason I need to stop a function from another function is so that I can disable a Wait() command activated by the Breaker team so that the panel doesn’t break when the Fixers fix it.

EDIT: That was probably too much information…

1 Like

Ok so let me get this straight – cause the better I understand this, the better I explain an approach I would take.

Two teams: Breakers, Fixers.
Objects: Circuit, Machine

Uses: PromptService for Breaking/Fixing

Gameplay Loop:

  1. Breakers disable all circuits.
  2. Fixers repair broken circuits.
  3. If all circuits broke, Fixers have 10 seconds to Repair; Breakers do nothing here.
  4. If repaired in time, countdown is disabled.
  5. If fixers run down the clock, they also win.
1 Like

Yes, that is correct. I know it’s probably boring but I’m a beginner so I’ve got to start somewhere :man_shrugging:
Also, the countdown resets. I don’t know if that was included in the disabled, but that’s an important part.

1 Like

I’m writing an example of what I would do for handling this right now, you are welcome to message me on discord though in the mean time. TechSpectrum#2620

1 Like

I don’t have discord… Thanks for the help by the way!

I didn’t run this through a test since it’s an example for you to read through and understand a concept.

local DEFAULT_GAME_TIME = 1800
local DEFAULT_BROKENDOWN_TIME = 10

local RoundTime = DEFAULT_GAME_TIME
local RoundActive = true

local BrokenDownTime = DEFAULT_BROKENDOWN_TIME
local BrokenDown = true

function RoundEnded(winner)
	RoundActive = false
	print(winner)
	wait(5)
end

coroutine.wrap(function()
	while wait(1) do
		if RoundActive then
			RoundTime = RoundTime - 1
			if BrokenDown then
				BrokenDownTime = BrokenDownTime - 1
			else
				BrokenDownTime = DEFAULT_BROKENDOWN_TIME
			end
			-- DID THE GAME END???
			local fixersWin = RoundTime <= 0
			local breakersWin = BrokenDownTime <= 0
			if fixersWin then
				RoundEnded("Fixers")
			elseif breakersWin then
				RoundEnded("Breakers")
			end
		else
			-- RESTART THE GAME
			RoundActive = true
			RoundTime = DEFAULT_GAME_TIME
			BrokenDownTime = DEFAULT_BROKENDOWN_TIME
		end
	end
end)()

Basically, you have a single coroutine that manages the gameplay state that keeps running.

You don’t need to stop anything, you just simply reset the timer within the coroutines loop itself.

1 Like

I’m sorry, but this isn’t what I was looking for. There are multiple panels, and I have posted my current code above. The code you have posted is something that I already have an idea for, and the issue does not lie there. Basically, there will be a counter that goes up every time a panel is destroyed, and if the counter reaches a certain point (The amount of panels,) then the Breakers win. I already have the code for the Fixer win. If you look at my code, there is a top function and a bottom function. The top function activates when a Breaker interacts with the panel, while the bottom one activates when a Fixer interacts with the panel. What I need to do is take a signal from the bottom function which disables the top function. Sorry about that.

EDIT: I can probably take what was used in there and use it to fix my script.

It sounds like the same solution to me, I just didn’t code an example for the events you mentioned because it’s self implied to you add your own logical check.

I still don’t see why this needs anything but a single timer in one coroutine running on a loop.

Yup, sorry. I was just being a bit dumb. I understand how I can use it now and I will implement it into my script.

1 Like