From 83fc258afca0db2230f3ea2413bd6b305886991f Mon Sep 17 00:00:00 2001 From: Rijad Zuzo Date: Sat, 4 Jul 2026 19:55:30 +0200 Subject: [PATCH] docs: establish simulation architecture gate --- docs/BUILD_IN_PUBLIC_PLAN.md | 73 ++++++++++++------ docs/LEARNING_ROADMAP.md | 77 +++++++++++++++---- docs/PROJECT_CONTEXT.md | 58 +++++++++++--- docs/README.md | 30 ++++++++ docs/RESOURCE_NODE_MIGRATION.md | 21 +++-- .../0001-simulation-authority-boundary.md | 73 ++++++++++++++++++ docs/decisions/README.md | 12 +++ 7 files changed, 288 insertions(+), 56 deletions(-) create mode 100644 docs/README.md create mode 100644 docs/decisions/0001-simulation-authority-boundary.md create mode 100644 docs/decisions/README.md diff --git a/docs/BUILD_IN_PUBLIC_PLAN.md b/docs/BUILD_IN_PUBLIC_PLAN.md index e943906..09aa766 100644 --- a/docs/BUILD_IN_PUBLIC_PLAN.md +++ b/docs/BUILD_IN_PUBLIC_PLAN.md @@ -9,6 +9,10 @@ The immediate visual goal is to replace the flat prototype presentation with a small, attractive, watchable environment while preserving the working NPC simulation, player controls, UI, task lifecycle, and navigation behavior. +This is a scoped visual-production plan. Milestone order and architecture gates +are owned by [the learning roadmap](LEARNING_ROADMAP.md); simulation authority +is governed by [ADR 0001](decisions/0001-simulation-authority-boundary.md). + Before runtime terrain integration, food and wood should migrate from abstract zones to actual finite world objects according to [the ResourceNode migration plan](RESOURCE_NODE_MIGRATION.md). This prevents the @@ -62,9 +66,9 @@ Main └── UI ``` -The player and `WorldViewManager` reference the task markers through exported -`NodePath` values. `NpcVisual` relies on the navigation map to reach those -markers. +The player and `WorldViewManager` still reference non-resource activity markers +through exported `NodePath` values. `NpcVisual` relies on the navigation map to +reach both those markers and ResourceNode interaction points. Replacing the ground without respecting those references would break behavior that already works. @@ -89,9 +93,7 @@ Main │ │ └── ResourceNodes │ │ ├── BerryBush instances │ │ └── Tree instances -│ ├── LegacyTaskMarkers temporary migration fallback -│ │ ├── FarmZone fallback only -│ │ ├── ForestZone fallback only +│ ├── LegacyTaskMarkers temporary non-resource activities │ │ ├── FoodZone │ │ ├── GuardZone │ │ ├── StudyZone @@ -250,7 +252,7 @@ This becomes both a regression reference and excellent before/after material. There is a reproducible baseline showing the existing flat prototype and its working behaviors. -### Systems prerequisite — Migrate food and wood targets +### Systems prerequisite — Migrate food and wood targets ✅ complete Implement and validate the first ResourceNodes on the current flat map before moving the playable runtime onto Terrain3D: @@ -263,7 +265,7 @@ moving the playable runtime onto Terrain3D: - extraction after work completion; - depletion and replanning; - actual extracted amount applied to the village; -- zone fallback with visible warnings. +- player interaction through the same extraction contract. Keep the other task zones temporarily. Rest, eating, study, and patrol will eventually use activity, storage, or workstation targets rather than pretending @@ -335,6 +337,29 @@ The final navigation bake still happens after terrain and props stabilize. One static frame contains the ridge landmark, roofs, river/waterfall, and village work area. A test agent can traverse the intended task loop. +### Systems gate — Harden simulation authority + +After the scaffold, greybox, and navigation spike prove the world shape, pause +visual production and complete the mandatory architecture gate from the +learning roadmap: + +- deterministic clock and seeded randomness; +- fixed-seed headless scenarios and final-state checksum; +- versioned serializable NPC, village, and resource records; +- 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. + +Do not solve this by moving simulation ownership into `JajceWorld`. The +environment remains a presentation and active-world query surface. + +### Exit condition + +The same scenario produces the same result without `main.tscn`; unloading a +visual does not change authoritative state; current resource and movement +behavior still pass regression tests. + ### Phase 3 — Establish the beauty baseline Add only the highest-value presentation: @@ -366,7 +391,7 @@ Once the world composition is stable: 2. Disable or remove the old flat world only after the new instance is present. 3. Place or move bushes and trees under `JajceWorld/WorldObjects/ResourceNodes` while preserving stable IDs. -4. Reconnect remaining player and `WorldViewManager` fallbacks to markers under +4. Reconnect only remaining non-resource activity markers under `JajceWorld/LegacyTaskMarkers`. 5. Bake navigation for the new walkable area. 6. Test each existing task from multiple spawn positions. @@ -538,25 +563,25 @@ The follow-up milestone is complete when: - cinematic and debug views can show the same real scenario; - a repeatable public-demo clip shows an autonomous cause and consequence; - performance and navigation regressions are measured and documented. +- the mandatory architecture gate passes before final beauty integration. ## Immediate implementation order 1. Capture the current flat-map baseline. -2. Implement and validate ResourceNodes on the flat map. -3. Migrate food and wood; keep remaining zones as logged fallbacks. -4. Create `JajceWorld.tscn`. -5. Create dedicated Terrain3D data under `terrain/jajce/`. -6. Create `JajceLookdev.tscn` and its beauty camera. -7. Sculpt the ridge, river valley, terraces, and waterfall drop. -8. Place ResourceNodes and only the still-required legacy markers. -9. Block out the fortress, houses, mill, and bridge. -10. Run the early navigation spike. -11. Establish terrain materials, lighting, water, mist, and foliage. -12. Capture “Jajce Lookdev 01.” -13. Instance `JajceWorld` into `main.tscn`. -14. Reconnect fallbacks, rebake navigation, and regression-test the simulation. -15. Add profession/readability presentation. -16. Capture “Simulation Garden 01.” +2. Treat ResourceNode migration and player parity as complete. +3. Create `JajceWorld.tscn` and dedicated Terrain3D data. +4. Create `JajceLookdev.tscn` and its beauty camera. +5. Greybox the ridge, river valley, terraces, and waterfall drop. +6. Place ResourceNodes with stable IDs and only required activity markers. +7. Block out the fortress, houses, mill, and bridge. +8. Run the early navigation spike. +9. Pass the mandatory architecture gate before beauty production. +10. Establish terrain materials, lighting, water, mist, and foliage. +11. Capture “Jajce Lookdev 01.” +12. Instance `JajceWorld` into `main.tscn`. +13. Reconnect activity markers, rebake navigation, and run regression scenarios. +14. Add profession/readability presentation and the reason inspector. +15. Capture “Simulation Garden 01.” Do not start with GIS data, a full city, a large asset pack, or more NPC mechanics. The next proof is a beautiful stage for the systems that already diff --git a/docs/LEARNING_ROADMAP.md b/docs/LEARNING_ROADMAP.md index 7ee3dc3..7febc20 100644 --- a/docs/LEARNING_ROADMAP.md +++ b/docs/LEARNING_ROADMAP.md @@ -28,6 +28,31 @@ Each milestone should produce five outcomes: Do not advance because files exist. Advance when the exit test passes. +The current implementation has completed ResourceNode migration through player +parity. Next, build only the minimal Jajce scaffold and navigation proof, then +pass the architecture gate below before beauty production or broader simulation +features. See [ADR 0001](decisions/0001-simulation-authority-boundary.md). + +## Mandatory architecture gate + +This gate sits between the first Jajce terrain/navigation proof and substantial +beauty work, inventories, schedules, relationships, or population growth. + +It requires: + +- an explicit deterministic simulation clock; +- controlled, seedable random streams; +- a headless fixed-seed scenario runner and final-state checksum; +- versioned serializable records for current NPC, village, and resource state; +- authoritative resource amounts and reservations outside scene nodes; +- stable action/profession IDs and initial definitions; +- separate action selection, execution, target resolution, and visual travel; +- an active-world adapter for navigation facts and NPC position synchronization. + +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. + ## Three vertical slices The long-term vision contains three major risks. Validate them separately before @@ -207,7 +232,8 @@ The staged replacement of abstract task zones begins with - ownership, storage, reservations, and transactions; - production recipes; - world interaction points; -- consistency and invariant testing. +- consistency and invariant testing; +- structured economic events as authoritative facts. ### Build @@ -226,9 +252,12 @@ Include: - abstract transfer for distant agents; - reservation and cancellation; - spoilage only if it improves the initial loop; -- player participation in the same resource rules. +- player participation in the same resource rules; +- structured gather, transfer, consume, deny, and depletion events carrying + stable actor, target, location, and resource IDs. -Add wood only after the food chain is coherent. +Wood extraction already exists. Do not build a deeper wood production chain +until the food chain is coherent. ### Reusable artifact @@ -548,26 +577,44 @@ At the end of each milestone, evaluate the system against this checklist: - Does it expose reason/debug information? - Do measurements justify its complexity? - Has at least one real gameplay feature exercised the API? +- Does persistent authority remain valid when its presentation node is absent? +- Can an active visual synchronize position without becoming the sole owner of + location state? Do not extract a plugin solely because a system might be reusable. Prefer a clear internal module until multiple real consumers establish a stable API. ## Recommended implementation order from the current repository +Completed foundations: + +- finite food and wood `ResourceNode` instances; +- NPC target selection, reservation, depletion, and authoritative yield; +- player parity through the same extraction contract; +- navigation-failure recovery and an initial headless contention scenario. + The practical next sequence is: -1. Add simulation controls and an NPC reason inspector. -2. Add finite berry bushes and trees through the first `ResourceNode`. -3. Migrate food target selection, reservation, depletion, and actual yield. -4. Introduce an explicit deterministic simulation clock and seed. -5. Replace remaining free-form task strings with action IDs/definitions. -6. Separate action selection, action execution, and visual travel. -7. Migrate wood and give the player the same extraction contract. -8. Build the first location-based food storage/inventory. -9. Make one NPC visibly gather, carry, store, retrieve, and eat food. -10. Build the first attractive Terrain3D simulation-garden layout. -11. Add simple stylized characters and profession readability. -12. Add save/load before the mutable world state becomes substantially larger. +1. Capture a reproducible flat-map baseline. +2. Create only the minimal `JajceWorld` scaffold, terrain greybox, navigation + spike, and stable-ID resource-placement proof. +3. Begin the architecture gate with deterministic clock/randomness, a headless + scenario runner, final-state checksums, and serializable state records. +4. Move resource amount/reservation authority out of `ResourceNode` scenes. +5. Replace free-form task and profession strings with stable IDs and + definitions. +6. Separate action selection, execution, target resolution, and visual travel; + remove decision mutation from `WorldViewManager`. +7. Define active-position synchronization and prove visual unload/reload. +8. Pass the architecture gate's deterministic headless and unloaded-visual exit + tests. +9. Build location-based food storage, inventory, and transactions. +10. Emit structured economic events while making one NPC visibly gather, carry, + store, retrieve, and eat food. +11. Add versioned save/load before schedules or social state expand. +12. Resume the attractive Terrain3D simulation-garden beauty pass. +13. Add stylized character and profession readability plus the reason + inspector. This order strengthens the simulation while regularly producing visible progress suitable for public development updates. diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 4c0d1c5..6ab0c57 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -2,9 +2,11 @@ > Agent-facing context for understanding the project quickly. > -> Snapshot basis: repository state after commit `b8752f8`, July 2026. Treat the +> Snapshot basis: repository state after commit `0900022`, July 2026. Treat the > code as the source of truth when this document and the implementation differ. +See the [documentation map](README.md) for the authority and scope of each plan. + ## Quick orientation **The Steward** is currently a small Godot prototype for an embodied village @@ -358,9 +360,11 @@ creation, and some gameplay API responsibilities. `WorldViewManager` bridges simulation data to visible NPC nodes. It: - instantiates `NpcVisual` scenes; -- maps task strings to world markers; +- resolves resource nodes, random wander targets, and remaining activity + markers; +- writes the selected ResourceNode ID onto the NPC as a transitional behavior; - sends targets to visuals; -- reports arrival back to `SimulationManager`; +- reports arrival and navigation failure back to `SimulationManager`; - applies visual death state. ### `player/npc/NpcVisual.gd` @@ -376,7 +380,8 @@ creation, and some gameplay API responsibilities. ### `player/player.gd` and `player/camera_rig.gd` These implement camera-relative character movement, physical interaction -proximity checks, mouse capture, and the elevated follow camera. +proximity checks, ResourceNode harvesting, mouse capture, and the elevated +follow camera. ### `world/ui/ui.gd` @@ -500,6 +505,26 @@ Use four conceptual layers: Do not make the simulation core depend on `Node3D`, scene paths, animation, physics frames, or a currently loaded map. +The authoritative-boundary decision is recorded in +[ADR 0001](decisions/0001-simulation-authority-boundary.md). The current +`ResourceNode` state and `WorldViewManager` target selection are transitional, +not patterns to extend into inventories, schedules, or relationships. + +### Authority and active-world adapters + +Persistent mutable state belongs in versioned, serializable simulation records. +Systems mutate those records. Godot nodes: + +- present nearby records; +- expose active-world interaction transforms and navigation results; +- translate player input into simulation commands; +- synchronize active position through an explicit adapter; +- never become the only owner of a persistent amount, reservation, action, or + identity. + +Target selection may consume facts supplied by the active world, but the +presentation bridge must not author an NPC's decision or persistent target. + ### Stable identity Every persistent entity should eventually have a stable ID: @@ -649,14 +674,25 @@ The project has two interleaved tracks. Every major systems milestone should produce a shareable visual behavior. Every visual milestone should support or reveal actual simulation state. -## Immediate milestone: the simulation garden +## Immediate milestone: scaffold, architecture gate, then simulation garden -Before integrating Terrain3D into the playable runtime, migrate food and wood -from abstract zones to finite resource nodes on the current flat test map. This -keeps target-selection and resource-conservation debugging separate from terrain -and navigation changes. +Food and wood migration on the flat test map is complete. The next visual step +is a deliberately minimal `JajceWorld` scaffold, greybox, navigation spike, and +resource-placement proof. Do not proceed directly from that proof into +open-ended beauty production. -The next coherent visual slice should then aim for: +After the scaffold proves terrain and navigation, complete the architecture +gate: + +- deterministic clock and controlled random source; +- fixed-seed headless scenarios with final-state checksums; +- versioned serializable NPC, village, and resource state; +- 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: - one attractive valley section; - six named villagers; @@ -713,6 +749,8 @@ These remain part of the vision, not the next implementation target. 11. Use Conventional Commits. 12. Update these documents when a decision materially changes the vision, architecture, milestones, or current-state description. +13. Follow the authority order in [the documentation map](README.md); do not + let a focused visual or migration plan silently redefine system ownership. ## Definition of “reusable for the future game” diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..6704ad7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,30 @@ +# Documentation map + +The project uses a small hierarchy so overlapping plans do not become competing +sources of truth. + +1. [`PROJECT_CONTEXT.md`](PROJECT_CONTEXT.md) is the canonical description of + the vision, current implementation, target architecture, and active + constraints. +2. [`LEARNING_ROADMAP.md`](LEARNING_ROADMAP.md) owns milestone order, + architecture gates, reusable-system exit tests, and intentionally deferred + work. +3. [`BUILD_IN_PUBLIC_PLAN.md`](BUILD_IN_PUBLIC_PLAN.md) owns the scoped Jajce + visual slice. It must respect the architecture gates in the learning + roadmap. +4. [`RESOURCE_NODE_MIGRATION.md`](RESOURCE_NODE_MIGRATION.md) is a focused + migration plan. Phases 1–4 are complete; its Phase 5 hands world placement to + the visual-slice plan. +5. [`decisions/`](decisions/) contains durable architectural decisions, + including consequences and revisit conditions. + +When documents disagree: + +- code and tests describe current behavior; +- the newest accepted decision record governs architecture; +- `PROJECT_CONTEXT.md` governs product intent; +- `LEARNING_ROADMAP.md` governs what should be built next; +- focused plans govern only their stated scope. + +Update the smallest relevant set of documents after a decision or milestone. +Do not copy full status tables into every plan. diff --git a/docs/RESOURCE_NODE_MIGRATION.md b/docs/RESOURCE_NODE_MIGRATION.md index 5883fd2..9d52501 100644 --- a/docs/RESOURCE_NODE_MIGRATION.md +++ b/docs/RESOURCE_NODE_MIGRATION.md @@ -112,7 +112,7 @@ type proves what is actually common. ## Fit with the current code -The existing flow is: +Before this migration, the flow was: ```text SimNPC chooses a task string @@ -124,7 +124,7 @@ SimNPC chooses a task string -> SimVillage applies a hard-coded task result ``` -The migrated flow should become: +The migrated flow is: ```text SimNPC chooses an action @@ -139,15 +139,16 @@ SimNPC chooses an action -> reservation is released ``` -During migration: +Current target behavior: ```text -gather_food -> prefer matching ResourceNode -> fallback FarmZone -gather_wood -> prefer matching ResourceNode -> fallback ForestZone +gather_food -> matching ResourceNode -> recover/wander when unavailable +gather_wood -> matching ResourceNode -> recover/wander when unavailable other tasks -> existing zones ``` -Fallbacks should log clearly so accidental reliance on zones is visible. +Food and wood zone fallback was deliberately removed to preserve resource +conservation. ## Repository-specific file layout @@ -472,6 +473,12 @@ authoritative-yield rules. ### Phase 5 — Jajce world placement +This phase is a bounded handoff to +[the build-in-public visual plan](BUILD_IN_PUBLIC_PLAN.md), not permission for +open-ended environment polish. Complete the scaffold, placement, and navigation +proof, then pass the learning roadmap's architecture gate before the beauty +baseline. + - place bushes and trees as real world objects in `JajceWorld`; - keep their IDs stable; - validate interaction points against terrain and navigation; @@ -516,7 +523,7 @@ At minimum, exercise: 7. NPC dies while working; 8. navigation fails; 9. node is disabled while reserved; -10. fallback zone is used because no matching node exists; +10. no matching node causes recovery without zone production; ✅ implemented 11. player and NPC contend for the same source; ✅ automated 12. duplicate node IDs are detected. diff --git a/docs/decisions/0001-simulation-authority-boundary.md b/docs/decisions/0001-simulation-authority-boundary.md new file mode 100644 index 0000000..5ba1614 --- /dev/null +++ b/docs/decisions/0001-simulation-authority-boundary.md @@ -0,0 +1,73 @@ +# ADR 0001: Serializable simulation state is authoritative + +- **Status:** Accepted +- **Date:** 2026-07-04 + +## Context + +The prototype correctly separates `SimNPC` from `NpcVisual`, but authority is +still split across simulation records and scene nodes: + +- `ResourceNode` owns remaining amount and reservations; +- `WorldViewManager` resolves targets and writes the chosen target ID onto an + NPC; +- `SimulationManager` combines time, orchestration, action completion, player + commands, and event publication; +- the visual position of an active NPC can diverge from its stored simulation + position. + +This is workable for one loaded flat map. It does not support reliable +save/load, unloaded locations, deterministic replay, simulation fidelity +changes, or a large data-only population. + +## Decision + +Persistent mutable gameplay state will move into versioned, serializable +records owned by a `WorldState`-style simulation model. + +- Definitions contain immutable action, profession, need, item, and location + data. +- State records contain people, resources, inventories, reservations, + locations, current actions, and later relationships and history. +- Systems are the only layer that authoritatively mutates those records. +- Godot world nodes present records and provide active-world facts such as + interaction transforms, navigation results, collision, and animation. +- Presentation adapters may submit commands and query results, but may not + choose actions or directly author persistent state. +- References between records use stable IDs, never `Node`, `NodePath`, or scene + ownership. +- Active-world position must synchronize through an explicit adapter so + unloading a visual does not erase or redefine the NPC's location. + +The simulation core must be runnable headlessly with a fixed clock, controlled +random streams, and no dependency on a loaded gameplay scene. + +## Staged migration + +1. Add a deterministic clock, seeded random source, and scenario runner. +2. Introduce serializable village, NPC, and resource-state records. +3. Bind `ResourceNode` presentation to resource records instead of owning + authoritative amount and reservation. +4. 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. +6. Add versioned save/load before inventories, schedules, or relationships + substantially expand mutable state. + +## Consequences + +- Some current prototype APIs are transitional and should not be generalized + as final architecture. +- The Jajce scaffold may proceed far enough to validate terrain, navigation, + and world-object placement, but beauty production pauses at the architecture + gate. +- New persistent features must define their state record and save behavior. +- Headless scenarios become the preferred regression surface for simulation + rules. + +## Revisit when + +Revisit this decision only if measured prototype work shows that a different +authority model materially simplifies deterministic persistence and simulation +LOD without coupling rules to loaded scenes. diff --git a/docs/decisions/README.md b/docs/decisions/README.md new file mode 100644 index 0000000..d59ba63 --- /dev/null +++ b/docs/decisions/README.md @@ -0,0 +1,12 @@ +# Architecture decisions + +Decision records capture choices that should survive individual implementation +plans. Use the next sequential number and include: + +- context and problem; +- decision; +- consequences; +- staged migration, if needed; +- conditions for revisiting the decision. + +Do not create records for routine edits or choices that are still exploratory.