docs: add resource, tool & invention system design

Design for LLM-driven emergent crafting and invention system.
NPCs gather resources from terrain, craft at workshops, and
occasionally have eureka moments where an LLM invents new items.
Updates LLM roadmap: this becomes item 2.2, old goal selection
splits into 2.5 (POI naming).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-08 20:37:20 +00:00
parent 87946bcb5c
commit 69c36e776b
2 changed files with 315 additions and 7 deletions
@@ -43,11 +43,17 @@
- [ ] Memory feeds into prompt context for all LLM features
- [ ] **Status:** NOT STARTED
### 2.2 LLM-Driven Goal Selection
- [ ] Expanded action/behavior system (craft, explore, seek company, avoid, investigate)
- [ ] Location/POI system (named places worth visiting)
- [ ] LLM picks from structured action menu based on personality + context
- [ ] **Status:** NOT STARTED
### 2.2 Resource, Tool & Invention System
- [ ] Map generation: water features, stone deposits, tree clusters as harvestable terrain
- [ ] Item/recipe registries (global singletons) with seed data (log, stone, water, axe, hammer)
- [ ] NPC inventory component + productivity need (drives gather/craft/build behavior)
- [ ] Industry system: gatheringSystem, craftingSystem, buildingSystem
- [ ] Buildable structures: stockpiles (resource storage) and workshops (crafting stations)
- [ ] Invention system: LLM-driven eureka moments create new items/resources/workshops
- [ ] Structured JSON output from LLM with validation pipeline
- [ ] Invention timeline + "Most Inventive" superlative
- [ ] **Design:** [resource-tool-invention-design.md](2026-03-08-resource-tool-invention-design.md)
- [ ] **Status:** DESIGNED, NOT STARTED
### 2.3 Emergent Gossip / Information Spread
- [ ] NPCs share information during social interactions
@@ -60,6 +66,12 @@
- [ ] LLM summarizes relationship arc for info panel
- [ ] **Status:** NOT STARTED
### 2.5 Location/POI Naming & LLM Goal Selection
- [ ] Location/POI system (named places worth visiting)
- [ ] LLM picks from structured action menu based on personality + context
- [ ] Builds on industry system goals (gather/craft/build) with social goals (seek company, avoid)
- [ ] **Status:** NOT STARTED
---
## Tier 3: World-Level Integration (Higher Infrastructure)
@@ -101,8 +113,10 @@
| `.env` config | 1.1 | All |
| NPC event memory | 2.1 | 1.3, 1.4, 2.2, 2.3, 2.4, 3.3 |
| Async text delivery to client | 1.3 | 1.3, 1.4, 2.4 |
| Expanded action system | 2.2 | 2.2 |
| Location/POI naming | 2.2 | 2.2, 3.1 |
| Item/recipe registries | 2.2 | 2.2, 3.1 |
| Industry systems (gather/craft/build) | 2.2 | 2.2, 2.5 |
| Invention system + LLM JSON output | 2.2 | 2.2 |
| Location/POI naming | 2.5 | 2.5, 3.1 |
| Knowledge graph | 2.3 | 2.3, 3.2 |
| World state aggregation | 3.1 | 3.1, 3.2 |
| Story state machine | 3.3 | 3.3 |
@@ -0,0 +1,294 @@
# Resource, Tool & Invention System Design
**Date:** 2026-03-08
**Status:** Approved design, not yet implemented
**LLM Roadmap Position:** Tier 2, Item 2.2
---
## Overview
A modular resource gathering, crafting, and LLM-driven invention system. NPCs gather raw resources from terrain, craft tools and materials at workshops, and occasionally have "eureka moments" where the LLM invents new items from existing materials. All inventions are emergent — no predefined tech tree.
## Architecture: Approach A (Flat Component Model)
Global registries (World singletons) for item/recipe definitions. Per-NPC inventory and industry state as ECS components. Structures (stockpiles, workshops) as ECS entities with position.
---
## Data Model
### Global Registries (World Singletons)
**ItemRegistry** — all known item types:
```ts
interface ItemDefinition {
id: string; // e.g. 'log', 'stone', 'wooden_axe'
name: string; // display name
description: string; // flavor text
category: 'resource' | 'tool' | 'material' | 'structure';
sourceTiles?: string[]; // for resources: which terrain types yield this (e.g. ['water', 'dirt'] for clay)
source: 'seed' | 'invented';
inventedBy?: { entityId: EntityId; name: string; tick: number; day: number };
}
```
**RecipeRegistry** — all known recipes:
```ts
interface Recipe {
id: string; // e.g. 'craft_wooden_axe'
outputItemId: string; // what it produces
outputQuantity: number;
inputs: { itemId: string; quantity: number }[];
workshopType?: string; // required workshop type (null = hand-craftable)
toolRequired?: string; // required tool in NPC inventory (null = no tool needed)
source: 'seed' | 'invented';
}
```
**InventionTimeline** — chronological log:
```ts
interface InventionEntry {
itemId: string;
inventorEntityId: EntityId;
inventorName: string;
tick: number;
day: number;
}
```
### Per-NPC Components
- **`inventory`**: `Map<string, number>` — itemId to quantity
- **`industryState`**: `{ productivity: number; currentTask: IndustryTask | null; taskTimer: number }`
- `productivity`: 0-100 need that decays like hunger/energy, motivates gathering/crafting
- `currentTask`: what the NPC is currently doing (gather/craft/build + details)
- `taskTimer`: ticks remaining on current task
### Needs Extension
The existing `Needs` interface gets a new `productivity` field (0-100, decays over time). When low, NPCs prioritize industry tasks over wandering.
### Structure Entities
Stockpiles and workshops are world entities with:
- `position` component — tile location
- `structure` component:
```ts
{
type: 'stockpile' | 'workshop';
subtype: string; // e.g. 'general', 'workbench', 'kiln'
inventory: Map<string, number>; // stored items (for stockpiles)
buildProgress?: number; // 0-1, undefined = complete
builderEntityId?: EntityId;
}
```
---
## Seed Data (Bootstrap)
### Resources (hardcoded at world start)
| ID | Name | Category | Source Tiles |
|----|------|----------|-------------|
| `log` | Log | resource | tree tiles |
| `stone` | Stone | resource | stone tiles |
| `water` | Water | resource | water tiles |
### Recipes (hardcoded at world start)
| ID | Output | Inputs | Workshop |
|----|--------|--------|----------|
| `craft_wooden_axe` | wooden_axe | 2 log, 1 stone | none (hand) |
| `craft_hammer` | hammer | 2 log, 1 stone | none (hand) |
| `build_stockpile` | stockpile | 4 log | none |
| `build_workbench` | workbench | 3 log, 2 stone | none |
### Seed Items (tools)
| ID | Name | Category |
|----|------|----------|
| `wooden_axe` | Wooden Axe | tool |
| `hammer` | Hammer | tool |
---
## Systems
### System Execution Order (updated)
```
statModifier → needsDecay → npcBrain → social → narration →
relationship → industry → gathering → crafting → invention →
movement → broadcast
```
### industrySystem
- Manages the `productivity` need (decays like hunger/energy)
- When productivity is low and no urgent needs (hunger/energy OK), NPC decides what to do:
- **Gather**: pick a resource type, path to nearest source tile
- **Craft**: pick a recipe they can make, path to appropriate workshop
- **Build**: if a needed structure doesn't exist, build one
- Decision influenced by stats:
- **intelligence**: crafting preference, recipe selection
- **curiosity**: exploration/new resource discovery bonus
- **strength**: gathering speed bonus
- **dexterity**: crafting speed bonus
- Sets `currentGoal` in npcBrain to `'gather'` / `'craft'` / `'build'`
### gatheringSystem
- When NPC arrives at a resource tile with goal `'gather'`:
- Extract resource (tree tile → log, stone tile → stone, water tile → water)
- Timer-based: takes N ticks per unit (modified by strength)
- Add to NPC inventory
- Productivity need recovers while actively gathering
- After gathering, if NPC inventory has items and a stockpile exists, path to stockpile to drop off
### craftingSystem
- When NPC is at a workshop with goal `'craft'`:
- Check recipe inputs against workshop inventory + NPC inventory
- Consume inputs, produce output after timer (modified by dexterity)
- Productivity recovers while crafting
### inventionSystem
- Runs periodically (every ~100 ticks, not every tick)
- For each NPC, small chance of "eureka moment":
- Base chance: ~0.5% per check
- Multipliers: intelligence (scaled 3-18 → 0.5x-2x), curiosity (similar), recent activity (must have gathered or crafted recently)
- NPC must have exposure to materials (items in inventory or recently used)
- On eureka: queue LLM call with context
- On success: register new item + recipe, add to timeline, queue narration event
- Track invention count per NPC for "Most Inventive" superlative
### buildingSystem
- When NPC needs a workshop/stockpile that doesn't exist:
- Pick walkable location near current position
- Create structure entity with `buildProgress: 0`
- NPC works on it (consuming required resources) until progress reaches 1.0
- Basic stockpile: costs 4 logs
- Workbench: costs 3 logs + 2 stone
- Invented workshops: costs defined by their recipe
---
## LLM Integration
### Invention Prompt
Context provided to LLM:
- Available materials: list of all items in the world (with categories)
- NPC context: name, personality stats (INT, CUR), backstory, recent activities
- Existing inventions: to avoid duplicates
- Game context: "medieval/fantasy village simulation"
Instruction: "Invent something new that could be made from 2-3 of the available materials. Return JSON."
### Expected Output Format
For crafted items:
```json
{
"name": "rope",
"description": "Twisted plant fibers that can bind things together",
"category": "material",
"inputs": [{"itemId": "log", "quantity": 2}],
"workshopType": null,
"toolRequired": null
}
```
For discovered resources:
```json
{
"name": "clay",
"description": "Malleable earth found near riverbanks",
"category": "resource",
"inputs": [],
"sourceTiles": ["water", "dirt"],
"workshopType": null
}
```
For new workshops:
```json
{
"name": "kiln",
"description": "A stone furnace for firing clay and smelting",
"category": "structure",
"inputs": [{"itemId": "stone", "quantity": 5}, {"itemId": "clay", "quantity": 3}],
"workshopType": null
}
```
### Validation Pipeline
1. Parse JSON (retry once on parse failure)
2. Check all input itemIds exist in registry
3. Check name doesn't collide with existing items (case-insensitive)
4. Check category is valid enum value
5. If `sourceTiles` specified, validate tile types exist
6. If `workshopType` specified, check workshop type exists
7. On pass: register new item + recipe, add to timeline, emit narration event
### Invention Chaining
Once new items exist, they appear in future invention prompts. This enables emergent tech chains:
- log + stone → axe
- log + log → rope (LLM discovers)
- log + rope → fishing rod (LLM discovers)
- stone + stone + clay → kiln (LLM discovers, after clay is found)
- clay + kiln → pottery (LLM discovers)
---
## Map Generation Prerequisites
The current map generator produces only grass terrain. Before implementing the resource system, the map generator needs:
1. **Water features**: ponds/rivers using Terrain.WATER
2. **Stone deposits**: new terrain type (Terrain.STONE) or decoration-based stone tiles
3. **Tree clusters**: already have tree canopy/trunk decorations, need to mark tree tiles as resource sources
This is a prerequisite implementation task.
---
## Superlative: Most Inventive
- Add `mostInventive: SuperlativeEntry | null` to `SuperlativesData`
- Computed from invention timeline: count entries per living NPC
- NPC with most inventions wins (minimum 1 to qualify)
---
## UI Considerations (future)
- Invention timeline panel (global view of all discoveries)
- NPC info panel: show inventory, current industry task
- Structure inspection: show workshop type, stored items
- Narration events for inventions ("Gwendolyn has invented the fishing rod!")
---
## LLM Roadmap Changes
This system is placed as **Tier 2, Item 2.2** on the LLM integration roadmap.
- **2.2** (new): Resource, Tool & Invention System (this design)
- **2.5** (new): Location/POI Naming (remaining piece from old 2.2)
- Old 2.2's "expanded action/behavior system" is absorbed by the industry system
- Old 2.2's "LLM picks from structured action menu" concept is partially covered by invention system's goal selection
No conflicts with other roadmap items. Synergies:
- 2.1 (Event Memory): invention events feed into memory
- 2.3 (Gossip): future enhancement could spread invention knowledge per-NPC
- 3.1 (World Events): resource levels feed into world state aggregation