await pauses a function until a signal fires. The rest of the game keeps running, and the function continues on the next line when the signal arrives:
func show_message(text: String) -> void:
$Label.text = text
$Label.show()
await get_tree().create_timer(2.0).timeout # wait 2 seconds
$Label.hide()
That one line replaces a Timer node, a connected signal and a separate handler function. The example needs a running game for its two seconds, so the runnable blocks below wait for signals and frames instead.
Waiting for a Signal
Any signal can be awaited. The value of await is the signal's argument:
Left or right?
You chose left
ask_player() paused at await answered and resumed when the signal fired. Because ask_player() contains await, it is a coroutine, and _ready() must await it too to get its result.
Coroutines Return to Their Caller
When a coroutine reaches await, it pauses and gives control back. A caller that does not await it carries on:
3
_ready keeps going
2, one frame later
This "fire and forget" call is useful for effects such as a flash that should not hold up the code that started it. If you need the coroutine's result, or need it to finish first, await it. Using its value without await is an error:
Parse Error: Function "countdown()" is a coroutine, so it must be called with "await".
await on a function that never pauses is fine: it returns its value at once.
Things You Can Await
await get_tree().create_timer(1.5).timeout # some time
await get_tree().process_frame # the next frame
await get_tree().physics_frame # the next physics step
await $AnimationPlayer.animation_finished # an animation
await create_tween().tween_property(self, "modulate:a", 0.0, 0.5).finished
await $Door.opened # your own signal
await some_coroutine() # another coroutine
A Cutscene with await
Several awaits in a row read like a script of events, which is what coroutines are good at:
func play_intro() -> void:
$Player.set_physics_process(false) # freeze controls
$Camera2D.position = $Castle.position
await get_tree().create_timer(1.0).timeout
$Dialog.say("The castle has fallen...")
await $Dialog.finished
$Camera2D.position = $Player.position
await get_tree().create_timer(0.5).timeout
$Player.set_physics_process(true)
Traps
- The node is gone. If the node running a coroutine is freed while it waits, the function never resumes, even when the signal fires later. The same happens when the object that owns the awaited signal is freed. Keep cutscenes on nodes that live long enough.
- Calling it twice. Each call is a separate coroutine. Pressing a button that starts
play_intro()twice runs two intros at once. Guard with a variable such asvar playing_intro := false. - Awaiting in
_process()._process()is called every frame regardless, so anawaitinside it starts a new paused copy each frame. Put timed sequences in their own function. - Timers and pause.
create_timer()keeps counting while the game is paused, because its second argument,process_always, defaults totrue. Passfalsefor a wait that should stop during the pause menu:create_timer(2.0, false).
Godot 3's yield
yield no longer exists in Godot 4:
| Godot 3 | Godot 4 |
|---|---|
yield(get_tree().create_timer(1.0), "timeout") | await get_tree().create_timer(1.0).timeout |
yield(self, "died") | await died |
yield(some_function(), "completed") | await some_function() |
Frequently Asked Questions
How do I wait a few seconds in Godot 4?
Write await get_tree().create_timer(2.0).timeout. The function pauses for 2 seconds while the game keeps running, then continues on the next line.
What replaced yield in Godot 4?
await. Godot 3's yield(get_tree().create_timer(1.0), "timeout") is now await get_tree().create_timer(1.0).timeout, and yield(self, "died") is await died.
What is a coroutine in GDScript?
Any function that contains await. When it reaches an await, it pauses and returns control to its caller; it resumes when the awaited signal fires. To get its return value, the caller must await it as well.
Does await freeze the game?
No. Only the function that awaits pauses. The rest of the game, including _process() and other functions, keeps running. A while loop that waits, by contrast, does freeze everything.