docs: mark resource authority phase complete

This commit is contained in:
2026-07-05 13:26:26 +02:00
parent 363620b731
commit 12f9ba616f
6 changed files with 61 additions and 45 deletions
+9 -4
View File
@@ -18,6 +18,9 @@
- **`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.
- **Duplicate node_id detection** (discovered during Phase 4): Added startup validation that disables nodes with duplicate IDs and pushes an error.
- **Simulation-owned resource authority** (architecture gate): Resource amount,
reservation, and enabled state now live in `ResourceStateRecord`; ResourceNode
binds by stable ID and can unload without deleting authoritative state.
### Bugs found and fixed
@@ -33,8 +36,8 @@
| 8 | `Variant as StringName`: invalid cast | Phase 2-3 | Check for `null` on Dictionary `.get()` instead of casting |
| 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 |
| 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 |
| 11 | Stolen extraction: NPC extracted after reservation was lost | Phase 4 | Guard extraction with the authoritative resource record's reservation |
| 12 | Depleted target retained an NPC reservation after player harvesting | Phase 4 | Authoritative extraction now releases its reservation on depletion |
## Decision
@@ -451,7 +454,8 @@ for the initial gather-food scenario.
### ✅ Phase 4 — Wood and player parity *[complete]*
**Wood migration** ✅ complete:
- `gather_wood` uses `ResourceNode.find_available("gather_wood")` in WVM
- `gather_wood` resolves loaded presentation candidates through
`SimulationManager.acquire_resource_target()`
- Tree_01 (15 wood, yield 3.0) and Tree_02 (12 wood, yield 3.0) placed
- Extraction follows same path as food (reserve → travel → work → extract → village resource delta)
- Zone fallback removed; NPC goes idle if no tree available
@@ -460,7 +464,8 @@ for the initial gather-food scenario.
- Player interaction resolves the nearest player-usable resource node by its
interaction point.
- `SimulationManager.harvest_resource_node()` uses the same authoritative
`ResourceNode.extract()` contract and applies exactly the returned amount.
`ResourceStateRecord.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.