extends SceneTree var failures: Array[String] = [] func _init() -> void: _run.call_deferred() func _run() -> void: var player := await _player_fixture() if player == null: _finish(null) return _set_beat_time(0.2) var basic_action: Resource = load("res://resources/actions/ground_attack_left_1.tres") player.call("_play_action_animation", "atk_ground_1", basic_action) var animation_player := player.get_node_or_null("AnimationPlayer") as AnimationPlayer if animation_player == null: failures.append("Player should include AnimationPlayer") else: _expect_float(float(animation_player.speed_scale), 1.75, 0.01, "AnimationPlayer actions should speed up to fit shortened beat durations") var smash_action: Resource = load("res://resources/actions/ground_smash_left.tres") player.call("_play_action_animation", "ground_smash", smash_action) player.call("_tick_manual_animation", 0.05) _expect_float(float(player.get("_manual_animation_time")), 0.1, 0.01, "Manual player action animation time should advance on the tempo-scaled action clock") _finish(player) func _player_fixture() -> Node: var scene: PackedScene = load("res://scenes/characters/player.tscn") if scene == null: failures.append("Player scene should load") return null var player := scene.instantiate() root.add_child(player) await process_frame return player func _set_beat_time(next_beat_time: float) -> void: var rhythm := root.get_node_or_null("RhythmManager") if rhythm == null: failures.append("RhythmManager autoload should exist") return rhythm.set("beat_time", next_beat_time) func _expect_float(actual: float, expected: float, tolerance: float, label: String) -> void: if absf(actual - expected) > tolerance: failures.append("%s: expected %.3f, got %.3f" % [label, expected, actual]) func _finish(player: Node) -> void: if player != null: player.free() if failures.is_empty(): print("PASS player action animation tempo") quit(0) else: for failure: String in failures: push_error(failure) quit(1)