extends SceneTree ## Run against the distributed pack, not the source checkout: ## godot --headless --main-pack /absolute/TheTree.pck --script /absolute/this_script.gd var _failures := 0 var _checks := 0 func _initialize() -> void: call_deferred("_run") func _run() -> void: var runtime: Variant = root.get_node("SimulationRuntime") var clock: Variant = root.get_node("GameClock") clock.set_paused(true) runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false}) if OS.get_environment("THE_TREE_REQUIRE_EXPORTED") == "1": _expect(not FileAccess.file_exists("res://project.godot") and not FileAccess.file_exists("res://data/facilities/reception.tres"), "release regression has no source checkout fallback") print("RECEPTION_RESOURCE file=%s resource=%s" % [FileAccess.file_exists("res://data/facilities/reception.tres"), ResourceLoader.exists("res://data/facilities/reception.tres")]) _expect(runtime.definition_registry.is_valid(), "exported facility definitions validate: %s" % runtime.definition_registry.get_report()) _expect(runtime.definition_registry.facility_count() == 23, "all 23 buildable definitions are present in the shipped pack") var main: Control = load("res://scenes/main/main.tscn").instantiate() root.add_child(main) runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false}) await process_frame await process_frame var buttons: Dictionary = main.get("build_buttons") _expect(buttons.size() == 23, "the actual build palette exposes all 23 facilities") _expect(buttons.has(&"reception"), "reception is selectable in the actual build palette") if not buttons.has(&"reception"): _finish() return _expect("受付" in buttons[&"reception"].text and not buttons[&"reception"].disabled, "reception button is labeled and enabled") var guide: Variant = main.find_child("InnOpeningGuide", true, false) _expect(guide != null and guide.get_progress().get(&"action") == &"build_reception", "new-game guide offers reception construction") if guide != null: (guide.get("_action") as Button).pressed.emit() await process_frame _expect(main.get("palette_scroll").visible and buttons[&"reception"].is_visible_in_tree(), "guide action opens the palette with a visible reception button") buttons[&"reception"].button_pressed = false buttons[&"reception"].button_pressed = true _expect(main.get("_selected_definition_id") == &"reception", "the reception button selects the real construction tool") main.call("_on_map_cell_clicked", Vector3i(-8, 0, 0)) _expect(runtime.construction_service.get_jobs().size() == 1, "map placement starts one real reception construction job") _expect(runtime.economy_service.get_balance(&"PLAYER_CASH") == 4500, "reception construction charges the actual 500 G cost") clock.advance_minutes(120) var reception: Variant = null for facility: Variant in runtime.facility_service.get_instances(): if facility.definition_id == &"reception": reception = facility _expect(reception != null, "the reception completes from the exported game data") _expect(guide != null and guide.get_progress().get(&"stage") == &"room", "opening guide advances to building a room") (main.get("guest_count_label") as Button).pressed.emit() await process_frame var observer: Variant = main.get("guest_observer") _expect(observer != null and observer.visible, "shipped HUD opens guest observation") var guest_panel: Variant = observer.find_child("GuestObservationPanel", true, false) if observer != null else null _expect(guest_panel != null and guest_panel.bars.size() == 4, "shipped observation includes all four need bars") if observer != null: observer.hide() await _check_original_facilities(main, runtime, clock) if OS.get_environment("THE_TREE_EXPORT_CAPTURE") == "1": main.call("_refresh_dashboard") await process_frame await RenderingServer.frame_post_draw root.get_texture().get_image().save_png(OS.get_environment("THE_TREE_EXPORT_CAPTURE_PATH")) _finish() func _expect(ok: bool, label: String) -> void: _checks += 1 if not ok: _failures += 1 print("%s: %s" % ["PASS" if ok else "FAIL", label]) func _finish() -> void: print("Exported opening: %d checks, %d failures" % [_checks, _failures]) quit(1 if _failures else 0) func _check_original_facilities(main: Control, runtime: Variant, clock: Variant) -> void: var buttons: Dictionary = main.get("build_buttons") for entry: Dictionary in [ {&"id": &"premium_room", &"origin": Vector3i(-8,2,0), &"size":Vector2i(4,1), &"upkeep":5}, {&"id": &"warehouse", &"origin": Vector3i(-8,0,1), &"size":Vector2i(4,2), &"upkeep":3}, {&"id": &"staff_dormitory", &"origin": Vector3i(-8,2,1), &"size":Vector2i(2,1), &"upkeep":4}, ]: var definition: Variant = runtime.definition_registry.get_facility(entry[&"id"]) _expect(definition != null and definition.footprint == entry[&"size"] and definition.maintenance_gold == entry[&"upkeep"], "packed original geometry and upkeep: %s" % entry[&"id"]) if definition == null or not buttons.has(entry[&"id"]): return buttons[entry[&"id"]].button_pressed = false buttons[entry[&"id"]].button_pressed = true _expect(main.get("_selected_definition_id") == entry[&"id"] and main.get("world_preview").layer_mode == entry[&"origin"].z, "packed palette selects correct facility/layer: %s" % entry[&"id"]) main.call("_on_map_cell_clicked", entry[&"origin"]) clock.advance_minutes(definition.build_minutes) var found := false for facility: Variant in runtime.facility_service.get_instances(): if facility.definition_id == entry[&"id"]: found = facility.occupied_cells.size() == entry[&"size"].x * entry[&"size"].y _expect(found, "packed construction completes correct occupied cells: %s" % entry[&"id"]) var path := "user://tests/export_original_%d" % Time.get_ticks_usec() var snapshot: Dictionary = runtime.create_snapshot() _expect(runtime.save_to_path(path)[&"ok"], "packed runtime writes completed original facilities") clock.advance_minutes(3) var loaded: Dictionary = runtime.load_from_path(path) var restored: Dictionary = runtime.create_snapshot() var expected_runtime: Dictionary = snapshot[&"systems"][&"runtime"] var restored_runtime: Dictionary = restored[&"systems"][&"runtime"] var events: Dictionary = restored_runtime[&"domain_events"] var last: Dictionary = events["recent_events"].back() _expect(loaded[&"ok"] and last["event_type"] == &"SAVE_LOADED" and events["published_ids"].size() == expected_runtime[&"domain_events"]["published_ids"].size()+1, "load publishes exactly one successful lifecycle event") # Loading intentionally appends SAVE_LOADED; all other saved gameplay state # must match, including every ID counter except this one new event. expected_runtime[&"domain_events"] = events expected_runtime[&"id_generator"]["counters"]["domain_event"] += 1 _expect(restored == snapshot, "packed runtime restores complete gameplay state with only the load event added") SaveService.delete_save(path) _expect(main.find_child("SaveLoadMenu", true, false) != null, "packed UI includes migrated-save load menu")