Hello, I'm attempting to recreate a harvest moon style time system in my game. The way it works is every 14 seconds in real time count as 10 minutes in game and the user only gets notified that the time has changed in intervals of 10 minutes. I achieve that by making the timer count in intervals of 1.4s and when its timeout signal is sent, it increases the minute count by 1. The main purpose of the coroutine is to have a reliable and constant time flow that can also be paused if needed.
var timeFlow: float = 1.4
func setTimeFlow(newValue: bool):
flowStatus = newValue
if (flowStatus):
print("starting time flow")
timeCoroutine()
func timeCoroutine():
while flowStatus:
yield(get_tree().create_timer(timeFlow), "timeout")
#exit the while loop if the game is paused
if not flowStatus:
print("pausing time flow")
break
updateTime()
updateTimeUIValues()
emit_signal("time_changed")
func updateTime():
minute += 1
# 60 minutes in an hour
if (minute >= 60):
#reset minute count
minute = 0
hour += 1
# 24 hours in a day
if (hour >=24):
#reset hour count
hour = 0
day += 1
# 30 days in a season
if (day >= 30):
# reset day count
day = 1
Whenever I start the game I set the flowStatus variable to true which in succession triggers the coroutine to start and if the player pauses the game the same variable is set to false which exits the loop. The problem is, if a player decides to spam pause/unpause multiple instances of the coroutine would get called, all running simultaneously making the flow of time greatly accelerate.
My solution for this was implementing a variable called coroutineActive that would keep the coroutine from running multiple instances, it is set to true at the start of the loop and once the loop is completed it is set to false. The real issue is that I pretty much patched one hole and made another. Now the player is able to spam the pause/unpause key to slowly but surely walk in the game while preventing the time from flowing for majority of the period.
func setTimeFlow(newValue: bool):
flowStatus = newValue
if (flowStatus && !coroutineActive ):
print("starting time flow")
timeCoroutine()
func timeCoroutine():
while flowStatus:
coroutineActive = true
yield(get_tree().create_timer(timeFlow), "timeout")
#exit the while loop if the game is paused
if not flowStatus:
print("pausing time flow")
coroutineActive = false
break
updateTime()
updateTimeUIValues()
emit_signal("time_changed")
coroutineActive = false
The lazy way to fix this would be having a timer that runs the moment pause is pressed and if the player presses the pause/unpause a certain amount of times while the timer is active I could forcibly increase the current in game time. I'm just curious is there a potential better way to approach this issue? Maybe I'm just complicating it for no reason, any insight is appreciated!