Introduction
I have a round-base game which depends on a timer for each round. I want the client to be able to see how long until the round is over, thus I created an IntValue in ReplicatedStorage which has the os.time() constant as to when the game is meant to end.
The server side looks like this, where game_end is the IntValue
function set_timer(t)
if game_end then
local future_time = (t~=0 and (os.time() + tonumber(t))) or 0
game_end.Value = future_time
else
warn("GameEnd timer IntValue not found inside ReplicatedStorage -> GameController/SetTimer")
end
end
Then, on the Client, inside of a StarterGui, I have this code:
local GameEnd = game.ReplicatedStorage:WaitForChild("GameEnd")
local Clock = script.Parent.Clock
local ClockRunner
ClockRunner = coroutine.create(
function()
while wait(1) do
local secondsLeft = os.difftime(GameEnd.Value, os.time())
local function SecondsToStamp(Seconds)
if Seconds<=0 then return "0:00" end
return string.format("%d:%.2d", Seconds / 60, Seconds % 60)
end
local format = SecondsToStamp(secondsLeft)
Clock.Text = (" Time Left: "..format)
if format == "0:00" then if coroutine.isyieldable(ClockRunner) then coroutine.yield(ClockRunner) end break end
end
end
)
GameEnd:GetPropertyChangedSignal("Value"):Connect(function()
if os.difftime(GameEnd.Value-os.time()) > 0 then
coroutine.resume(ClockRunner)
end
end)
The first time the value is changed, the timer works and we get this effect. However, the second time it runs, the coroutine isn't resumed and the timer does not work.
How can I properly do this?
How can I resume this coroutine, seeing that it's not doing so?

7 comments
I'm not 100% inclined when it comes to coroutines so I will not submit a formal answer. However, have you tried to wrap() the coroutine and call it like a function when it needs to be resumed? Wrap is the same as create, except wrap returns a function that resumes the coroutine each time it is called
local newcour = coroutine.wrap(function() print("Wrap") end) newcour()
yes but what if I need to yield it @WizyTheNinja?
I tried it, didn't work :/
Well it looks like you are just yielding when the timer is over, and starting back up when the timer resets. Running Wrap() will run the function until the code is done, on a seperate thread. It's really no different than running just a straight function, other than the fact that the rest of your script will still run even if the coroutine is. If I am right on my guess, you just need to call
the wrap() function everytime the timer resets, instead of yielding it until it does.
Hmm. Let me debug around with it and see if I can get a working code going.