Give every NPC a race and class, resolved at spawn time

NPCs can now optionally specify race and class in their TOML. When
omitted, race is randomly selected from non-hidden races and class is
determined by the race's default_class or picked randomly from
compatible non-hidden classes. Race/class are re-rolled on each
respawn for NPCs without fixed values, so killing the barkeep may
bring back a different race next time.

New hidden content (excluded from character creation):
- Beast race: for animals (rats, etc.) with feral stats and no
  equipment slots
- Peasant class: weak default for humanoid NPCs
- Creature class: default for beasts/animals

Existing races gain default_class fields (humanoids → peasant,
beast → creature, dragon → random compatible). Look and examine
commands now display NPC race and class.

Made-with: Cursor
This commit is contained in:
AI Agent
2026-03-14 16:32:27 -06:00
parent 598360ac95
commit 7b6829b1e8
17 changed files with 240 additions and 38 deletions

View File

@@ -84,11 +84,21 @@ src/
2. Currently: hostile NPCs auto-engage players in their room
3. Add new behaviors there (e.g. NPC movement, dialogue triggers)
### New NPC
1. Create `world/<region>/npcs/<name>.toml`
2. Optional `race` and `class` fields pin the NPC to a specific race/class
3. If omitted, race is randomly chosen from non-hidden races at spawn time
4. If class is omitted, the race's `default_class` is used; if that's also unset, a random non-hidden class is picked
5. Race/class are re-rolled on each respawn for NPCs without fixed values
6. For animals: use `race = "race:beast"` and `class = "class:creature"`
### New race
1. Create `world/races/<name>.toml` — see `dragon.toml` for a complex example
2. Required: `name`, `description`
3. All other fields have sensible defaults via `#[serde(default)]`
4. Key sections: `[stats]` (7 stats), `[body]` (size, weight, slots), `[natural]` (armor, attacks), `[resistances]`, `[regen]`, `[misc]`, `[guild_compatibility]`
5. Set `hidden = true` for NPC-only races (e.g., `beast`) to exclude from character creation
6. Set `default_class` to reference a class ID for the race's default NPC class
5. `traits` and `disadvantages` are free-form string arrays
6. If `[body] slots` is empty, defaults to humanoid slots
7. Natural attacks: use `[natural.attacks.<name>]` with `damage`, `type`, optional `cooldown_ticks`