Restart A coroutine

Hey! Im making a weather thing for a game and i use a coroutine to manage the timer. Theres an option to restart the weather, but I don’t understand how to make the coroutine stop and then play again.

Is there a better way to do this? It does not have to be coroutines, it just needs to be able to restart

Example code: (i wrote this on the spot not in studio, so if theres any errors/ inconsistencies, thats why)

local weatherFunction = coroutine.wrap(function()
    while true do
        weather = 1
        wait(250)
        weather = 2
        wait(250)
    end
end)
weatherFunction()

game.ReplicatedStorage.RestartWeather.OnServerEvent:Connect(function(player)
    --restart weather
end)

If you have any questions, ask! All help is appreciated!

2 Likes

Maybe add a bool for the loop? like

while process do

1 Like

Use coroutine.resume()

coroutine.resume(weatherFunction)

2 Likes

You can’t use coroutine.resume() with coroutine.wrap(). You have to use coroutine.create() to use coroutine.resume() and coroutine.yield().

2 Likes

This works except one thing. coroutine.yield(coroutine) doesn’t seem to work outside of a coroutine : (
How do in fix?

Take into account what @ Delexory said.

1 Like

The only way I could use it, is if I changed the “process” value back right after to restart it, but it doesn’t actually stop it. :frowning:

And how does the code you used look like?

1 Like

Something like this to add onto the example

local process = true
local weatherFunction = coroutine.wrap(function()
    while process do
        weather = 1
        wait(250)
        weather = 2
        wait(250)
    end
end)
weatherFunction()

game.ReplicatedStorage.RestartWeather.OnServerEvent:Connect(function(player)
    process = false --stop
    wait(1)
    process = true --has to be true to restart
    weatherFunction()
end)

The coroutine.create seems to be better than what I tried with this, so I went back to it.
I think it doesnt restart because of the waits and how the process is true before the waits end?

Initialize a variable weatherOn. We’re going to use this to keep track of the state of weather.

Declare it inside of the coroutine and set it to true.

In your connection, set weatherOn to false and run the coroutine.

local weatherOn;

local weatherFunc = coroutine.wrap(function()
    weatherOn = true;

    while (weatherOn) do
        ...;
    end
end)

weatherFunc();

...:Connect(function()
    weatherOn = false;
    weatherFunc();
end)

Let me know what happens.

1 Like

After a bit of experimenting, I’ve been getting 2 errors that have stopped me from really testing this.
They are:
attempt to call a nil value (this has no context, lines for code, or anything)
and
cannot resume dead coroutine (On the line where it calls the coroutine the 2nd time where it sets the weatherOn to false.

I searched the second one up and I found somewhere that said to put the coroutine into a function and call it there. (this post)
However, when I tried this, it still didn’t stop the coroutine, so Im guessing it had to do with that

It seems coroutines created by coroutine.wrap can only be called once. Try switching related content:

local weatherOn;

local weatherFunc = coroutine.create(function()
    weatherOn = true;

    while (weatherOn) do
        ...;
    end
end)

coroutine.resume(weatherFunc);

...:Connect(function()
    weatherOn = false;
    coroutine.resume(weatherFunc);
end)
1 Like

Ah yeah, I’ve had it like that ealier, but I changed it back and forgot about it. :sweat_smile:

This fixes the cannot resume dead coroutine issue, however the attempt to call a nil value error still occurs.
Ive done some testing, and it only happens when the line with weatherOn = false is present. I’m pretty sure if this error gets fixed, Itd be how I need it to be!
Ive tried a few things with my code to fix it, but so far it hasn’t worked. Im gonna try to search it up more and see if I can fix it. Thanks for your help so far! If you know how to fix it, please let me know.

Edit: After a bit more testing, I relized the error always happens after the cide finishes in the coroutine.