docs: mark resource authority phase complete
This commit is contained in:
@@ -361,7 +361,7 @@ learning roadmap:
|
||||
- deterministic clock and seeded randomness; ✅
|
||||
- fixed-seed headless scenarios and final-state checksum; ✅
|
||||
- versioned serializable NPC, village, resource, clock, and RNG records; ✅
|
||||
- resource amount and reservation authority outside scene nodes;
|
||||
- resource amount and reservation authority outside scene nodes; ✅
|
||||
- stable action/profession IDs and initial definitions;
|
||||
- separate action selection, execution, target resolution, and visual travel;
|
||||
- explicit active-position synchronization.
|
||||
|
||||
+18
-15
@@ -54,7 +54,7 @@ The gate is complete when the same scenario produces the same checksum without
|
||||
loading `main.tscn`, and loading or unloading a visual does not change
|
||||
authoritative NPC or resource state.
|
||||
|
||||
**Current progress:** the first two architecture slices are implemented:
|
||||
**Current progress:** the first three architecture slices are implemented:
|
||||
|
||||
- `SimulationClock` advances explicit fixed ticks while preserving remainder;
|
||||
- NPC decisions and visual wander requests use controlled per-NPC random
|
||||
@@ -65,10 +65,15 @@ authoritative NPC or resource state.
|
||||
clock, and RNG state;
|
||||
- a save-at-tick-24 continuation test matches an uninterrupted 48-tick
|
||||
checksum and rejects unsupported schema versions.
|
||||
- `SimulationManager` owns resource records and all amount/reservation
|
||||
mutation; ResourceNode binds by stable ID as presentation and interaction
|
||||
geometry;
|
||||
- an unload/rebind regression proves resource state remains authoritative while
|
||||
its scene node is absent.
|
||||
|
||||
The gate remains open. Scene-independent resource authority, stable
|
||||
definitions, responsibility separation, and visual load/unload invariance are
|
||||
still required. See [the simulation state schema](SIMULATION_STATE_SCHEMA.md).
|
||||
The gate remains open. Stable definitions, responsibility separation, and NPC
|
||||
visual load/unload invariance are still required. See
|
||||
[the simulation state schema](SIMULATION_STATE_SCHEMA.md).
|
||||
|
||||
## Three vertical slices
|
||||
|
||||
@@ -615,23 +620,21 @@ Completed foundations:
|
||||
|
||||
The practical next sequence is:
|
||||
|
||||
1. Move resource amount/reservation authority out of `ResourceNode` scenes and
|
||||
make unloaded resources remain in state.
|
||||
2. Replace free-form task and profession strings with stable IDs and
|
||||
1. Replace free-form task and profession strings with stable IDs and
|
||||
definitions.
|
||||
3. Separate action selection, execution, target resolution, and visual travel;
|
||||
2. Separate action selection, execution, target resolution, and visual travel;
|
||||
remove decision mutation from `WorldViewManager`.
|
||||
4. Define active-position synchronization and prove visual unload/reload.
|
||||
5. Pass the architecture gate's deterministic headless and unloaded-visual exit
|
||||
3. Define active-position synchronization and prove visual unload/reload.
|
||||
4. Pass the architecture gate's deterministic headless and unloaded-visual exit
|
||||
tests.
|
||||
6. Build location-based food storage, inventory, and transactions.
|
||||
7. Emit structured economic events while making one NPC visibly gather, carry,
|
||||
5. Build location-based food storage, inventory, and transactions.
|
||||
6. Emit structured economic events while making one NPC visibly gather, carry,
|
||||
store, retrieve, and eat food.
|
||||
8. Add save-slot persistence and explicit schema migrations before schedules
|
||||
7. Add save-slot persistence and explicit schema migrations before schedules
|
||||
or social state expand.
|
||||
9. Resume Terrain3D sculpting, runtime integration, and the simulation-garden
|
||||
8. Resume Terrain3D sculpting, runtime integration, and the simulation-garden
|
||||
beauty pass.
|
||||
10. Add stylized character and profession readability plus the reason
|
||||
9. Add stylized character and profession readability plus the reason
|
||||
inspector.
|
||||
|
||||
This order strengthens the simulation while regularly producing visible
|
||||
|
||||
+10
-10
@@ -434,7 +434,7 @@ NpcVisual navigates through the active world
|
||||
| Later ticks complete work
|
||||
| |
|
||||
| v
|
||||
| ResourceNode.extract() -> village.apply_resource_delta()
|
||||
| ResourceStateRecord.extract() -> village.apply_resource_delta()
|
||||
| |
|
||||
| v
|
||||
| village_changed signal updates the UI
|
||||
@@ -498,10 +498,10 @@ These are expected prototype constraints, not necessarily isolated bugs:
|
||||
- Task names and task-to-activity-marker mappings are duplicated strings.
|
||||
- Temporary activity markers remain for eating, rest, study, and patrol; NPC
|
||||
and player food/wood gathering use `ResourceNode` instances with no fallback.
|
||||
- Current NPC, village, loaded resource, clock, and RNG state serialize through
|
||||
schema v1, but there is no save-slot/file UX or backward migration yet.
|
||||
- Resource records currently mirror loaded ResourceNode state; the scene nodes
|
||||
still own live amounts and reservations.
|
||||
- Current NPC, village, resource, clock, and RNG state serialize through schema
|
||||
v1, but there is no save-slot/file UX or top-level backward migration yet.
|
||||
- Simulation-owned resource records retain live amounts, reservations, and
|
||||
usage definitions while ResourceNode scenes are unloaded.
|
||||
- An explicit fixed-step clock converts frame delta into simulation ticks, but
|
||||
orchestration still lives on the scene-tree `SimulationManager`.
|
||||
- Automated coverage includes deterministic same-seed and save/restore
|
||||
@@ -716,21 +716,21 @@ Food and wood migration and the deliberately minimal `JajceWorld` scaffold,
|
||||
greybox, navigation spike, and stable-ID placement proof are complete. Do not
|
||||
proceed directly from that proof into open-ended beauty production.
|
||||
|
||||
The architecture gate is now the active milestone. Its first two slices are
|
||||
The architecture gate is now the active milestone. Its first three slices are
|
||||
complete:
|
||||
|
||||
- explicit fixed-step simulation clock;
|
||||
- seeded per-NPC decision and wander random streams;
|
||||
- headless fixed-seed scenario with a final-state checksum;
|
||||
- versioned JSON records for NPC, village, loaded resource, clock, and RNG
|
||||
state;
|
||||
- deterministic save/restore continuation with exact 64-bit RNG preservation.
|
||||
- versioned JSON records for NPC, village, resource, clock, and RNG state;
|
||||
- deterministic save/restore continuation with exact 64-bit RNG preservation;
|
||||
- simulation-owned resource amount/reservation state with ResourceNode
|
||||
presentation binding and unload/rebind coverage.
|
||||
|
||||
The remaining gate work is:
|
||||
|
||||
- data-defined action and profession IDs;
|
||||
- separated action selection, execution, target resolution, and visual travel;
|
||||
- resource amount and reservation authority moved out of scene nodes;
|
||||
- explicit synchronization of active NPC position.
|
||||
|
||||
The coherent visual slice can then aim for:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -11,7 +11,8 @@ simulation. Schema v1 captures:
|
||||
starvation state, and decision RNG stream;
|
||||
- village resource counters;
|
||||
- controlled per-NPC wander RNG streams;
|
||||
- loaded ResourceNode amount, reservation, and enabled state.
|
||||
- scene-independent resource state plus the definition facts needed while its
|
||||
ResourceNode is unloaded.
|
||||
|
||||
The top-level identity is:
|
||||
|
||||
@@ -42,19 +43,26 @@ its future random sequence.
|
||||
4. running the remaining 24 ticks;
|
||||
5. requiring the complete final-state checksums to match.
|
||||
|
||||
It also verifies clock remainder, ResourceNode amount/reservation/enabled
|
||||
round-tripping, and rejection of unsupported schemas.
|
||||
It also verifies clock remainder, resource amount/reservation/enabled
|
||||
round-tripping, presentation unload/rebind, and rejection of unsupported
|
||||
schemas.
|
||||
|
||||
## Transitional resource boundary
|
||||
## Resource authority
|
||||
|
||||
Schema v1 can capture and restore loaded `ResourceNode` state, but the scene
|
||||
node still owns the live amount and reservation. That is transitional support,
|
||||
not the final authority model.
|
||||
`SimulationManager` owns `ResourceStateRecord` instances independently of the
|
||||
scene tree. Amount, reservation, enabled state, action/resource identity,
|
||||
yield, and usage permissions remain available and serializable while no
|
||||
ResourceNode is loaded.
|
||||
|
||||
The next architecture-gate phase moves those values into scene-independent
|
||||
resource records. ResourceNode will then bind to a record by stable ID and act
|
||||
as presentation plus an active-world interaction surface. An unloaded resource
|
||||
must remain simulated and serializable.
|
||||
ResourceNode binds to a record by stable ID and provides presentation,
|
||||
interaction transforms, and active-world discoverability. Unloading a node does
|
||||
not delete its record. Loading another node with the same stable ID rebinds to
|
||||
the existing record and cannot overwrite its amount or reservation with scene
|
||||
defaults.
|
||||
|
||||
ResourceStateRecord v2 adds the definition facts needed while unloaded. Nested
|
||||
v1 resource records are migrated explicitly and hydrate their missing
|
||||
definition from a matching presentation node when one becomes available.
|
||||
|
||||
## Deliberately out of scope
|
||||
|
||||
@@ -64,7 +72,7 @@ This phase does not yet provide:
|
||||
- backward migrations beyond schema v1;
|
||||
- inventory, relationship, schedule, or history records;
|
||||
- a player-facing load flow;
|
||||
- scene-independent resource authority.
|
||||
- save-slot persistence for scene-independent resource state.
|
||||
|
||||
Those features should build on this boundary rather than inventing parallel
|
||||
serialization paths.
|
||||
|
||||
@@ -46,9 +46,9 @@ random streams, and no dependency on a loaded gameplay scene.
|
||||
|
||||
1. ✅ Add a deterministic clock, seeded random source, and scenario runner.
|
||||
2. ✅ Introduce serializable village, NPC, and resource-state records.
|
||||
3. **Next:** Bind `ResourceNode` presentation to resource records instead of
|
||||
owning authoritative amount and reservation.
|
||||
4. Move target choice and reservation coordination out of
|
||||
3. ✅ Bind `ResourceNode` presentation to resource records instead of owning
|
||||
authoritative amount and reservation.
|
||||
4. **Next:** Move target choice and reservation coordination out of
|
||||
`WorldViewManager` into an action/target system with an active-world query
|
||||
adapter.
|
||||
5. Split action selection, execution, and presentation travel.
|
||||
|
||||
Reference in New Issue
Block a user