feat: add npc decision inspector

This commit is contained in:
2026-07-05 23:50:18 +02:00
parent 7edf9acd57
commit d883148132
16 changed files with 305 additions and 13 deletions
+11
View File
@@ -53,6 +53,17 @@ func _test_selection_and_execution_are_separate() -> void:
selection.action_id == SimulationIds.ACTION_WITHDRAW_FOOD,
"Selection should independently choose food retrieval"
)
_check(
not selection.reason.is_empty(),
"Selection should expose the real decision branch for presentation"
)
npc.hunger = 20.0
npc.energy = 80.0
var work_selection := selector.select_action(npc, village)
_check(
work_selection.scores.size() == 4,
"Ordinary work selection should expose all compared utility scores"
)
func _test_target_resolution_and_travel_are_separate() -> void:
+28
View File
@@ -16,10 +16,38 @@ func _run() -> void:
var manager: Node = main_scene.get_node("SimulationManager")
var view: Node = main_scene.get_node("WorldViewManager")
var ui: CanvasLayer = main_scene.get_node("UI")
manager.set_process(false)
var npc: SimNPC = manager.npcs[0]
var visual: Node3D = view.active_npc_visuals[npc.id]
visual.set_physics_process(false)
var profession_definition := SimulationDefinitions.get_profession(npc.profession)
var body: MeshInstance3D = visual.get_node("MeshInstance3D")
_check(
body.material_override.albedo_color == profession_definition.visual_color,
"NPC body color should come from its profession definition"
)
_check(
visual.get_node("ProfessionProp").mesh != null
and profession_definition.display_name in visual.get_node("ProfessionLabel").text,
"NPC visual should expose a profession prop and readable label"
)
var test_decision := ActionSelectionResult.new(
SimulationIds.ACTION_GATHER_FOOD,
-1.0,
"Test shortage reason",
{SimulationIds.ACTION_GATHER_FOOD: 4.5}
)
manager.latest_decisions[npc.id] = test_decision
manager.emit_signal("npc_decision_recorded", npc, test_decision)
var inspector_label: Label = ui.get_node(
"NpcInspectorPanel/MarginContainer/NpcInspectorLabel"
)
_check(
"Test shortage reason" in inspector_label.text
and npc.npc_name in inspector_label.text,
"NPC inspector should show the selected villager's real decision reason"
)
var carried_food: MeshInstance3D = visual.get_node("CarriedFood")
_check(not carried_food.visible, "NPC should begin without a carried-food prop")
npc.add_inventory(SimulationIds.RESOURCE_FOOD, 1.0)
+9 -1
View File
@@ -38,11 +38,19 @@ func _test_registry_integrity() -> void:
var profession_ids := SimulationDefinitions.get_profession_ids()
_check(profession_ids.size() == 5, "Registry should contain all five prototype professions")
var profession_colors := {}
for profession_id in profession_ids:
var profession := SimulationDefinitions.get_profession(profession_id)
_check(
SimulationDefinitions.get_profession(profession_id) != null,
profession != null,
"Profession lookup should return '%s'" % profession_id
)
if profession != null:
profession_colors[profession.visual_color.to_html()] = true
_check(
profession_colors.size() == profession_ids.size(),
"Each profession should have a distinct definition-backed visual color"
)
func _test_definition_backed_behavior() -> void: