Files
aetherbound-guild/runtime/tests/p9_0r1_capture_test.gd
T

135 lines
3.9 KiB
GDScript

extends SceneTree
const MainScene = preload("res://main.tscn")
const STATES := [
"title",
"yard_empty",
"yard_front",
"yard_ready",
"battle_pressure",
"victory",
]
var output_root := ""
var viewport_size := Vector2i(1280, 720)
var locale := "zh_CN"
var text_scale := 1.0
var failures: Array[String] = []
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
output_root = OS.get_environment("ABG_P9_0R1_CAPTURE_ROOT")
if output_root.is_empty():
output_root = "/tmp/abg-p9-0r1-captures"
viewport_size = Vector2i(
read_int("ABG_P9_0R1_VIEWPORT_WIDTH", 1280),
read_int("ABG_P9_0R1_VIEWPORT_HEIGHT", 720)
)
locale = read_string("ABG_P9_0R1_LOCALE", "zh_CN")
text_scale = read_float("ABG_P9_0R1_TEXT_SCALE", 1.0)
DirAccess.make_dir_recursive_absolute(output_root)
var viewport := SubViewport.new()
viewport.size = viewport_size
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
root.add_child(viewport)
var game := MainScene.instantiate()
game.auto_boot = false
viewport.add_child(game)
await settle()
game.locale = locale
game.text_scale = text_scale
game.reduced_motion = true
game.muted = true
game.boot_verified = true
for index in range(STATES.size()):
await capture_state(viewport, game, index + 1, STATES[index])
game.queue_free()
viewport.queue_free()
await drain_cleanup()
if failures.is_empty():
print("ABG_P9_0R1_RUNTIME_CAPTURE_OK frames=6 viewport=%sx%s locale=%s text_scale=%.1f renderer=normal input_claim=none root=%s" % [viewport_size.x, viewport_size.y, locale, text_scale, output_root])
call_deferred("finish", 0)
else:
for failure in failures:
push_error(failure)
call_deferred("finish", 1)
func finish(exit_code: int) -> void:
quit(exit_code)
func capture_state(viewport: SubViewport, game: Control, index: int, state_name: String) -> void:
game.clear_experience()
apply_state(game, state_name)
game.render()
await settle()
await RenderingServer.frame_post_draw
var image := viewport.get_texture().get_image()
var path := output_root.path_join("%02d-%s.png" % [index, state_name])
var error := image.save_png(path)
if error != OK:
failures.append("capture %s failed with %s" % [state_name, error])
func apply_state(game: Control, state_name: String) -> void:
match state_name:
"title":
game.page = game.AppPage.TITLE
"yard_empty":
game.page = game.AppPage.YARD
game.notice = game.tr_text("先选前排:盾卫更稳,游侠更灵活。", "Choose the front: Guardian is steady, Runner is agile.")
"yard_front":
game.page = game.AppPage.YARD
game.front_choice = "Hearthguard"
game.notice = game.tr_text("艾连进入前排。现在选择一名后排。", "Elian joined the front. Now choose a rear role.")
"yard_ready":
game.page = game.AppPage.YARD
game.front_choice = "Hearthguard"
game.rear_choice = "Farstring"
game.notice = game.tr_text("妮娅进入后排。队伍已准备好。", "Nia joined the rear. The squad is ready.")
"battle_pressure":
game.page = game.AppPage.BATTLE
game.front_choice = "Hearthguard"
game.rear_choice = "Farstring"
game.battle_playing = false
game.battle_phase = 2
game.front_hp = 82
game.enemy_hp = 100
"victory":
game.page = game.AppPage.VICTORY
game.front_choice = "Hearthguard"
game.rear_choice = "Farstring"
game.front_hp = 82
game.enemy_hp = 0
func read_string(key: String, fallback: String) -> String:
var value := OS.get_environment(key)
return value if not value.is_empty() else fallback
func read_int(key: String, fallback: int) -> int:
var value := OS.get_environment(key)
return int(value) if not value.is_empty() else fallback
func read_float(key: String, fallback: float) -> float:
var value := OS.get_environment(key)
return float(value) if not value.is_empty() else fallback
func settle() -> void:
for frame in range(10):
await process_frame
func drain_cleanup() -> void:
for frame in range(120):
await process_frame