feat: runtime familiarity from shared work and utility exposure

NPCs who target the same resource or site concurrently gain mutual familiarity +0.1 per encounter, capped at 1.0. Action selection now receives the full NPC array and adds a +0.3 utility bonus for actions that familiar NPCs are currently performing - NPCs gravitate toward their housemates' professions. Inspector shows the highest-familiarity NPC with a percentage score under the resource lines.
This commit is contained in:
2026-07-09 00:09:50 +02:00
parent fce5c533fe
commit 595d67724f
3 changed files with 56 additions and 5 deletions
+13 -3
View File
@@ -18,7 +18,7 @@ const WORK_BEGIN := 0.28
const WORK_END := 0.85
func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5) -> ActionSelectionResult:
func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5, all_npcs: Array = []) -> ActionSelectionResult:
if npc.is_dead:
return null
@@ -120,10 +120,10 @@ func select_action(npc: SimNPC, village: SimVillage, time_of_day: float = 0.5) -
SimulationIds.ACTION_WANDER, -1.0, "Discretionary wander"
)
return _choose_best_work_action(npc, village)
return _choose_best_work_action(npc, village, all_npcs)
func _choose_best_work_action(npc: SimNPC, village: SimVillage) -> ActionSelectionResult:
func _choose_best_work_action(npc: SimNPC, village: SimVillage, all_npcs: Array) -> ActionSelectionResult:
var scores := {
SimulationIds.ACTION_GATHER_FOOD:
_calculate_score(
@@ -170,6 +170,16 @@ func _choose_best_work_action(npc: SimNPC, village: SimVillage) -> ActionSelecti
0.75
)
}
for familiar_id in npc.familiarity:
if not familiar_id is int:
continue
var other_task: StringName
for other in all_npcs:
if other.id == familiar_id and not other.is_dead:
other_task = other.current_task
break
if other_task in scores:
scores[other_task] = float(scores[other_task]) + 0.3
var best_action := SimulationIds.ACTION_GATHER_FOOD
var best_score: float = scores[best_action]
for action_id in [