docs: add NPC statistics system design
Two-tier stat system (Physical + Personality) using 3d6 generation, transient modifiers, slow baseline drift, and integration points for needs decay, brain, and social systems. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# NPC Statistics System Design
|
||||
|
||||
## Overview
|
||||
|
||||
Add a two-tier stat system to NPCs: Physical stats (RPG-rooted) and Personality stats (emotion/behavior-driven). Stats use GURPS-style 3d6 generation (range 3-18, bell curve centered ~10.5). Stats influence needs decay rates, brain decisions, and social interaction outcomes.
|
||||
|
||||
## Stat Definitions
|
||||
|
||||
### Physical Stats (3d6, range 3-18)
|
||||
|
||||
| Stat | Governs |
|
||||
|------|---------|
|
||||
| **Strength** | Carry capacity, physical task output, melee outcomes |
|
||||
| **Dexterity** | Movement speed modifier, dodge/craft precision |
|
||||
| **Constitution** | Needs decay rates (high = slower drain), recovery speed |
|
||||
| **Intelligence** | Learning rate (baseline drift speed), task efficiency |
|
||||
| **Perception** | Awareness radius for social detection, noticing events |
|
||||
|
||||
### Personality Stats (3d6, range 3-18)
|
||||
|
||||
| Stat | Governs |
|
||||
|------|---------|
|
||||
| **Sociability** | Likelihood of initiating social interactions, cooldown reduction |
|
||||
| **Courage** | Willingness to explore unknown areas, resistance to fleeing |
|
||||
| **Curiosity** | Tendency to wander far vs. stay near, goal variety |
|
||||
| **Empathy** | Social outcome bias (positive), responsiveness to others' needs |
|
||||
| **Temperament** | Emotional stability; high = calm, low = volatile. Scales transient modifier magnitude |
|
||||
|
||||
## Data Model
|
||||
|
||||
### Stats Component
|
||||
|
||||
```typescript
|
||||
export interface Stats {
|
||||
// Physical
|
||||
strength: number;
|
||||
dexterity: number;
|
||||
constitution: number;
|
||||
intelligence: number;
|
||||
perception: number;
|
||||
// Personality
|
||||
sociability: number;
|
||||
courage: number;
|
||||
curiosity: number;
|
||||
empathy: number;
|
||||
temperament: number;
|
||||
}
|
||||
```
|
||||
|
||||
### Transient Modifiers Component
|
||||
|
||||
```typescript
|
||||
export interface StatModifier {
|
||||
stat: keyof Stats;
|
||||
value: number; // additive (+/-)
|
||||
remaining: number; // ticks remaining
|
||||
}
|
||||
|
||||
export interface StatModifiers {
|
||||
modifiers: StatModifier[];
|
||||
}
|
||||
```
|
||||
|
||||
**Effective stat** = base stat + sum of active modifiers, clamped to 3-18.
|
||||
|
||||
### Generation
|
||||
|
||||
Roll 3d6 per stat at spawn. Pure bell curve, no rerolls or point-buy.
|
||||
|
||||
### Baseline Drift
|
||||
|
||||
- Base stats stored as floats internally, floored to integer for effective value
|
||||
- Stat-relevant events shift base by tiny amounts (e.g., +0.05)
|
||||
- Drift capped to 3-18 range
|
||||
- Noticeable over hundreds of interactions, not minutes
|
||||
|
||||
### Wire Protocol
|
||||
|
||||
Stats sent as part of `EntityState` as effective (computed) integer values. Modifiers stay server-side only.
|
||||
|
||||
## System Integration
|
||||
|
||||
### New System: `statModifierSystem`
|
||||
|
||||
Runs each tick **before** needsDecay. System order becomes:
|
||||
|
||||
`statModifier` -> `needsDecay` -> `npcBrain` -> `social` -> `movement` -> `broadcast`
|
||||
|
||||
Responsibilities per tick:
|
||||
1. Decay modifiers (decrement `remaining`, remove expired)
|
||||
2. Apply needs-based modifiers (replace, not stack)
|
||||
3. Provide `getEffectiveStat()` helper for other systems
|
||||
|
||||
### Needs Decay (Constitution)
|
||||
|
||||
```
|
||||
effectiveDecay = BASE_DECAY * (1 - (constitution - 10) * 0.03)
|
||||
```
|
||||
|
||||
CON 14 = 12% slower decay. CON 6 = 12% faster. CON 10 = unchanged.
|
||||
|
||||
### NPC Brain (Curiosity, Courage)
|
||||
|
||||
- **Curiosity** influences wander target selection (high = farther/more varied destinations)
|
||||
- **Courage** is a future hook for threat response (no immediate behavior change)
|
||||
|
||||
### Social System (Sociability, Empathy, Perception, Temperament)
|
||||
|
||||
- **Perception** modifies awareness radius: `AWARENESS_RADIUS + (perception - 10)`
|
||||
- **Sociability** modifies global cooldown: `SOCIAL_GLOBAL_COOLDOWN * (1 - (sociability - 10) * 0.04)`
|
||||
- **Empathy** biases outcomes: `positiveChance = 0.5 + (empathy - 10) * 0.03`
|
||||
- **Temperament** scales modifier magnitude: `modifierValue * (1 + (10 - temperament) * 0.05)`
|
||||
|
||||
### Modifier Sources
|
||||
|
||||
**Needs-based (ongoing, replaced each tick):**
|
||||
- Low hunger (<30): Intelligence -2, Sociability -1
|
||||
- Low energy (<20): Dexterity -2, Temperament -2
|
||||
|
||||
**Event-based (decaying):**
|
||||
- Positive social outcome: Sociability +1 for 100 ticks
|
||||
- Negative social outcome: Sociability -1, Empathy -1 for 100 ticks
|
||||
|
||||
### Baseline Drift Triggers
|
||||
|
||||
- Successful social interaction: Sociability +0.05, Empathy +0.05
|
||||
- Negative social interaction: Temperament +0.02
|
||||
- Long wander completed: Curiosity +0.03, Courage +0.02
|
||||
- Eating/resting: Constitution +0.01
|
||||
|
||||
## UI
|
||||
|
||||
Stats displayed numerically in the NpcInfoPanel alongside existing needs bars. Future iteration will move to descriptive labels (e.g., "Strong", "Shy").
|
||||
Reference in New Issue
Block a user