Await isn't working between classes

Topic on the same question is already exist, but I created this to give more structured context.

Godot Version

4.2.0

Contecst

I with my team making custom cutscene system. we have class Plot that contain and execute Command classes. Command class is basic class for different actions: Wait or PlayAnim foe example.
Plot executin every Command in func Run().
Right now we making feature, that will execute them in turn, waiting for execution of each. For that purpose we have await (something); return 0.
So we thought it will work like tis: await in for is waiting await of current executioning class and then executes necst. But forsome reason it didnt work

Plot.gd

class_name Plot

var _commands = []
var _cutscene

func _init(cutscene):
	_cutscene = cutscene

func Add(command : Command):
	_commands.append(command)

func _Reset(cutscene : Node):
	for node in cutscene.get_children():
		if node is PhantomCamera2D:
			node.set_priority(0)

func Run():
	for command : Command in _commands:
		await command.Execute(_cutscene)
	_Reset(_cutscene)

Command.gd

class_name Command

func Execute(cutscene : Node) -> int:
	return 0

PlayAnim.gd

class_name PlayAnim
extends Command

var _name # node name
var _anim # animation name
var _is_async # sets delay for waiting till its done

func _init(name,anim = "default",is_async = false):
	_name = name
	_anim = anim
	_is_async = is_async

func Execute(cutscene) -> int:
	for node in cutscene.get_children():
		if node is AnimationPlayer:
			if node.get_name() == _name:
				node.play(_anim)
				if(_is_async):
					await node.animation_finished
				return 0
	return 1

Wait.gd

class_name Wait 
extends Command 

var _time_sec # wait time


func _init(time_sec : int):
	_time_sec = time_sec

func Execute(cutscene : Node) -> int:
	await cutscene.get_tree().create_timer(_time_sec).timeout
	return 0

The problem

for in Run() is executing first Command but then it just ignoring others and game continues to running.
Why for is skipping others and how to make it work?
Or maybe for is still waiting for command to fully execute and rest of the game code is working as normal?

Is this initialized? Or just a simplified version of the code.

This is how await should work, it is a coroutine. it will not block and will return to the caller. If the caller has await it will return to the next caller, up the call stack. Until there is no await and will continue execution of the main loop.

(It is actually really bad to use await inside a process or physics function because it will create a new coroutine every frame.)

Exactly.

My follow up was going to be have you checked that the signal is happening.

I did also spot in your extension of command class in the animation class, is that the parameter isn’t typed as the base command class is.

It should be
func Execute(cutscene: Node) -> int

This is just an inconsistency not sure its the problem. ( Godot wont allow overriding, but that is technically a different function signature if it isn’t typed like command is )

i did a very rudementary test on 4.2.2 and it seems to work.

extends Node

var bc: = MyBaseClass.new()
var wait:= MyWait.new()

func _ready():
	add_child(bc)
	add_child(wait)
	print("starting ", Time.get_unix_time_from_system())
	var bcwait := wait as BaseClass
	await wait.Execute(null)
	await bcwait.Execute(null) 
	await bc.Execute(null)
	print("done     ", Time.get_unix_time_from_system())
	
class MyWait extends BaseClass:
	func Execute(node:Node)->int:
		await get_tree().create_timer(1.0).timeout
		print(name," timeout")
		return 0

class MyBaseClass extends Node :
	func Execute(node:Node)->int:
		return 0

image

There is probably something in your code that isn’t working as expected.

like get children is returning an empty array.