Town NPC
Classic needs-driven utility NPC. Three needs decaying at different rates. Demonstrates utility considerations + commit-time floor.
[ Example ]
Town NPC — eat, sleep, work
The simplest "real game" shape. A town NPC with three internal needs — Hunger, Fatigue, Work — that decay over time and compete for the agent's attention. Eat when hungry, sleep when tired, work otherwise. If you've ever played a Sims-like or a Stardew Valley NPC, the underlying pattern is exactly this.
Anatomy
Schema — DA_Schema_TownNPC
HungerScalar- Decay
- +0.01 / sec
FatigueScalar- Decay
- +0.005 / sec
WorkDoneScalar- Range
- 0.0 → 1.0
AtHomeBool- Source
- Distance-derived
AtWorkstationBool- Source
- Distance-derived
Goals — all priority 1.0, differentiated by considerations
DA_Goal_EatIntentGoal- Consideration
- smoothstep(0.2, 0.9, Hunger)
DA_Goal_SleepIntentGoal- Consideration
- smoothstep(0.3, 0.85, Fatigue)
DA_Goal_WorkIntentGoal- Consideration
- 1 - WorkDone (linear)
Actions
GoHomeIntentAction- Effect
- AtHome = true
EatIntentAction- Precondition
- AtHome
- Effect
- Hunger = 0
SleepIntentAction- Precondition
- AtHome
- Effect
- Fatigue = 0
GoToWorkstationIntentAction- Effect
- AtWorkstation = true
WorkIntentAction- Precondition
- AtWorkstation
- Effect
- +0.1 WorkDone
The response curves
Each goal's consideration is a scalar response curve — sigmoid-shaped (low when need is low, steep around 0.5, saturating to 1.0 when critical). This is what makes the NPC commit hard once a need passes the midpoint.
- Hunger:
smoothstep(0.2, 0.9, Hunger)— basically zero below 0.2, ramps up between 0.2 and 0.9, saturates at 1.0. - Fatigue: same shape, threshold 0.3/0.85.
- Work:
1 - WorkDone(linear) — pressure increases as the job remains undone.
The planner picks the goal with the highest scored output, and those response curves are what makes the NPC's behaviour feel reasonable rather than mechanical. When Hunger is at 0.5 and Fatigue is at 0.3, Hunger wins. When both are at 0.5 they're competing — and the goal momentum bonus (Family 1) breaks the tie in favor of whatever the NPC is currently doing.
Why this example is here
Three things you'll need for any "life-like" NPC:
- Utility considerations — how to express "this matters more as the value approaches its critical threshold".
- Commit-time floor — how to stop the NPC from abandoning meals mid-bite when scores hover near equal.
- Internal-state sensors — sensors that read from the component's own state (need timers), not from world geometry.