fix: enforce village resource invariants
This commit is contained in:
@@ -68,6 +68,20 @@ func _test_selection_and_execution_are_separate() -> void:
|
||||
work_selection.scores.size() == 4,
|
||||
"Ordinary work selection should expose all compared utility scores"
|
||||
)
|
||||
var guard := SimNPC.new(701, "BoundaryGuard", SimulationIds.PROFESSION_GUARD, 5.0, 5.0)
|
||||
guard.hunger = 20.0
|
||||
guard.energy = 80.0
|
||||
village.food = 100.0
|
||||
village.wood = 0.0
|
||||
village.safety = 0.0
|
||||
village.knowledge = 100.0
|
||||
village.update_modifiers()
|
||||
village.update_priorities()
|
||||
var unfunded_selection := selector.select_action(guard, village, 0.5)
|
||||
_check(
|
||||
unfunded_selection.action_id == SimulationIds.ACTION_GATHER_WOOD,
|
||||
"A guard should gather wood instead of selecting patrol when its material cost is unavailable"
|
||||
)
|
||||
|
||||
|
||||
func _test_target_resolution_and_travel_are_separate() -> void:
|
||||
|
||||
@@ -112,6 +112,7 @@ func _run() -> void:
|
||||
"Exactly one food unit should leave the world when eaten"
|
||||
)
|
||||
_check_economic_event_chain(manager)
|
||||
_test_wood_work_requires_material()
|
||||
|
||||
var restored: Node = load("res://simulation/SimulationManager.gd").new()
|
||||
restored.debug_logs = false
|
||||
@@ -179,3 +180,48 @@ func _check_economic_event_chain(manager: Node) -> void:
|
||||
),
|
||||
"Economic events should record exact transferred quantities"
|
||||
)
|
||||
|
||||
|
||||
func _test_wood_work_requires_material() -> void:
|
||||
var manager: Node = load("res://simulation/SimulationManager.gd").new()
|
||||
manager.debug_logs = false
|
||||
root.add_child(manager)
|
||||
manager.set_process(false)
|
||||
var woodpile: StorageStateRecord = manager.get_woodpile()
|
||||
woodpile.withdraw(SimulationIds.RESOURCE_WOOD, 1000.0)
|
||||
woodpile.deposit(SimulationIds.RESOURCE_WOOD, 0.5)
|
||||
manager._sync_village_wood()
|
||||
var npc: SimNPC = manager.npcs[0]
|
||||
var safety_before: float = manager.village.safety
|
||||
|
||||
npc.set_task(SimulationIds.ACTION_PATROL, 1.0)
|
||||
npc.start_working()
|
||||
manager.simulate_tick()
|
||||
_check(
|
||||
(
|
||||
is_equal_approx(manager.village.safety, safety_before)
|
||||
and is_equal_approx(woodpile.get_amount(SimulationIds.RESOURCE_WOOD), 0.5)
|
||||
),
|
||||
"Patrol should not consume partial wood or create safety when its full cost cannot be paid"
|
||||
)
|
||||
|
||||
manager.add_wood(1.5)
|
||||
_check(
|
||||
(
|
||||
is_equal_approx(woodpile.get_amount(SimulationIds.RESOURCE_WOOD), 2.0)
|
||||
and is_equal_approx(manager.village.wood, 2.0)
|
||||
),
|
||||
"Wood changes should update authoritative storage and the village projection"
|
||||
)
|
||||
var knowledge_before: float = manager.village.knowledge
|
||||
npc.set_task(SimulationIds.ACTION_STUDY, 1.0)
|
||||
npc.start_working()
|
||||
manager.simulate_tick()
|
||||
_check(
|
||||
(
|
||||
is_equal_approx(woodpile.get_amount(SimulationIds.RESOURCE_WOOD), 1.0)
|
||||
and manager.village.knowledge > knowledge_before
|
||||
),
|
||||
"Funded study should consume one wood and produce knowledge"
|
||||
)
|
||||
manager.free()
|
||||
|
||||
@@ -189,7 +189,7 @@ func _test_household_familiarity() -> void:
|
||||
manager.simulation_seed = 700
|
||||
manager.debug_logs = false
|
||||
manager.set_process(false)
|
||||
manager.home_positions = [
|
||||
var household_positions: Array[Vector3] = [
|
||||
Vector3(-15.0, 2.0, 7.0),
|
||||
Vector3(-15.0, 2.0, 8.0),
|
||||
Vector3(-8.5, 2.0, 3.0),
|
||||
@@ -197,6 +197,7 @@ func _test_household_familiarity() -> void:
|
||||
Vector3(20.0, 0.0, 20.0),
|
||||
Vector3(22.0, 0.0, 22.0)
|
||||
]
|
||||
manager.home_positions = household_positions
|
||||
root.add_child(manager)
|
||||
|
||||
var a: SimNPC = manager.npcs[0]
|
||||
|
||||
Reference in New Issue
Block a user