10 June 2023

Timers in Godot Loops

How to *correctly* add a timer delay within a while loop in Godot

For the past week, I’ve been trying to implement what felt like a relatively easy task - add a time delay within a loop withing GDScript.

The problem that I was trying to solve was that I’d like to update a label node with the outcome of each iteration of a while loop. For the user, seeing each iteration individually is important - and without a delay, we go through 1,000+ iterations in a second.

Because GDScript is very pythonic, I was expecting something relatively easy like Time.Sleep(). Searching around, I would get the same answer - use:

yield(create_timer().start(1.0),"timeout") 

And while that seemed like it should work, it would fail every time.

For example, this was my first implementation:

My expectation was that each time simulateDown() would run, the program would wait 1 second. So the print values would be:

simulateQuarter
simulateDrive
simulateDown
(wait 1 second)
simulateDown
(wait 1 second)
etc

Instead, I got all the print statements all at once with no delay. I was incredibly confused. A little bit of research into coroutines and this YouTube vide where the ‘ah ha’ moments for me.

Specifically, the way that “yield” works in GDscript is that it sends back a paused state back to the caller. So in the case of the above implementation, simulateDown() doesn’t actually finish running - it gets sent back to line 18 in a paused state and the line 17 while loop continues to run.

The key we need is that we need for simulateDown() to finsh running fully before continuing through the while loop.

The GDscript documentation called out that you can also use yield to wait for a signal (similar to what we’re doing in line 24) - and that each function has a “completed” signal. I modified the original script to include more yield statements that yielded for function complete and - voilà, that worked!

Coroutines and yields were a hard thing to get my head around - but hopefully this is helpful for anyone looking to add some timer delay in their loops.

Categories

Game Dev