docs: establish simulation architecture gate

This commit is contained in:
2026-07-04 19:55:30 +02:00
parent 0900022558
commit 83fc258afc
7 changed files with 288 additions and 56 deletions
+49 -24
View File
@@ -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
+62 -15
View File
@@ -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.
+48 -10
View File
@@ -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”
+30
View File
@@ -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 14 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.
+14 -7
View File
@@ -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.
@@ -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.
+12
View File
@@ -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.