extends "res://tests/ui/test_first_operating_day.gd" ## Two-process natural opening/three-close debug flow. The Python runner supplies ## an isolated slot and evidence directory; never use ordinary player saves. var _handoff_done := false func _run() -> void: if OS.get_environment("THE_TREE_OPENING_RESTART_SLOT").is_empty(): push_error("Restart runner must supply its isolated save slot") quit(1) return if "--read" not in OS.get_cmdline_user_args(): await super._run() return _clock = root.get_node("GameClock") _runtime = root.get_node("SimulationRuntime") var state: Variant = root.get_node("GameState") _clock.reset(1, 6, 0) state.reset() _runtime.initialize(_clock, state, 424242) _clock.set_paused(true) root.size = Vector2i(1440, 810) _main = load("res://scenes/main/main.tscn").instantiate() _main.set("manual_save_path", OS.get_environment("THE_TREE_OPENING_RESTART_SLOT")) root.add_child(_main) _runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false}) await process_frame await process_frame _guide = _main.find_child("InnOpeningGuide", true, false) _ledger = _main.find_child("OperatingLedgerPanel", true, false) _load_handoff() await _continue_to_third_close() var expected: Variant = JSON.parse_string(FileAccess.get_file_as_string(_evidence_path("expected.json"))) _expect(expected is Dictionary, "previous process retained expected continuation evidence") if expected is Dictionary: _expect(_gameplay_digest() == expected.get("gameplay_digest"), "fresh process reproduces full gameplay snapshot through third close") _expect(JSON.stringify(_runtime.operations_coordinator.get_day_summaries()) == expected.get("closes_json"), "all three financial reports exactly match uninterrupted continuation") await _capture_restart("restarted-third-close") if _failures == 0: SaveService.delete_save(OS.get_environment("THE_TREE_OPENING_RESTART_SLOT")) super._finish() func _finish() -> void: if _failures > 0 or _handoff_done: super._finish() return _handoff_done = true _main.set("manual_save_path", OS.get_environment("THE_TREE_OPENING_RESTART_SLOT")) var selected_id: StringName = _runtime.facility_service.get_instances()[0].instance_id _main.call("_on_facility_selected", selected_id) var selection_file := FileAccess.open(_evidence_path("selection.json"), FileAccess.WRITE) selection_file.store_string(JSON.stringify({"id": String(selected_id)})) selection_file.close() var found_save := false for node: Node in _main.find_children("*", "Button", true, false): if node.text == "保存": node.pressed.emit() found_save = true break _expect(found_save, "save through the normal dashboard button") _load_handoff() await _capture_restart("saved-second-morning") await _continue_to_third_close() var file := FileAccess.open(_evidence_path("expected.json"), FileAccess.WRITE) _expect(file != null, "continuation evidence can be retained") if file != null: file.store_string(JSON.stringify({"gameplay_digest": _gameplay_digest(), "closes_json": JSON.stringify(_runtime.operations_coordinator.get_day_summaries())}, "\t") + "\n") file.close() await _capture_restart("uninterrupted-third-close") super._finish() func _load_handoff() -> void: var menu := _main.find_child("SaveLoadMenu", true, false) as MenuButton _expect(menu != null and not menu.disabled, "normal load menu is available") if menu != null and not menu.disabled: menu.get_popup().id_pressed.emit(0) _expect(_clock.absolute_minute == 1920, "disk load restores the second morning at08:00") _expect(_guide.get_progress().get(&"stage") == &"complete", "restarted UI recognizes completed opening") var selection: Dictionary = JSON.parse_string(FileAccess.get_file_as_string(_evidence_path("selection.json"))) _expect(String(_main.get("_selected_entity_id")) == selection["id"], "disk load restores the facility selected when saving") _expect(_main.get("_selected_entity_kind") == &"facility", "disk load restores the selection type") _expect(String(_main.get("world_preview").selected_entity_id) == selection["id"], "disk load restores the selected facility highlight") func _continue_to_third_close() -> void: await _advance(4320 - _clock.absolute_minute) _expect(_clock.absolute_minute == 4320, "natural operation reaches third midnight") var summaries: Array = _runtime.operations_coordinator.get_day_summaries() _expect(summaries.size() == 3, "three calendar closes exist exactly once") for summary: Dictionary in summaries: _expect(summary.get(&"balanced", false), "every operating close reconciles with the ledger") var report: Dictionary = _runtime.get_operations_report() _expect(not report.get(&"runtime_failure_latched", true), "no simulation failure after multi-day continuation") _expect(_ledger.get_report().get(&"selected_close") == summaries.back(), "dashboard presents latest third-day report") var detail: String = _ledger.get("_facility_label").text _expect(not detail.contains("facility_"), "completed infrastructure has human-readable ledger names") for definition_id: StringName in [&"guest_stairs", &"guest_corridor"]: var definition: FacilityDefinition = _runtime.definition_registry.get_facility(definition_id) _expect(detail.contains(definition.display_name), "ledger identifies charged infrastructure: %s" % definition.display_name) func _gameplay_digest() -> String: var snapshot: Dictionary = _runtime.create_snapshot() # SAVE_LOADED contains measured elapsed time, which differs by process. # Preserve ID counters, RNG streams and every other gameplay subsystem. snapshot[&"systems"][&"runtime"].erase(&"domain_events") var phase := "read" if "--read" in OS.get_cmdline_user_args() else "write" var evidence := FileAccess.open(_evidence_path(phase + "-gameplay.json"), FileAccess.WRITE) if evidence != null: evidence.store_string(JSON.stringify(snapshot, "\t") + "\n") evidence.close() return SimulationDigest.compute(snapshot) func _evidence_path(name: String) -> String: return OS.get_environment("THE_TREE_OPENING_RESTART_OUTPUT").path_join(name) func _capture_restart(name: String) -> void: if DisplayServer.get_name() == "headless": return _main.call("_refresh_dashboard") await process_frame await RenderingServer.frame_post_draw _expect(root.get_texture().get_image().save_png(_evidence_path(name + ".png")) == OK, "capture restart flow: " + name)