docs: mark resource node phase 4 complete

This commit is contained in:
2026-07-04 19:48:15 +02:00
parent 326df51cbe
commit 0900022558
2 changed files with 36 additions and 21 deletions
+13 -5
View File
@@ -208,8 +208,9 @@ plugin content, not game architecture.
- WASD movement is camera-relative. - WASD movement is camera-relative.
- The elevated third-person camera rotates with the mouse and uses smoothed - The elevated third-person camera rotates with the mouse and uses smoothed
follow/focus behavior. follow/focus behavior.
- Pressing `E` near a task zone directly contributes food, wood, safety, or - Pressing `E` near a berry bush or tree extracts its configured yield into the
knowledge, or consumes village food. village through the same `ResourceNode` contract used by NPCs.
- Guard, study, and food interactions still use their temporary task zones.
- `Escape` releases captured mouse input. - `Escape` releases captured mouse input.
### Village simulation ### Village simulation
@@ -300,9 +301,12 @@ primitive geometry and a few tree assets.
**Migration status:** NPC `gather_food` and `gather_wood` no longer use the **Migration status:** NPC `gather_food` and `gather_wood` no longer use the
farm and forest zones. They target `ResourceNode` instances (berry bushes and farm and forest zones. They target `ResourceNode` instances (berry bushes and
trees) instead. The zone markers remain for: trees) instead. The zone markers remain for:
- Player interaction (pressing E near farm/forest zones adds resources)
- Non-resource NPC tasks (patrol → guard_zone, study → study_zone, rest → rest_zone, eat → food_zone) - Non-resource NPC tasks (patrol → guard_zone, study → study_zone, rest → rest_zone, eat → food_zone)
The player also harvests food and wood directly from nearby `ResourceNode`
instances. Extraction returns the actual amount removed, updates the village by
that amount, and releases an NPC reservation if the source is depleted.
Storage, rest, study, and guard behavior should later migrate to target types Storage, rest, study, and guard behavior should later migrate to target types
that match their actual semantics rather than treating every usable object as a that match their actual semantics rather than treating every usable object as a
resource source. resource source.
@@ -437,6 +441,8 @@ NpcVisual navigates through the active world
│ ├── SimNPC.gd │ ├── SimNPC.gd
│ ├── SimVillage.gd │ ├── SimVillage.gd
│ └── SimulationManager.gd │ └── SimulationManager.gd
├── tests/
│ └── resource_node_player_parity_test.gd
├── world/ ├── world/
│ ├── resource_nodes/ │ ├── resource_nodes/
│ │ ├── ResourceNode.gd │ │ ├── ResourceNode.gd
@@ -453,11 +459,13 @@ NpcVisual navigates through the active world
These are expected prototype constraints, not necessarily isolated bugs: These are expected prototype constraints, not necessarily isolated bugs:
- Task names and task-to-zone mappings are duplicated strings. - Task names and task-to-zone mappings are duplicated strings.
- Task zones remain for non-resource tasks and player interaction; gather food/wood NPCs use ResourceNode instances instead. - Task zones remain for non-resource activities; NPC and player food/wood
gathering use `ResourceNode` instances.
- Mutable simulation state is not serializable through a defined save schema. - Mutable simulation state is not serializable through a defined save schema.
- Randomness is not seeded for deterministic replay. - Randomness is not seeded for deterministic replay.
- Simulation time depends on `_process` and a scene-tree node. - Simulation time depends on `_process` and a scene-tree node.
- There is no automated test or headless simulation harness. - Automated coverage currently contains one headless player-parity and
resource-contention scenario; broader simulation coverage is still missing.
- Resources are global floating-point counters rather than items in locations - Resources are global floating-point counters rather than items in locations
and inventories. and inventories.
- NPCs do not have homes, schedules, possessions, memories, relationships, - NPCs do not have homes, schedules, possessions, memories, relationships,
+23 -16
View File
@@ -8,13 +8,13 @@
| **2** | Food target selection + reservation | ✅ Complete | | **2** | Food target selection + reservation | ✅ Complete |
| **3** | Authoritative extraction on completion | ✅ Complete | | **3** | Authoritative extraction on completion | ✅ Complete |
| **4a** | Wood target selection (NPC) | ✅ Complete | | **4a** | Wood target selection (NPC) | ✅ Complete |
| **4b** | Player parity (extraction contract) | ⏳ Not started | | **4b** | Player parity (extraction contract) | ✅ Complete |
| **5** | Jajce world placement | ❌ Not started | | **5** | Jajce world placement | ❌ Not started |
| **6** | Remove remaining zone model | ❌ Not started | | **6** | Remove remaining zone model | ❌ Not started |
### Key divergences from the original plan ### Key divergences from the original plan
- **Zone fallback removed** (Phase 3): `gather_food`/`gather_wood` no longer fall back to `FarmZone`/`ForestZone` markers when no resource node is available. The original plan called for a logged fallback; instead, the NPC goes idle (via `navigation_failed` → wander) to guarantee resource conservation. The zone markers are still available for player interaction. - **Zone fallback removed** (Phase 3): `gather_food`/`gather_wood` no longer fall back to `FarmZone`/`ForestZone` markers when no resource node is available. The original plan called for a logged fallback; instead, the NPC goes idle (via `navigation_failed` → wander) to guarantee resource conservation. Player harvesting also uses resource nodes; remaining zones serve only non-resource activities.
- **`navigation_failed` signal** (discovered during Phase 4): Added a separate signal pathway to distinguish genuine arrival from navigation failure. The original plan treated all "arrivals" uniformly. - **`navigation_failed` signal** (discovered during Phase 4): Added a separate signal pathway to distinguish genuine arrival from navigation failure. The original plan treated all "arrivals" uniformly.
- **Stale-path prevention** (discovered during Phase 4): Added `path_request_id` + `path_pending` to reject async path results that arrive after a new target was set or the NPC died. - **Stale-path prevention** (discovered during Phase 4): Added `path_request_id` + `path_pending` to reject async path results that arrive after a new target was set or the NPC died.
- **Duplicate node_id detection** (discovered during Phase 4): Added startup validation that disables nodes with duplicate IDs and pushes an error. - **Duplicate node_id detection** (discovered during Phase 4): Added startup validation that disables nodes with duplicate IDs and pushes an error.
@@ -34,6 +34,7 @@
| 9 | Empty-path re-entrancy: immediate arrival report caused re-entrant signal chain | Phase 4 | Defer to `stuck_counter`/`stuck_time` in `_physics_process` instead | | 9 | Empty-path re-entrancy: immediate arrival report caused re-entrant signal chain | Phase 4 | Defer to `stuck_counter`/`stuck_time` in `_physics_process` instead |
| 10 | Stale async path: `await physics_frame` result used after target or death changed | Phase 4 | `path_request_id`/`path_pending` guard | | 10 | Stale async path: `await physics_frame` result used after target or death changed | Phase 4 | `path_request_id`/`path_pending` guard |
| 11 | Stolen extraction: NPC extracted from node after reservation was lost | Phase 4 | Guard extraction with `node.reserved_by == npc.id` | | 11 | Stolen extraction: NPC extracted from node after reservation was lost | Phase 4 | Guard extraction with `node.reserved_by == npc.id` |
| 12 | Depleted target retained an NPC reservation after player harvesting | Phase 4 | `ResourceNode.extract()` now releases its reservation on depletion |
## Decision ## Decision
@@ -445,7 +446,7 @@ total bush decrease == total village food increase
for the initial gather-food scenario. for the initial gather-food scenario.
### 🔶 Phase 4 — Wood and player parity *(partially complete)* ### Phase 4 — Wood and player parity *[complete]*
**Wood migration** ✅ complete: **Wood migration** ✅ complete:
- `gather_wood` uses `ResourceNode.find_available("gather_wood")` in WVM - `gather_wood` uses `ResourceNode.find_available("gather_wood")` in WVM
@@ -453,14 +454,21 @@ for the initial gather-food scenario.
- Extraction follows same path as food (reserve → travel → work → extract → village resource delta) - Extraction follows same path as food (reserve → travel → work → extract → village resource delta)
- Zone fallback removed; NPC goes idle if no tree available - Zone fallback removed; NPC goes idle if no tree available
**Player parity** ⏳ not started: **Player parity** ✅ complete:
- Player currently still uses zone-marker interaction in `player.gd` - Player interaction resolves the nearest player-usable resource node by its
- Player should use `ResourceNode.extract()` via proximity detection or raycast interaction point.
- Player interaction bypasses reservation (player presses E at a node → extract if available) - `SimulationManager.harvest_resource_node()` uses the same authoritative
- `PlayerInteraction.gd` exists as an empty stub `ResourceNode.extract()` contract and applies exactly the returned amount.
- Player harvesting can contend with an NPC reservation; depletion releases
that reservation so the NPC can recover cleanly.
- Depleted and disabled targets provide explicit feedback.
- Food and forest zone bindings were removed from the player.
- `tests/resource_node_player_parity_test.gd` verifies food conservation, wood
conservation, depletion, and player/NPC contention.
**Updated exit:** food and wood no longer require their abstract zones during **Exit:** food and wood no longer require their abstract zones during normal
normal play *for NPCs*. Player parity is required to fully exit this phase. play. NPC and player extraction obey the same availability, depletion, and
authoritative-yield rules.
### Phase 5 — Jajce world placement ### Phase 5 — Jajce world placement
@@ -509,7 +517,7 @@ At minimum, exercise:
8. navigation fails; 8. navigation fails;
9. node is disabled while reserved; 9. node is disabled while reserved;
10. fallback zone is used because no matching node exists; 10. fallback zone is used because no matching node exists;
11. player and NPC contend for the same source; 11. player and NPC contend for the same source; ✅ automated
12. duplicate node IDs are detected. 12. duplicate node IDs are detected.
Use a fixed seed and concise reason tracing where possible. Use a fixed seed and concise reason tracing where possible.
@@ -542,14 +550,14 @@ resource conservation through debug presentation.
| 9 | Apply actual extracted yield on completion | ✅ Done | `c6033b6` | | 9 | Apply actual extracted yield on completion | ✅ Done | `c6033b6` |
| 10 | Add navigation failure handling (replaces regression scenarios) | ✅ Done | `b8752f8` | | 10 | Add navigation failure handling (replaces regression scenarios) | ✅ Done | `b8752f8` |
| 11 | Migrate wood | ✅ Done | `c6033b6`, `8049c52` | | 11 | Migrate wood | ✅ Done | `c6033b6`, `8049c52` |
| 12 | Give the player the same extraction path | ⏳ Not started | — | | 12 | Give the player the same extraction path | ✅ Done | `326df51` |
| 13 | Continue with the Jajce world scaffold | ❌ Not started | — | | 13 | Continue with the Jajce world scaffold | ❌ Not started | — |
## Definition of done for the first migration ## Definition of done for the first migration
| Criterion | Status | | Criterion | Status |
|-----------|--------| |-----------|--------|
| Food and wood use actual finite world objects | ✅ (NPCs) / ⏳ (player) | | Food and wood use actual finite world objects | ✅ |
| NPCs select available targets and reserve them | ✅ | | NPCs select available targets and reserve them | ✅ |
| NPC state stores stable target IDs rather than nodes or scene paths | ✅ | | NPC state stores stable target IDs rather than nodes or scene paths | ✅ |
| Active visuals navigate to explicit interaction points | ✅ | | Active visuals navigate to explicit interaction points | ✅ |
@@ -558,6 +566,5 @@ resource conservation through debug presentation.
| Depletion changes availability and presentation | ✅ | | Depletion changes availability and presentation | ✅ |
| Failure, interruption, and death release reservations | ✅ | | Failure, interruption, and death release reservations | ✅ |
| Old food and forest zone fallbacks are no longer used by NPCs | ✅ (fallback removed by design) | | Old food and forest zone fallbacks are no longer used by NPCs | ✅ (fallback removed by design) |
| The player and NPCs can use the same extraction contract | ⏳ (player side not started) | | The player and NPCs can use the same extraction contract | |
| Behavior is inspectable and covered by reproducible scenarios | ✅ (debug logging, debug overlay on nodes) | | Behavior is inspectable and covered by reproducible scenarios | ✅ (debug logging, node overlay, headless player-parity test) |