extends SceneTree class DenyingOperationsCoordinator: extends OperationsCoordinator func can_start_construction_or_investment() -> Dictionary: return { &"allowed": false, &"reason": &"ARREARS_REMAIN", &"arrears_total": 25, &"consecutive_insolvency_count": 1, } var _checks := 0 var _failures := 0 var _clock: Variant var _state: Variant var _runtime: Variant var _direct_command_id := 900_000 func _initialize() -> void: call_deferred("_run") func _run() -> void: print("MVP: Runtime content, hiring, and progression integration") _test_catalog_bootstrap_and_queries() _test_progression_resource_and_guest_facts() _test_catalog_staff_hire_transaction() _test_rank_two_three_and_atomic_failure() _test_v3_migration_and_v4_tamper_guards() _test_twenty_four_hour_replay() _cleanup() if _failures == 0: print("PASS: %d checks" % _checks) else: push_error("FAIL: %d of %d checks failed" % [_failures, _checks]) quit(_failures) func _reset_runtime(seed := 82_001) -> void: _cleanup() _clock = load("res://autoload/game_clock.gd").new() _state = load("res://autoload/game_state.gd").new() _runtime = load("res://autoload/simulation_runtime.gd").new() _clock.reset(1, 6, 0) _state.reset() var report: Dictionary = _runtime.initialize(_clock, _state, seed) _clock.set_paused(true) _expect(bool(report.get(&"valid", false)), "Runtime initializes with validated content and Progression") func _cleanup() -> void: if _runtime != null: _runtime.free() if _clock != null: _clock.free() if _state != null: _state.free() _runtime = null _clock = null _state = null func _test_catalog_bootstrap_and_queries() -> void: _reset_runtime(82_001) var report: Dictionary = _runtime.get_mvp_content_report() _expect(bool(report[&"valid"]), "MVP catalog report is valid") _expect(int(report[&"counts"]["guest_classes"]) == 8, "catalog exposes eight Guest classes") _expect(int(report[&"counts"]["species"]) == 4, "catalog exposes four independent species") _expect(int(report[&"counts"]["staff_candidates"]) == 20, "catalog exposes twenty fixed Staff candidates") _expect(int(report[&"counts"]["unique_characters"]) == 2, "catalog exposes both unique characters") var catalog_ids: Array[StringName] = _runtime.get_mvp_guest_definition_ids() _expect(catalog_ids.size() == 32, "Runtime registers every class/species Guest definition") _expect(_runtime.guest_service.get_definitions().size() == 35, "legacy three Guest definitions coexist with the 32 catalog definitions") var sorted_ids := catalog_ids.duplicate() sorted_ids.sort_custom(func(left: StringName, right: StringName) -> bool: return String(left) < String(right)) _expect(catalog_ids == sorted_ids, "Runtime catalog Guest IDs use stable canonical order") var all_registered := true for guest_type_id: StringName in catalog_ids: if _runtime.guest_service.get_definition(guest_type_id) == null: all_registered = false break _expect(all_registered, "all 32 catalog Guest definitions are queryable by stable ID") report[&"counts"]["guest_classes"] = 0 _expect(int(_runtime.get_mvp_content_report()[&"counts"]["guest_classes"]) == 8, "content report query is a defensive copy") var candidate: Dictionary = _runtime.get_mvp_staff_candidate_payload(&"staff_akane") (candidate[&"options"][&"skills"] as Dictionary)[&"service"] = -1 _expect( int(_runtime.get_mvp_staff_candidate_payload(&"staff_akane")[&"options"][&"skills"][&"service"]) == 68, "Staff candidate payload query is a defensive copy" ) var progression_report: Dictionary = _runtime.get_progression_report() (progression_report[&"snapshot"][&"metrics"] as Dictionary)["asset_gold"] = 0 _expect(int(_runtime.progression_service.metrics[&"asset_gold"]) == 5_000, "Progression report query is a defensive copy") func _test_progression_resource_and_guest_facts() -> void: _reset_runtime(82_002) var faith: CommandResult = _runtime.submit_command( &"change_resources", {&"deltas": {&"faith": 40}}, &"player", &"", 50, -1, &"mvp.progression.faith" ) _expect(faith.is_success(), "positive Faith resource change succeeds") _expect(_state.get_resource(&"faith") == 40, "positive Faith changes live GameState") _expect(int(_runtime.progression_service.metrics[&"faith_lifetime"]) == 40, "positive Faith increments lifetime progression atomically") var spawned: CommandResult = _runtime.submit_command( &"spawn_guest", { &"guest_id": &"catalog_guest_one", &"guest_type_id": _runtime.get_mvp_guest_definition_ids()[0], &"gold": 50, &"options": {&"current_cell": Vector3i.ZERO}, }, &"world", &"catalog_guest_one", 40, -1, &"mvp.progression.guest_one" ) _expect(spawned.is_success(), "catalog Guest can spawn through Runtime") _expect(int(_runtime.progression_service.metrics[&"guest_lifetime"]) == 1, "successful Guest spawn increments lifetime Guest count once") var duplicate: CommandResult = _runtime.submit_command( &"spawn_guest", { &"guest_id": &"catalog_guest_one", &"guest_type_id": _runtime.get_mvp_guest_definition_ids()[0], &"options": {&"current_cell": Vector3i.ZERO}, }, &"world", &"catalog_guest_one", 40, -1, &"mvp.progression.guest_duplicate" ) _expect(not duplicate.is_success(), "duplicate Guest spawn is rejected") _expect(int(_runtime.progression_service.metrics[&"guest_lifetime"]) == 1, "failed Guest spawn cannot increment lifetime progression") _expect( _runtime.progression_service.update_metrics({&"faith_lifetime": ProgressionService.MAX_SAFE_INTEGER}), "overflow rollback fixture reaches the maximum lifetime Faith" ) var state_before: Dictionary = _state.create_snapshot() var economy_before: Dictionary = _runtime.economy_service.create_snapshot() var progression_before: Dictionary = _runtime.progression_service.create_snapshot() var overflow: CommandResult = _runtime._execute_change_resources(_direct_command( &"change_resources", {&"deltas": {&"faith": 1}} )) _expect(not overflow.is_success(), "lifetime Faith overflow rejects the resource command") _expect(_state.create_snapshot() == state_before, "failed lifetime update restores GameState exactly") _expect(_runtime.economy_service.create_snapshot() == economy_before, "failed lifetime update restores Economy exactly") _expect(_runtime.progression_service.create_snapshot() == progression_before, "failed lifetime update restores Progression exactly") func _test_catalog_staff_hire_transaction() -> void: _reset_runtime(82_003) var bypass: CommandResult = _runtime.submit_command( &"register_staff", { &"staff_id": &"staff_akane", &"role_id": &"guard", &"options": {&"current_cell": Vector3i.ZERO}, }, &"player", &"staff_akane", 80, -1, &"mvp.hire.bypass" ) _expect(not bypass.is_success(), "generic Staff registration cannot bypass a reserved catalog candidate") var cash_before: int = _runtime.economy_service.get_balance(_runtime.PLAYER_CASH_ACCOUNT) var hired: CommandResult = _runtime.submit_command( &"hire_staff_candidate", {&"candidate_id": &"staff_akane", &"current_cell": Vector3i.ZERO}, &"player", &"staff_akane", 80, -1, &"mvp.hire.akane" ) _expect(hired.is_success(), "validated Staff candidate hires atomically") var staff: StaffRuntime = _runtime.staff_service.get_staff(&"staff_akane") var shift: ShiftInstance = _runtime.staff_service.get_shift(StringName(hired.details[&"shift_id"])) _expect(staff != null and staff.role_id == &"receptionist", "hire uses the catalog role as the sole source of truth") _expect(staff != null and staff.daily_wage == 120, "FREE_HIRE retains its catalog daily wage") _expect(staff != null and staff.get_employment_kind_name() == &"FREE_HIRE", "ordinary catalog hire records explicit FREE_HIRE employment") _expect(staff != null and int(staff.skills[&"service"]) == 68, "hire copies catalog skills without caller inference") _expect(staff != null and staff.permitted_task_tags == [&"reception", &"service"], "hire copies canonical permitted Task tags") _expect(shift != null and shift.template_id == &"DAY", "hire creates the candidate's preferred Shift") _expect(_runtime.staff_service.get_daily_payroll_total() == 120, "hired candidate participates in deterministic daily payroll") _expect( _runtime.economy_service.get_balance(_runtime.PLAYER_CASH_ACCOUNT) == cash_before - 180, "signing cost is paid exactly once through the Gold ledger" ) _expect(_state.get_resource(&"gold") == cash_before - 180, "ledger signing cost synchronizes GameState Gold") _expect(_runtime.path_service.has_actor_projection(&"staff:staff_akane"), "hired Staff is projected into Path traffic") _expect(_runtime.get_hired_staff_candidate_ids() == [&"staff_akane"], "Runtime records the candidate as permanently hired") var saw_hire_event := false for event: SimulationDomainEvent in _runtime.domain_events.recent_events(): if event.event_type == &"STAFF_CANDIDATE_HIRED" and &"staff_akane" in event.entity_ids: saw_hire_event = true _expect(saw_hire_event, "successful hire publishes a structured DomainEvent") var replay_cash: int = _runtime.economy_service.get_balance(_runtime.PLAYER_CASH_ACCOUNT) var replay: CommandResult = _runtime.submit_command( &"hire_staff_candidate", {&"candidate_id": &"staff_akane", &"current_cell": Vector3i.ZERO}, &"player", &"staff_akane", 80, -1, &"mvp.hire.akane" ) _expect(not replay.is_success() and replay.code == CommandResult.Code.DUPLICATE_IDEMPOTENCY_KEY, "resent hire command is recognized by its idempotency key") _expect(_runtime.economy_service.get_balance(_runtime.PLAYER_CASH_ACCOUNT) == replay_cash, "resent hire never charges the signing cost twice") var duplicate: CommandResult = _runtime.submit_command( &"hire_staff_candidate", {&"candidate_id": &"staff_akane", &"current_cell": Vector3i.ZERO}, &"player", &"staff_akane", 80, -1, &"mvp.hire.akane.other" ) _expect(not duplicate.is_success(), "same candidate cannot be hired under a different request") _expect(_runtime.economy_service.get_balance(_runtime.PLAYER_CASH_ACCOUNT) == replay_cash, "duplicate-candidate rejection spends no Gold") var original_coordinator: Variant = _runtime.operations_coordinator var original_operations_enabled: bool = bool(_runtime._operations_enabled) var staff_before_gate: Dictionary = _runtime.staff_service.create_snapshot() var economy_before_gate: Dictionary = _runtime.economy_service.create_snapshot() var hired_before_gate: Array[StringName] = _runtime.get_hired_staff_candidate_ids() _runtime.operations_coordinator = DenyingOperationsCoordinator.new() _runtime._operations_enabled = true var gated: CommandResult = _runtime._execute_hire_staff_candidate(_direct_command( &"hire_staff_candidate", {&"candidate_id": &"staff_tessa", &"current_cell": Vector3i.ZERO} )) _runtime.operations_coordinator = original_coordinator _runtime._operations_enabled = original_operations_enabled _expect( not gated.is_success() and StringName(gated.details.get(&"reason", &"")) == &"ARREARS_REMAIN", "Operations arrears gate rejects a new wage-bearing Staff contract" ) _expect( _runtime.staff_service.create_snapshot() == staff_before_gate and _runtime.economy_service.create_snapshot() == economy_before_gate and _runtime.get_hired_staff_candidate_ids() == hired_before_gate, "rejected Operations-gated hire spends nothing and mutates no Staff history" ) var staff_before: Dictionary = _runtime.staff_service.create_snapshot() var economy_before: Dictionary = _runtime.economy_service.create_snapshot() var game_state_before: Dictionary = _state.create_snapshot() var path_before: Dictionary = _runtime.path_service.create_snapshot() var credits_before: Dictionary = _runtime._movement_credits.duplicate(true) var events_before: Dictionary = _runtime.domain_events.create_snapshot() var ids_before: Dictionary = _runtime.id_generator.create_snapshot() var hired_ids_before: Array[StringName] = _runtime.get_hired_staff_candidate_ids() var callback := Callable(_runtime, "_on_staff_registered") _runtime.staff_service.staff_registered.disconnect(callback) var forced_failure: CommandResult = _runtime._execute_hire_staff_candidate(_direct_command( &"hire_staff_candidate", {&"candidate_id": &"staff_bardo", &"current_cell": Vector3i.ZERO} )) _runtime.staff_service.staff_registered.connect(callback) _expect(not forced_failure.is_success(), "missing Path projection forces a post-payment hire failure") _expect(_runtime.staff_service.create_snapshot() == staff_before, "failed hire restores Staff and Shift state exactly") _expect(_runtime.economy_service.create_snapshot() == economy_before, "failed hire restores the ledger exactly") _expect(_state.create_snapshot() == game_state_before, "failed hire restores GameState exactly") _expect(_runtime.path_service.create_snapshot() == path_before, "failed hire restores Path exactly") _expect(_runtime._movement_credits == credits_before, "failed hire restores movement credits exactly") _expect(_runtime.domain_events.create_snapshot() == events_before, "failed hire restores DomainEvents exactly") _expect(_runtime.id_generator.create_snapshot() == ids_before, "failed hire restores stable ID counters exactly") _expect(_runtime.get_hired_staff_candidate_ids() == hired_ids_before, "failed hire leaves candidate history unchanged") var canonical_save: Dictionary = _runtime.create_snapshot() var wage_tamper: Dictionary = canonical_save.duplicate(true) for raw_staff: Dictionary in wage_tamper[&"systems"][&"runtime"][&"staff"][&"staff"]: if String(raw_staff[&"staff_id"]) == "staff_akane": raw_staff[&"daily_wage"] = 0 break var live_before: Dictionary = _runtime.create_snapshot() _expect(not _runtime.restore_snapshot(wage_tamper), "v4 restore rejects a hired candidate whose catalog wage was altered") _expect(_runtime.create_snapshot() == live_before, "catalog Staff crosslink rejection is atomic") func _test_rank_two_three_and_atomic_failure() -> void: _reset_runtime(82_004) var rank_before: Dictionary = _runtime.progression_service.create_snapshot() var world_before: Dictionary = _runtime.world_service.create_snapshot() var unmet: CommandResult = _runtime._execute_set_world_tree_rank(_direct_command( &"set_world_tree_rank", {&"rank": 2, &"request_id": &"rank_two_unmet"} )) _expect(not unmet.is_success(), "Rank 2 rejects unmet reputation and asset requirements") _expect(_runtime.progression_service.create_snapshot() == rank_before, "failed eligibility check leaves Progression exact") _expect(_runtime.world_service.create_snapshot() == world_before, "failed eligibility check leaves World exact") _expect(_runtime._execute_update_progression_metrics(_direct_command( &"update_progression_metrics", {&"metrics": {&"reputation": 25}} )).is_success(), "Rank 2 reputation fact updates") _expect(_runtime._execute_change_resources(_direct_command( &"change_resources", {&"deltas": {&"gold": 5_000}} )).is_success(), "Rank 2 asset threshold is funded") var promoted_two: CommandResult = _runtime._execute_set_world_tree_rank(_direct_command( &"set_world_tree_rank", {&"rank": 2, &"request_id": &"rank_two"} )) _expect(promoted_two.is_success(), "eligible Rank 2 promotion succeeds") _expect(_runtime.progression_service.current_rank == 2 and _state.world_tree_rank == 2, "Progression and GameState commit Rank 2 together") _expect(_runtime.world_service.get_bounds() == ProgressionService.RANK_BOUNDS[2], "Rank 2 commits canonical World bounds") var replay_before: Dictionary = _runtime.create_snapshot() var replay: CommandResult = _runtime._execute_set_world_tree_rank(_direct_command( &"set_world_tree_rank", {&"rank": 2, &"request_id": &"rank_two"} )) _expect(replay.is_success() and replay.is_replay, "same rank request ID replays the original success") _expect(_runtime.create_snapshot() == replay_before, "rank request replay is completely read-only") var skip: CommandResult = _runtime._execute_set_world_tree_rank(_direct_command( &"set_world_tree_rank", {&"rank": 4, &"request_id": &"rank_four_skip"} )) _expect(not skip.is_success() and _runtime.progression_service.current_rank == 2, "rank progression cannot skip Rank 3") var rank_three_guests_ok := true var rank_guest_definition: StringName = _runtime.get_mvp_guest_definition_ids()[0] for index in range(300): var guest_id := StringName("rank_three_guest_%03d" % index) var spawned: CommandResult = _runtime._execute_spawn_guest(_direct_command( &"spawn_guest", { &"guest_id": guest_id, &"guest_type_id": rank_guest_definition, &"gold": 0, &"options": { &"current_cell": Vector3i.ZERO, &"planned_exit_at": 10_000, }, } )) rank_three_guests_ok = rank_three_guests_ok and spawned.is_success() var lifetime_updated: CommandResult = _runtime._execute_update_progression_metrics(_direct_command( &"update_progression_metrics", {&"metrics": {&"faith_lifetime": 100}} )) _expect( rank_three_guests_ok and lifetime_updated.is_success() \ and int(_runtime.progression_service.metrics[&"guest_lifetime"]) == 300, "Rank 3 lifetime facts derive from 300 authoritative Guest records" ) var promoted_three: CommandResult = _runtime._execute_set_world_tree_rank(_direct_command( &"set_world_tree_rank", {&"rank": 3, &"request_id": &"rank_three"} )) _expect(promoted_three.is_success(), "eligible Rank 3 promotion succeeds") _expect(_runtime.progression_service.current_rank == 3 and _state.world_tree_rank == 3, "Progression and GameState commit Rank 3 together") var saw_rank_event := false for event: SimulationDomainEvent in _runtime.domain_events.recent_events(): if event.event_type == &"WORLD_TREE_RANK_ADVANCED" and int(event.payload.get(&"rank", 0)) == 3: saw_rank_event = true _expect(saw_rank_event, "successful promotion publishes WORLD_TREE_RANK_ADVANCED") _reset_runtime(82_005) _runtime.progression_service.update_metrics({&"reputation": 25}) _runtime._execute_change_resources(_direct_command(&"change_resources", {&"deltas": {&"gold": 5_000}})) _expect(_runtime._expand_world_to_rank(3), "rank apply-failure fixture expands World and Path coherently") var atomic_before := { &"progression": _runtime.progression_service.create_snapshot(), &"world": _runtime.world_service.create_snapshot(), &"path": _runtime.path_service.create_snapshot(), &"state": _state.create_snapshot(), &"credits": _runtime._movement_credits.duplicate(true), &"events": _runtime.domain_events.create_snapshot(), &"ids": _runtime.id_generator.create_snapshot(), } var apply_failure: CommandResult = _runtime._execute_set_world_tree_rank(_direct_command( &"set_world_tree_rank", {&"rank": 2, &"request_id": &"rank_two_apply_failure"} )) _expect(not apply_failure.is_success(), "World/Path apply failure rejects promotion") _expect(_runtime.progression_service.create_snapshot() == atomic_before[&"progression"], "failed rank apply restores Progression exactly") _expect(_runtime.world_service.create_snapshot() == atomic_before[&"world"], "failed rank apply restores World exactly") _expect(_runtime.path_service.create_snapshot() == atomic_before[&"path"], "failed rank apply restores Path exactly") _expect(_state.create_snapshot() == atomic_before[&"state"], "failed rank apply restores GameState exactly") _expect(_runtime._movement_credits == atomic_before[&"credits"], "failed rank apply restores movement credits exactly") _expect(_runtime.domain_events.create_snapshot() == atomic_before[&"events"], "failed rank apply restores DomainEvents exactly") _expect(_runtime.id_generator.create_snapshot() == atomic_before[&"ids"], "failed rank apply restores stable IDs exactly") func _test_v3_migration_and_v4_tamper_guards() -> void: _reset_runtime(82_006) _runtime._execute_change_resources(_direct_command(&"change_resources", {&"deltas": {&"faith": 12}})) for index in range(2): var guest_id := StringName("legacy_guest_%d" % index) var spawned: CommandResult = _runtime._execute_spawn_guest(_direct_command( &"spawn_guest", { &"guest_id": guest_id, &"guest_type_id": _runtime.get_mvp_guest_definition_ids()[index], &"gold": 0, &"options": {&"current_cell": Vector3i.ZERO}, } )) _expect(spawned.is_success(), "legacy migration fixture Guest %d spawns" % index) _runtime.guest_service.despawn_guest(&"legacy_guest_1", _clock.absolute_minute) var v3: Dictionary = _runtime.create_snapshot() var v3_runtime: Dictionary = v3[&"systems"][&"runtime"] v3_runtime[&"runtime_schema_version"] = 3 v3_runtime.erase(&"kitchen_production") v3_runtime.erase(&"elevators") v3_runtime[&"path"][&"schema_version"] = 3 v3_runtime[&"path"].erase(&"vertical_walk_blockers") v3_runtime.erase(&"operations") v3_runtime.erase(&"catalog_manifest") v3_runtime.erase(&"progression") v3_runtime.erase(&"hired_staff_candidate_ids") for infrastructure_key: StringName in [ &"excavation", &"spatial_subslots", &"route_projection", &"facility_infrastructure", ]: v3_runtime.erase(infrastructure_key) _expect(_runtime.restore_snapshot(v3), "Runtime v3 Rank 1 snapshot migrates without guessed promotion evidence") _expect(_runtime.progression_service.current_rank == 1, "v3 migration creates fresh Rank 1 Progression") _expect(int(_runtime.progression_service.metrics[&"asset_gold"]) == _runtime.economy_service.get_balance(_runtime.PLAYER_CASH_ACCOUNT), "v3 migration derives asset Gold from the authoritative ledger") _expect(int(_runtime.progression_service.metrics[&"faith_lifetime"]) == 12, "v3 migration derives lifetime Faith from current Faith") _expect(int(_runtime.progression_service.metrics[&"guest_lifetime"]) == 2, "v3 migration derives lifetime Guests from active plus persistent records") _expect(_runtime.get_mvp_guest_definition_ids().size() == 32, "v3 migration registers the current 32 catalog definitions") var migrated: Dictionary = _runtime.create_snapshot() _expect(int(migrated[&"systems"][&"runtime"][&"runtime_schema_version"]) == 8, "v3 migration emits canonical Runtime schema v8") var digest := SimulationDigest.compute(migrated) _expect(_runtime.restore_snapshot(migrated), "canonical v8 snapshot restores") _expect(SimulationDigest.compute(_runtime.create_snapshot()) == digest, "canonical v8 restore is exact") var progressed_legacy: Dictionary = v3.duplicate(true) progressed_legacy[&"game_state"][&"world_tree_rank"] = 2 var live_before: Dictionary = _runtime.create_snapshot() _expect(not _runtime.restore_snapshot(progressed_legacy), "v3 Rank 2 snapshot is rejected because promotion evidence is absent") _expect(_runtime.create_snapshot() == live_before, "rejected progressed v3 migration is atomic") var corruptions: Array[Dictionary] = [] var manifest: Dictionary = migrated.duplicate(true) manifest[&"systems"][&"runtime"][&"catalog_manifest"][&"guest_definition_ids"][0] = "tampered_guest" corruptions.append({&"label": "catalog manifest", &"snapshot": manifest}) var definition: Dictionary = migrated.duplicate(true) var catalog_id := String(_runtime.get_mvp_guest_definition_ids()[0]) for raw_definition: Dictionary in definition[&"systems"][&"runtime"][&"guests"][&"definitions"]: if String(raw_definition[&"guest_type_id"]) == catalog_id: raw_definition[&"wealth_min"] = int(raw_definition[&"wealth_min"]) + 1 break corruptions.append({&"label": "catalog Guest definition", &"snapshot": definition}) var progression: Dictionary = migrated.duplicate(true) progression[&"systems"][&"runtime"][&"progression"][&"current_rank"] = 2 corruptions.append({&"label": "Progression history", &"snapshot": progression}) var rank: Dictionary = migrated.duplicate(true) rank[&"game_state"][&"world_tree_rank"] = 2 corruptions.append({&"label": "GameState rank", &"snapshot": rank}) var bounds: Dictionary = migrated.duplicate(true) bounds[&"systems"][&"runtime"][&"world"][&"bounds"][&"max_x"] = 13 corruptions.append({&"label": "World rank bounds", &"snapshot": bounds}) var hired_manifest: Dictionary = migrated.duplicate(true) hired_manifest[&"systems"][&"runtime"][&"hired_staff_candidate_ids"] = ["not_a_candidate"] corruptions.append({&"label": "hired candidate manifest", &"snapshot": hired_manifest}) for corruption: Dictionary in corruptions: live_before = _runtime.create_snapshot() _expect( not _runtime.restore_snapshot(corruption[&"snapshot"]) and _runtime.create_snapshot() == live_before, "%s tamper is rejected atomically" % corruption[&"label"] ) func _test_twenty_four_hour_replay() -> void: _reset_runtime(82_007) var spawn: CommandResult = _runtime._execute_spawn_guest(_direct_command( &"spawn_guest", { &"guest_id": &"replay_guest", &"guest_type_id": _runtime.get_mvp_guest_definition_ids()[0], &"gold": 100, &"options": {&"current_cell": Vector3i.ZERO, &"planned_exit_at": _clock.absolute_minute + 2_000}, } )) var hire: CommandResult = _runtime._execute_hire_staff_candidate(_direct_command( &"hire_staff_candidate", {&"candidate_id": &"staff_akane", &"current_cell": Vector3i.ZERO} )) _expect(spawn.is_success() and hire.is_success(), "24-hour replay fixture creates catalog Guest and Staff") var start: Dictionary = _runtime.create_snapshot() var second_clock = load("res://autoload/game_clock.gd").new() var second_state = load("res://autoload/game_state.gd").new() var second_runtime = load("res://autoload/simulation_runtime.gd").new() second_clock.reset(1, 6, 0) second_state.reset() second_runtime.initialize(second_clock, second_state, 82_007) second_clock.set_paused(true) _expect(second_runtime.restore_snapshot(start), "24-hour replay clone restores exact v4 start") _clock.set_paused(false) second_clock.set_paused(false) _clock.advance_minutes(1_440) second_clock.advance_minutes(1_440) _expect( SimulationDigest.compute(_runtime.create_snapshot()) \ == SimulationDigest.compute(second_runtime.create_snapshot()), "catalog, Staff hire, Progression, and six-Need state replay exactly for 24 hours" ) second_runtime.free() second_clock.free() second_state.free() func _direct_command(command_type: StringName, payload: Dictionary) -> SimulationCommand: _direct_command_id += 1 return SimulationCommand.new( _direct_command_id, _clock.absolute_minute, _clock.absolute_minute, 100, command_type, &"test", &"", payload, &"" ) func _expect(condition: bool, label: String) -> void: _checks += 1 if condition: print(" ✓ %s" % label) return _failures += 1 push_error(" ✗ %s" % label)