extends SceneTree var failures: Array[String] = [] func _initialize() -> void: call_deferred("_run") func _run() -> void: await _test_single_two_leg_delivery() await _test_one_unit_contention() await _test_legacy_pre_pickup_restore_reroutes() await _test_legacy_working_restore_reroutes() await _test_post_pickup_restore_continuation() _finish() func _test_single_two_leg_delivery() -> void: var fixture := await _load_world() var main_scene: Node = fixture["main"] var manager: Node = fixture["manager"] var view: Node = fixture["view"] var pantry_node := StorageNode.get_by_id(SimulationIds.STORAGE_VILLAGE_PANTRY) as StorageNode var zora_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_ZORA) var dunja_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_DUNJA) var pantry: StorageStateRecord = manager.get_pantry() var zora_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) var dunja_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_DUNJA) _check( ( pantry_node != null and zora_node != null and dunja_node != null and pantry != null and zora_state != null and dunja_state != null ), "The delivery proof needs the authored pantry and both bound named goats", ) if ( pantry_node == null or zora_node == null or dunja_node == null or pantry == null or zora_state == null or dunja_state == null ): await _unload_world(main_scene) return _prepare_population(manager, view) _set_pantry_food(manager, 3.0) zora_state.set_hunger(72.0) dunja_state.set_hunger(30.0) var caretaker: SimNPC = manager.npcs[0] var origin := zora_node.get_interaction_position() _prepare_feed_task(manager, view, caretaker, origin) _check( manager.resolve_npc_target(caretaker.id, origin), "A caretaker should resolve a physical route for hungry Zora", ) _check( ( caretaker.current_task == SimulationIds.ACTION_FEED_ANIMAL and caretaker.target_id == SimulationIds.ANIMAL_ZORA and zora_state.get_reserved_by() == caretaker.id and caretaker.has_travel_target and caretaker.travel_target_position.is_equal_approx( pantry_node.get_interaction_position() ) ), "The first feed leg should retain exact Zora authority while targeting the pantry", ) var pantry_before := pantry.get_amount(SimulationIds.RESOURCE_FOOD) var observed_villages := [] var observed_food := [] var observed_states := [] manager.village_changed.connect( func(changed_village): observed_villages.append(changed_village) observed_food.append(changed_village.food) observed_states.append(manager.serialize_state()) ) _arrive_at_current_target(manager, view, caretaker) var withdrawal_events := _events_for( manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker.id ) var observed_record: SimulationStateRecord var observed_npc: SimNPC if observed_states.size() == 1: observed_record = SimulationStateRecord.from_json(String(observed_states[0])) if observed_record != null: var observed_npc_record := _find_npc_record(observed_record.npcs, caretaker.id) if observed_npc_record != null: observed_npc = observed_npc_record.restore(false) _check( ( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), pantry_before - 1.0) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and caretaker.current_task == SimulationIds.ACTION_FEED_ANIMAL and caretaker.task_state == SimNPC.TASK_STATE_TRAVELING and caretaker.target_id == SimulationIds.ANIMAL_ZORA and zora_state.get_reserved_by() == caretaker.id and caretaker.has_travel_target and caretaker.travel_target_position.is_equal_approx( zora_node.get_interaction_position() ) and observed_villages.size() == 1 and observed_villages[0] == manager.village and is_equal_approx(float(observed_food[0]), pantry_before - 1.0) and observed_record != null and observed_npc != null and is_equal_approx(observed_npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and observed_npc.target_id == SimulationIds.ANIMAL_ZORA and observed_npc.travel_target_position.is_equal_approx( zora_node.get_interaction_position() ) ), ( "Pantry arrival should atomically expose synchronized food, carried inventory, " + "and the same claimed Zora delivery waypoint" ), ) _check( ( withdrawal_events.size() == 1 and _is_exact_withdrawal( withdrawal_events[0], caretaker.id, pantry_node.get_interaction_position(), ) ), "The pickup leg should record one exact pantry-to-caretaker transfer at the pantry", ) var carried_food := _get_carried_food(view, caretaker.id) _check( carried_food != null and carried_food.visible, "Authoritative caretaker inventory should reveal the existing carried-food prop", ) _check( is_equal_approx( ( pantry.get_amount(SimulationIds.RESOURCE_FOOD) + caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD) ), pantry_before, ), "Food should be conserved across the pantry pickup boundary", ) var zora_hunger_before := zora_state.get_hunger() var dunja_hunger_before := dunja_state.get_hunger() _arrive_at_current_target(manager, view, caretaker) _check( caretaker.task_state == SimNPC.TASK_STATE_WORKING, "Arrival at exact Zora should begin the feed work without another withdrawal", ) var work_ticks := int(ceil(caretaker.task_duration)) for _tick in range(work_ticks): manager.simulate_tick() var feed_events := _events_for(manager, SimulationIds.EVENT_ANIMAL_FED, caretaker.id) _check( ( is_equal_approx( zora_state.get_hunger(), ( zora_hunger_before + AnimalStateRecord.HUNGER_PER_TICK * work_ticks - AnimalStateRecord.HUNGER_RELIEF ), ) and is_equal_approx( dunja_state.get_hunger(), dunja_hunger_before + AnimalStateRecord.HUNGER_PER_TICK * work_ticks, ) and zora_state.get_last_fed_tick() == manager.tick_count and zora_state.get_reserved_by() == -1 and is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), pantry_before - 1.0) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) ), "Delivery completion should consume carried food and mutate only Zora beyond natural hunger", ) _check( ( feed_events.size() == 1 and _is_exact_feed(feed_events[0], caretaker.id, SimulationIds.ANIMAL_ZORA, zora_state) and ( _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker.id).size() == 1 ) ), "The complete delivery should retain one withdrawal followed by one exact inventory feed", ) _check( ( feed_events.size() == 1 and is_equal_approx( ( pantry.get_amount(SimulationIds.RESOURCE_FOOD) + caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD) + float(feed_events[0].data["amount"]) ), pantry_before, ) ), "Exactly one delivered food should account for the unit that leaves tracked holdings", ) carried_food = _get_carried_food(view, caretaker.id) _check( carried_food != null and not carried_food.visible, "The carried-food prop should disappear after the exact goat receives it", ) await _unload_world(main_scene) func _test_one_unit_contention() -> void: var fixture := await _load_world() var main_scene: Node = fixture["main"] var manager: Node = fixture["manager"] var view: Node = fixture["view"] var pantry_node := StorageNode.get_by_id(SimulationIds.STORAGE_VILLAGE_PANTRY) as StorageNode var zora_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_ZORA) var dunja_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_DUNJA) var pantry: StorageStateRecord = manager.get_pantry() var zora_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) var dunja_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_DUNJA) if ( pantry_node == null or zora_node == null or dunja_node == null or pantry == null or zora_state == null or dunja_state == null ): _check(false, "The contention proof needs the authored pantry and paired goats") await _unload_world(main_scene) return _prepare_population(manager, view) _set_pantry_food(manager, 1.0) zora_state.set_hunger(72.0) dunja_state.set_hunger(72.0) var winner: SimNPC = manager.npcs[0] var loser: SimNPC = manager.npcs[1] var shared_origin := zora_node.get_interaction_position() _prepare_feed_task(manager, view, winner, shared_origin) _prepare_feed_task(manager, view, loser, shared_origin) var winner_resolved: bool = manager.resolve_npc_target(winner.id, shared_origin) var loser_resolved: bool = manager.resolve_npc_target(loser.id, shared_origin) _check( ( winner_resolved and loser_resolved and winner.target_id == SimulationIds.ANIMAL_ZORA and loser.target_id == SimulationIds.ANIMAL_DUNJA and zora_state.get_reserved_by() == winner.id and dunja_state.get_reserved_by() == loser.id and winner.travel_target_position.is_equal_approx( pantry_node.get_interaction_position() ) and loser.travel_target_position.is_equal_approx(pantry_node.get_interaction_position()) ), "Two caretakers should retain independent exact goat claims while sharing the pantry leg", ) _arrive_at_current_target(manager, view, winner) _arrive_at_current_target(manager, view, loser) var all_withdrawals := _events_of_type(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN) var loser_blocked := _events_for(manager, SimulationIds.EVENT_TASK_BLOCKED, loser.id) _check( ( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), 0.0) and is_equal_approx(winner.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and is_equal_approx(loser.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) and all_withdrawals.size() == 1 and int(all_withdrawals[0].data["actor_id"]) == winner.id ), "One pantry unit should produce exactly one winning pickup without duplication", ) _check( ( winner.current_task == SimulationIds.ACTION_FEED_ANIMAL and winner.target_id == SimulationIds.ANIMAL_ZORA and zora_state.get_reserved_by() == winner.id and loser.current_task != SimulationIds.ACTION_FEED_ANIMAL and loser.get_inventory_amount(SimulationIds.RESOURCE_FOOD) == 0.0 and dunja_state.get_reserved_by() == -1 and loser_blocked.size() == 1 and ( StringName(loser_blocked[0].data["source_id"]) == SimulationIds.STORAGE_VILLAGE_PANTRY ) and (StringName(loser_blocked[0].data["action_id"]) == SimulationIds.ACTION_FEED_ANIMAL) and is_equal_approx(float(loser_blocked[0].data["required_amount"]), 1.0) ), "The losing pantry arrival should record the shortfall, release only its claim, and not feed", ) var zora_hunger_before := zora_state.get_hunger() var dunja_hunger_before := dunja_state.get_hunger() _arrive_at_current_target(manager, view, winner) var work_ticks := int(ceil(winner.task_duration)) for _tick in range(work_ticks): manager.simulate_tick() var feed_events := _events_of_type(manager, SimulationIds.EVENT_ANIMAL_FED) _check( ( feed_events.size() == 1 and _is_exact_feed(feed_events[0], winner.id, SimulationIds.ANIMAL_ZORA, zora_state) and is_equal_approx( zora_state.get_hunger(), ( zora_hunger_before + AnimalStateRecord.HUNGER_PER_TICK * work_ticks - AnimalStateRecord.HUNGER_RELIEF ), ) and is_equal_approx( dunja_state.get_hunger(), dunja_hunger_before + AnimalStateRecord.HUNGER_PER_TICK * work_ticks, ) ), "Contention should complete only the winning caretaker's exact Zora delivery", ) _check( ( _events_of_type(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN).size() == 1 and is_equal_approx( ( pantry.get_amount(SimulationIds.RESOURCE_FOOD) + winner.get_inventory_amount(SimulationIds.RESOURCE_FOOD) + loser.get_inventory_amount(SimulationIds.RESOURCE_FOOD) + float(feed_events[0].data["amount"]) ), 1.0, ) ), "One-unit contention should conserve exactly one food through final delivery", ) await _unload_world(main_scene) func _test_legacy_pre_pickup_restore_reroutes() -> void: var fixture := await _load_world() var main_scene: Node = fixture["main"] var manager: Node = fixture["manager"] var view: Node = fixture["view"] var pantry_node := StorageNode.get_by_id(SimulationIds.STORAGE_VILLAGE_PANTRY) as StorageNode var zora_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_ZORA) var pantry: StorageStateRecord = manager.get_pantry() var zora_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) if pantry_node == null or zora_node == null or pantry == null or zora_state == null: _check(false, "The legacy-route proof needs the authored pantry and Zora") await _unload_world(main_scene) return _prepare_population(manager, view) _set_pantry_food(manager, 2.0) zora_state.set_hunger(72.0) var caretaker: SimNPC = manager.npcs[0] var caretaker_id := caretaker.id var origin := zora_node.get_interaction_position() _prepare_feed_task(manager, view, caretaker, origin) _check( manager.resolve_npc_target(caretaker.id, origin), "The legacy-route caretaker should establish an exact Zora claim", ) # Schema v11 predates the pantry leg, so its valid active feed records can # retain an empty inventory while traveling directly to the claimed goat. caretaker.travel_target_position = zora_node.get_interaction_position() caretaker.has_travel_target = true var legacy_route_json: String = manager.serialize_state() var legacy_route_checksum: String = manager.get_state_checksum() var pantry_before := pantry.get_amount(SimulationIds.RESOURCE_FOOD) _check( manager.restore_state_from_json(legacy_route_json), "A pre-delivery schema-v11 feed route should remain restorable", ) _freeze_visuals(view) caretaker = _find_npc(manager.npcs, caretaker_id) pantry = manager.get_pantry() zora_state = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) _check( ( caretaker != null and manager.get_state_checksum() == legacy_route_checksum and caretaker.travel_target_position.is_equal_approx( zora_node.get_interaction_position() ) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) and zora_state.get_reserved_by() == caretaker_id ), "Restore should first preserve the valid legacy route and exact claim", ) if caretaker == null: await _unload_world(main_scene) return _arrive_at_current_target(manager, view, caretaker) _check( ( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), pantry_before) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) and _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker_id).is_empty() and caretaker.current_task == SimulationIds.ACTION_FEED_ANIMAL and caretaker.task_state == SimNPC.TASK_STATE_TRAVELING and caretaker.target_id == SimulationIds.ANIMAL_ZORA and zora_state.get_reserved_by() == caretaker_id and caretaker.travel_target_position.is_equal_approx( pantry_node.get_interaction_position() ) ), "Legacy goat arrival should reroute to the pantry without a remote withdrawal", ) _arrive_at_current_target(manager, view, caretaker) var withdrawal_events := _events_for( manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker_id ) _check( ( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), pantry_before - 1.0) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and withdrawal_events.size() == 1 and _is_exact_withdrawal( withdrawal_events[0], caretaker_id, pantry_node.get_interaction_position(), ) and caretaker.travel_target_position.is_equal_approx( zora_node.get_interaction_position() ) and zora_state.get_reserved_by() == caretaker_id ), "Legacy continuation should withdraw only after physical pantry arrival", ) await _unload_world(main_scene) func _test_legacy_working_restore_reroutes() -> void: var fixture := await _load_world() var main_scene: Node = fixture["main"] var manager: Node = fixture["manager"] var view: Node = fixture["view"] var pantry_node := StorageNode.get_by_id(SimulationIds.STORAGE_VILLAGE_PANTRY) as StorageNode var zora_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_ZORA) var pantry: StorageStateRecord = manager.get_pantry() var zora_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) if pantry_node == null or zora_node == null or pantry == null or zora_state == null: _check(false, "The legacy-working proof needs the authored pantry and Zora") await _unload_world(main_scene) return _prepare_population(manager, view) _set_pantry_food(manager, 2.0) zora_state.set_hunger(72.0) var caretaker: SimNPC = manager.npcs[0] var caretaker_id := caretaker.id var origin := zora_node.get_interaction_position() _prepare_feed_task(manager, view, caretaker, origin) _check( manager.resolve_npc_target(caretaker.id, origin), "The legacy-working caretaker should establish an exact Zora claim", ) # The old one-leg flow could also be saved after goat arrival, while work # was already in progress but before pantry-backed completion. caretaker.task_state = SimNPC.TASK_STATE_WORKING caretaker.task_progress = 2.0 caretaker.task_complete = false caretaker.has_travel_target = false caretaker.travel_target_position = zora_node.get_interaction_position() var legacy_working_json: String = manager.serialize_state() var legacy_working_checksum: String = manager.get_state_checksum() var pantry_before := pantry.get_amount(SimulationIds.RESOURCE_FOOD) _check( manager.restore_state_from_json(legacy_working_json), "A working pre-delivery schema-v11 feed state should remain restorable", ) _freeze_visuals(view) caretaker = _find_npc(manager.npcs, caretaker_id) pantry = manager.get_pantry() zora_state = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) _check( ( caretaker != null and manager.get_state_checksum() == legacy_working_checksum and caretaker.task_state == SimNPC.TASK_STATE_WORKING and is_equal_approx(caretaker.task_progress, 2.0) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) and zora_state.get_reserved_by() == caretaker_id ), "Restore should initially preserve the legacy working state and checksum", ) if caretaker == null: await _unload_world(main_scene) return manager.simulate_tick() _check( ( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), pantry_before) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) and _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker_id).is_empty() and caretaker.current_task == SimulationIds.ACTION_FEED_ANIMAL and caretaker.task_state == SimNPC.TASK_STATE_TRAVELING and caretaker.target_id == SimulationIds.ANIMAL_ZORA and caretaker.has_travel_target and caretaker.travel_target_position.is_equal_approx( pantry_node.get_interaction_position() ) and is_equal_approx(caretaker.task_progress, 2.0) and zora_state.get_reserved_by() == caretaker_id ), "The first resumed tick should preserve work progress and reroute to the pantry", ) _arrive_at_current_target(manager, view, caretaker) _check( ( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), pantry_before - 1.0) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and caretaker.task_state == SimNPC.TASK_STATE_TRAVELING and caretaker.travel_target_position.is_equal_approx( zora_node.get_interaction_position() ) and is_equal_approx(caretaker.task_progress, 2.0) and zora_state.get_reserved_by() == caretaker_id ), "Recovered work should pick up at the pantry and return to the same Zora claim", ) _arrive_at_current_target(manager, view, caretaker) _check( ( caretaker.task_state == SimNPC.TASK_STATE_WORKING and is_equal_approx(caretaker.task_progress, 2.0) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and zora_state.get_reserved_by() == caretaker_id ), "Legacy work should resume beside Zora without losing its saved progress", ) await _unload_world(main_scene) func _test_post_pickup_restore_continuation() -> void: var fixture := await _load_world() var main_scene: Node = fixture["main"] var manager: Node = fixture["manager"] var view: Node = fixture["view"] var pantry_node := StorageNode.get_by_id(SimulationIds.STORAGE_VILLAGE_PANTRY) as StorageNode var zora_node := AnimalNode.get_by_id(SimulationIds.ANIMAL_ZORA) var pantry: StorageStateRecord = manager.get_pantry() var zora_state: AnimalStateRecord = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) if pantry_node == null or zora_node == null or pantry == null or zora_state == null: _check(false, "The restore proof needs the authored pantry and Zora") await _unload_world(main_scene) return _prepare_population(manager, view) _set_pantry_food(manager, 2.0) zora_state.set_hunger(72.0) var caretaker: SimNPC = manager.npcs[0] var caretaker_id := caretaker.id var origin := zora_node.get_interaction_position() _prepare_feed_task(manager, view, caretaker, origin) _check( manager.resolve_npc_target(caretaker.id, origin), "The restore caretaker should resolve Zora's two-leg delivery", ) _arrive_at_current_target(manager, view, caretaker) var midpoint_json: String = manager.serialize_state() var midpoint_checksum: String = manager.get_state_checksum() var midpoint_position := caretaker.position var midpoint_destination := caretaker.travel_target_position var midpoint_pantry := pantry.get_amount(SimulationIds.RESOURCE_FOOD) _check( ( caretaker.target_id == SimulationIds.ANIMAL_ZORA and caretaker.task_state == SimNPC.TASK_STATE_TRAVELING and caretaker.has_travel_target and caretaker.travel_target_position.is_equal_approx( zora_node.get_interaction_position() ) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and zora_state.get_reserved_by() == caretaker.id and ( _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker.id).size() == 1 ) and _events_for(manager, SimulationIds.EVENT_ANIMAL_FED, caretaker.id).is_empty() ), "The save point should be after one real pickup and before the exact goat delivery", ) _arrive_at_current_target(manager, view, caretaker) var continuation_ticks := int(ceil(caretaker.task_duration)) for _tick in range(continuation_ticks): manager.simulate_tick() var uninterrupted_checksum: String = manager.get_state_checksum() var uninterrupted_feed_events := _events_for( manager, SimulationIds.EVENT_ANIMAL_FED, caretaker_id ) _check( ( uninterrupted_feed_events.size() == 1 and ( _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker_id).size() == 1 ) ), "The uninterrupted control should finish with one pickup and one feed", ) _check( manager.restore_state_from_json(midpoint_json), "A post-pickup in-progress feed state should pass the complete save schema", ) _freeze_visuals(view) caretaker = _find_npc(manager.npcs, caretaker_id) pantry = manager.get_pantry() zora_state = manager.animal_care.get_state(SimulationIds.ANIMAL_ZORA) var restored_visual := _get_visual(view, caretaker_id) var restored_carried_food := _get_carried_food(view, caretaker_id) _check( ( caretaker != null and pantry != null and zora_state != null and manager.get_state_checksum() == midpoint_checksum and caretaker.position.is_equal_approx(midpoint_position) and caretaker.travel_target_position.is_equal_approx(midpoint_destination) and caretaker.current_task == SimulationIds.ACTION_FEED_ANIMAL and caretaker.task_state == SimNPC.TASK_STATE_TRAVELING and caretaker.target_id == SimulationIds.ANIMAL_ZORA and caretaker.has_travel_target and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0) and is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), midpoint_pantry) and zora_state.get_reserved_by() == caretaker_id and restored_visual != null and restored_visual.global_position.is_equal_approx(midpoint_position) and restored_visual.get("current_target") == midpoint_destination and restored_carried_food != null and restored_carried_food.visible and ( _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker_id).size() == 1 ) and _events_for(manager, SimulationIds.EVENT_ANIMAL_FED, caretaker_id).is_empty() ), "Restore should retain exact claim, route, carried food, pickup history, and checksum", ) if caretaker == null: await _unload_world(main_scene) return _arrive_at_current_target(manager, view, caretaker) for _tick in range(continuation_ticks): manager.simulate_tick() var restored_feed_events := _events_for(manager, SimulationIds.EVENT_ANIMAL_FED, caretaker_id) _check( ( manager.get_state_checksum() == uninterrupted_checksum and ( _events_for(manager, SimulationIds.EVENT_STORAGE_WITHDRAWN, caretaker_id).size() == 1 ) and restored_feed_events.size() == 1 and _is_exact_feed( restored_feed_events[0], caretaker_id, SimulationIds.ANIMAL_ZORA, zora_state, ) and is_equal_approx(caretaker.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0) and is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), midpoint_pantry) ), "Restored continuation should match uninterrupted state without replaying either transfer", ) await _unload_world(main_scene) func _load_world() -> Dictionary: var main_scene: Node = load("res://main.tscn").instantiate() root.add_child(main_scene) await process_frame for _frame in 3: await physics_frame var manager: Node = main_scene.get_node("SimulationManager") manager.set_process(false) var view: Node = main_scene.get_node("WorldViewManager") _freeze_visuals(view) return {"main": main_scene, "manager": manager, "view": view} func _unload_world(main_scene: Node) -> void: main_scene.queue_free() await process_frame await physics_frame func _prepare_population(manager: Node, view: Node) -> void: for npc in manager.npcs: manager.release_npc_reservation(npc.id) npc.inventory.clear() npc.hunger = 20.0 npc.energy = 100.0 npc.is_starving = false npc.starvation_ticks = 0 npc.set_task(SimulationIds.ACTION_WANDER, 1000.0) npc.start_working() ( manager . emit_signal( "npc_inventory_changed", npc, SimulationIds.RESOURCE_FOOD, npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD), ) ) _freeze_visuals(view) func _prepare_feed_task(manager: Node, view: Node, npc: SimNPC, origin: Vector3) -> void: manager.release_npc_reservation(npc.id) npc.inventory.clear() npc.target_id = &"" npc.has_travel_target = false npc.position = origin npc.set_task(SimulationIds.ACTION_FEED_ANIMAL) var visual := _get_visual(view, npc.id) if visual != null: visual.global_position = origin manager.synchronize_npc_position(npc.id, origin) func _set_pantry_food(manager: Node, amount: float) -> void: var pantry: StorageStateRecord = manager.get_pantry() ( pantry . withdraw( SimulationIds.RESOURCE_FOOD, pantry.get_amount(SimulationIds.RESOURCE_FOOD), ) ) pantry.deposit(SimulationIds.RESOURCE_FOOD, amount) manager.economy.sync_resource(SimulationIds.RESOURCE_FOOD) func _arrive_at_current_target(manager: Node, view: Node, npc: SimNPC) -> void: var visual := _get_visual(view, npc.id) if visual != null: visual.set_physics_process(false) visual.global_position = npc.travel_target_position manager.synchronize_npc_position(npc.id, npc.travel_target_position) manager.notify_npc_arrived(npc.id) func _freeze_visuals(view: Node) -> void: for visual in view.active_npc_visuals.values(): visual.set_physics_process(false) func _get_visual(view: Node, npc_id: int) -> Node3D: return view.active_npc_visuals.get(npc_id) as Node3D func _get_carried_food(view: Node, npc_id: int) -> MeshInstance3D: var visual := _get_visual(view, npc_id) if visual == null: return null return visual.get_node("CarriedFood") as MeshInstance3D func _find_npc(npcs: Array[SimNPC], npc_id: int) -> SimNPC: for npc in npcs: if npc.id == npc_id: return npc return null func _find_npc_record(records: Array[NPCStateRecord], npc_id: int) -> NPCStateRecord: for record in records: if int(record.data["id"]) == npc_id: return record return null func _events_for( manager: Node, event_type: StringName, actor_id: int ) -> Array[EconomicEventRecord]: var matching: Array[EconomicEventRecord] = [] for event in manager.economic_events: if ( StringName(event.data["event_type"]) == event_type and int(event.data["actor_id"]) == actor_id ): matching.append(event) return matching func _events_of_type(manager: Node, event_type: StringName) -> Array[EconomicEventRecord]: var matching: Array[EconomicEventRecord] = [] for event in manager.economic_events: if StringName(event.data["event_type"]) == event_type: matching.append(event) return matching func _is_exact_withdrawal( event: EconomicEventRecord, actor_id: int, pantry_position: Vector3 ) -> bool: return ( event != null and int(event.data["actor_id"]) == actor_id and StringName(event.data["source_id"]) == SimulationIds.STORAGE_VILLAGE_PANTRY and (StringName(event.data["destination_id"]) == SimulationIds.npc_inventory_id(actor_id)) and StringName(event.data["item_id"]) == SimulationIds.RESOURCE_FOOD and is_equal_approx(float(event.data["amount"]), 1.0) and event.get_world_position().is_equal_approx(pantry_position) ) func _is_exact_feed( event: EconomicEventRecord, actor_id: int, animal_id: StringName, animal_state: AnimalStateRecord, ) -> bool: return ( event != null and animal_state != null and int(event.data["actor_id"]) == actor_id and StringName(event.data["source_id"]) == SimulationIds.npc_inventory_id(actor_id) and StringName(event.data["destination_id"]) == animal_id and StringName(event.data["item_id"]) == SimulationIds.RESOURCE_FOOD and is_equal_approx(float(event.data["amount"]), 1.0) and event.get_world_position().is_equal_approx(animal_state.get_position()) ) func _check(condition: bool, message: String) -> void: if not condition: failures.append(message) func _finish() -> void: if failures.is_empty(): print("[TEST] Animal food delivery passed") quit(0) return for failure in failures: push_error("[TEST] " + failure) quit(1)