feat: add npc decision inspector
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user