extends SceneTree var failures: Array[String] = [] func _initialize() -> void: call_deferred("_run") func _run() -> void: var manager: Node = load("res://simulation/SimulationManager.gd").new() manager.debug_logs = false root.add_child(manager) manager.set_process(false) var pantry: StorageStateRecord = manager.get_pantry() pantry.withdraw(SimulationIds.RESOURCE_FOOD, 1000.0) manager._sync_village_food() var resource := ResourceStateRecord.from_dictionary({ "schema_version": ResourceStateRecord.SCHEMA_VERSION, "node_id": "food_loop_bush", "action_id": String(SimulationIds.ACTION_GATHER_FOOD), "resource_id": String(SimulationIds.RESOURCE_FOOD), "amount_remaining": 10.0, "yield_per_action": 2.0, "reserved_by": -1, "enabled": true, "can_npcs_use": true, "can_player_use": true }) manager.resource_states[resource.get_node_id()] = resource var npc: SimNPC = manager.npcs[0] npc.hunger = 20.0 npc.energy = 100.0 npc.set_task(SimulationIds.ACTION_GATHER_FOOD, 1.0) npc.target_id = resource.get_node_id() resource.reserve(npc.id) npc.start_working() manager.simulate_tick() _check( is_equal_approx(resource.get_amount_remaining(), 8.0) and is_equal_approx( npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 2.0 ), "Gathering should move food from the source into NPC inventory" ) _check( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), 0.0), "Gathering should not teleport food into storage" ) manager.simulate_tick() _check( npc.current_task == SimulationIds.ACTION_DEPOSIT_FOOD, "Carried food should select the deposit action" ) manager.notify_npc_arrived(npc.id) manager.simulate_tick() _check( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), 2.0) and is_equal_approx( npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0 ), "Deposit should transfer carried food into the pantry" ) npc.hunger = 80.0 manager.simulate_tick() _check( npc.current_task == SimulationIds.ACTION_WITHDRAW_FOOD, "Hungry NPC should retrieve food from storage" ) manager.notify_npc_arrived(npc.id) manager.simulate_tick() _check( is_equal_approx(pantry.get_amount(SimulationIds.RESOURCE_FOOD), 1.0) and is_equal_approx( npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 1.0 ), "Withdraw should transfer pantry food into NPC inventory" ) manager.simulate_tick() _check( npc.current_task == SimulationIds.ACTION_EAT, "NPC carrying food should select eat" ) manager.notify_npc_arrived(npc.id) var hunger_before_eating := npc.hunger manager.simulate_tick() manager.simulate_tick() _check( npc.hunger < hunger_before_eating and is_equal_approx( npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD), 0.0 ), "Eating should consume carried food and reduce hunger" ) var conserved_food := ( resource.get_amount_remaining() + pantry.get_amount(SimulationIds.RESOURCE_FOOD) + npc.get_inventory_amount(SimulationIds.RESOURCE_FOOD) ) _check( is_equal_approx(conserved_food, 9.0), "Exactly one food unit should leave the world when eaten" ) if failures.is_empty(): print("[TEST] Food storage loop passed") quit(0) return for failure in failures: push_error("[TEST] " + failure) quit(1) func _check(condition: bool, message: String) -> void: if not condition: failures.append(message)