Hello!
I’m doing some procedural generation in tilemaps in Godot and it requires some nested loops and stuff that can take a while to run - not super long yet, but perhaps ten seconds.
Now before game dev I used to write stuff in Python, and for this case I wrote myself a progress bar that I can plug into the for loop, that updates the progress bar every loop iteration - both so I can confirm new code is doing something and to see if it will complete in reasonable time.
So I tried to implement this in Godot but figured it does not work because the for loop runs in a single frame and thus the game just freezes until the loop is done.
Im just at the beginning of my generation, the waiting times will get longer - is there a way to circumvent or possibly override the single frame for loop to update the progress on screen?
Most preferred would be a reusable solution, one that I can plug into any for loop. In python I would start my timer function once before the loop starts, initializing it with the loop length and then call update once per loop iteration.
Yeah, the way I’d generally go about this is to do one iteration per frame. Here’s some relevant documentation, and an example:
# we could have this function connected to a signal
func _on_some_event():
do_slow_computation()
# or we could look for some condition in _process
func _process(_delta):
if some_condition:
do_slow_computation()
# don't do the computation again right away
some_condition = false
func do_slow_computation():
for x in range(100):
print("doing stuff")
# wait for next frame
await get_tree().process_frame
The idea is that because do_slow_computation uses await, it becomes a coroutine, and if we call it without awaiting it, it’ll simply run concurrently with the main thread, doing its thing. It’s important that we don’t await directly in _process - we typically do not want the _process function to be a coroutine.