extends SceneTree const Controller = preload("res://p10_2/runtime_controller.gd") const P101Controller = preload("res://p10_1/runtime_controller.gd") const Main = preload("res://main.gd") const BattleService = preload("res://p10_2/mid_contract_battle_service.gd") const SaveV8 = preload("res://p10_2/save_v8_service.gd") const Fixture = preload("res://tests/p10_2/mid_contract_fixture.gd") const VIEWPORT := Vector2i(844, 390) var failures: Array[String] = [] var experience func _initialize() -> void: call_deferred("run_test") func run_test() -> void: root.size = VIEWPORT root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND root.content_scale_size = VIEWPORT experience = Controller.new() experience.persistence_enabled = false experience.battle_auto_advance = false experience.locale = "zh_CN" experience.size = Vector2(VIEWPORT) experience.configure_entry(Fixture.new().migrated_snapshot()) root.add_child(experience) await settle_frames(12) expect(experience.p102_mode, "Save v8 activates the P10.2 runtime") expect(experience.screen == Controller.P102_SCREEN_MARKET, "Market 2 resumes as the first P10.2 world screen") expect(experience.find_children("P102RecruitTarget_*", "Button", true, false).size() == 3, "Market exposes three direct Recruit targets") expect(experience.find_children("P102EquipmentTarget_*", "Button", true, false).size() == 4, "Market exposes four direct equipment targets") expect(experience.find_children("P102RouteTarget_*", "Button", true, false).size() == 3, "Market exposes three direct route posts") var first_id := String(experience.region_market.state.current_run.deployed_recruit_ids[0]) experience.tap_region_company(first_id) experience.tap_region_company(first_id) await settle_frames() expect(first_id in experience.region_market.state.current_run.reserve_recruit_ids, "a direct Recruit target can move one member into visible Reserve") expect(experience.find_child("P102ReserveTarget_%s" % first_id, true, false) != null, "Reserve has its own world target") experience.tap_region_company(first_id) experience.tap_region_company(first_id) await settle_frames() expect(first_id in experience.region_market.state.current_run.deployed_recruit_ids, "the same Reserve target can return its Recruit to the Line") await clear_round(2, 2, "follow_tide", "drownseed_evaded", "P102DrownseedMarker") expect(experience.region_market.state.current_run.line_capacity == 5, "Round 2 visibly grows Line capacity to five") await clear_round(3, 1, "focus_source", "source_interrupted", "P102MedicPulse") await clear_round(4, 1, "guard_center", "center_guarded", "P102FogjawReveal") var run: Dictionary = experience.region_market.state.current_run expect(experience.screen == Controller.P102_SCREEN_MARKET_5, "three settlements reach stable Market 5") expect(run.cleared_rounds == 4 and run.line_capacity == 6, "Market 5 records four clears and capacity six") expect(run.reed_ferry_restored and experience.find_child("P102ReedFerryRestored", true, false) != null, "Ferry restoration changes the rendered world") expect(experience.find_children("P102Survivor_*", "TextureRect", true, false).size() == run.company.size(), "Market 5 renders every surviving Recruit") var encoded: Dictionary = SaveV8.new().encode_snapshot(experience.region_market.state.snapshot(), 40) var decoded: Dictionary = SaveV8.new().decode_text(String(encoded.get("text", "")), 40) expect(encoded.ok and decoded.ok and decoded.snapshot == experience.region_market.state.snapshot(), "visible Market 5 roundtrips through Save v8") experience.queue_free() await settle_frames(18) var game = Main.new() game.auto_boot = false game.p100_persistence_enabled = false root.add_child(game) await settle_frames() game.p100_experience = P101Controller.new() game.p100_experience.persistence_enabled = false game.p100_experience.size = Vector2(VIEWPORT) game.p100_experience.configure_entry(Fixture.new().p101_market_2_snapshot()) game.add_child(game.p100_experience) await settle_frames(12) expect(is_instance_valid(game.p102_handoff_button), "main exposes one Continue Round 2 command on saved P10.1 Market 2") if is_instance_valid(game.p102_handoff_button): game.p102_handoff_button.emit_signal(&"pressed") await settle_frames(12) expect(is_instance_valid(game.p102_experience), "main can hand a saved P10.1 Market 2 to the P10.2 runtime") if is_instance_valid(game.p102_experience): expect(game.p102_experience.p102_mode and int(game.p102_experience.region_market.state.current_run.market_index) == 2, "main handoff migrates into exact P10.2 Market 2") game.queue_free() await settle_frames(45) if failures.is_empty(): print("ABG_P10_2_CONTINUOUS_RUNTIME_OK markets=2,3,4,5 rounds=2,3,4 plans=follow_tide,focus_source,guard_center reserve=direct capacity=4,5,5,6 drownseed=event_bound medic=event_bound fogjaw=event_bound ferry=restored save_v8=stable main=handoff") quit(0) else: for failure in failures: push_error(failure) quit(1) func clear_round(market_index: int, risk: int, plan_id: String, event_kind: String, effect_node: String) -> void: expect(int(experience.region_market.state.current_run.market_index) == market_index, "Round %d starts at the matching Market" % market_index) var route: Dictionary = experience.region_market.state.current_run.market_board.battle_offers[risk] expect(String(BattleService.PREFERRED_PLAN[String(route.route_id)]) == plan_id, "Round %d fixture chooses its preferred plan" % market_index) experience.tap_region_route(String(route.offer_id)) experience.commit_region_route() await settle_frames() expect(experience.screen == Controller.P102_SCREEN_PLAN, "Round %d opens the four-plan screen" % market_index) expect(experience.find_children("P102PlanTarget_*", "Button", true, false).size() == 4, "Round %d presents four direct plan targets" % market_index) experience.choose_region_plan(plan_id) experience.advance_region_battle_ticks(999) await settle_frames() expect(experience.screen == Controller.P102_SCREEN_BATTLE and experience.region_battle_complete, "Round %d reaches visible battle result" % market_index) expect(int(experience.region_event_counts.get(event_kind, 0)) == 1, "Round %d consumes %s exactly once" % [market_index, event_kind]) expect(experience.find_child(effect_node, true, false) != null, "Round %d binds %s to a world effect" % [market_index, event_kind]) experience.settle_region_battle() await settle_frames() func settle_frames(count := 5) -> void: for _index in count: await process_frame func expect(condition: bool, message: String) -> void: if not condition: failures.append("P10.2 continuous runtime: %s" % message)