fix: empty-path re-entrancy, retry_count reset, := to = for Variant
This commit is contained in:
@@ -0,0 +1,563 @@
|
||||
# The Steward — Build-in-Public Visual Slice Plan
|
||||
|
||||
## Purpose
|
||||
|
||||
This plan adapts the proposed “Jajce simulation garden” to the repository as it
|
||||
exists now. It does not assume a blank project.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
new environment from being authored around a zone model already marked for
|
||||
removal.
|
||||
|
||||
The slice should make a viewer understand this promise quickly:
|
||||
|
||||
> A cozy Bosnian-inspired world where autonomous people visibly make decisions,
|
||||
> work, struggle, and create stories.
|
||||
|
||||
This is not a plan to build the full city of Jajce. It is a plan to create one
|
||||
strong visual composition that can host the current simulation and grow with
|
||||
future systems.
|
||||
|
||||
## What already exists
|
||||
|
||||
Do not redo these tasks:
|
||||
|
||||
- Godot 4.7 project configuration;
|
||||
- Terrain3D 1.0.2 installed and enabled;
|
||||
- cross-platform Git configuration;
|
||||
- working `main.tscn`;
|
||||
- camera-relative player movement and elevated follow camera;
|
||||
- three autonomous simulated NPCs;
|
||||
- hunger, energy, starvation, death, task scoring, and task duration;
|
||||
- task-change and village-change signals;
|
||||
- visual NPC navigation and arrival reporting;
|
||||
- farm, forest, food, guard, study, and rest markers;
|
||||
- aggregate village UI;
|
||||
- initial tree assets;
|
||||
- a baked navigation region for the current flat test area.
|
||||
|
||||
Terrain3D's bundled `demo/` directory and most of `addons/terrain_3d/` are
|
||||
plugin content. They are references, not the game.
|
||||
|
||||
## Current architectural constraint
|
||||
|
||||
`main.tscn` currently owns several different concerns:
|
||||
|
||||
```text
|
||||
Main
|
||||
├── current flat World and NavigationRegion3D
|
||||
├── Player
|
||||
├── CameraRig
|
||||
├── SimulationManager
|
||||
├── WorldViewManager
|
||||
├── ActiveNPCs
|
||||
├── TaskZone markers
|
||||
├── WorldEnvironment
|
||||
└── UI
|
||||
```
|
||||
|
||||
The player and `WorldViewManager` reference the task markers through exported
|
||||
`NodePath` values. `NpcVisual` relies on the navigation map to reach those
|
||||
markers.
|
||||
|
||||
Replacing the ground without respecting those references would break behavior
|
||||
that already works.
|
||||
|
||||
## Adjusted scene strategy
|
||||
|
||||
Create a reusable environment scene and instance it into the existing runtime.
|
||||
Keep game orchestration in `main.tscn`.
|
||||
|
||||
Target structure:
|
||||
|
||||
```text
|
||||
Main
|
||||
├── JajceWorld instanced environment
|
||||
│ ├── TerrainRoot
|
||||
│ │ └── Terrain3D
|
||||
│ ├── WaterRoot
|
||||
│ ├── VillageRoot
|
||||
│ ├── FoliageRoot
|
||||
│ ├── NavigationRegion3D
|
||||
│ ├── WorldObjects
|
||||
│ │ └── ResourceNodes
|
||||
│ │ ├── BerryBush instances
|
||||
│ │ └── Tree instances
|
||||
│ ├── LegacyTaskMarkers temporary migration fallback
|
||||
│ │ ├── FarmZone fallback only
|
||||
│ │ ├── ForestZone fallback only
|
||||
│ │ ├── FoodZone
|
||||
│ │ ├── GuardZone
|
||||
│ │ ├── StudyZone
|
||||
│ │ └── RestZone
|
||||
│ ├── DirectionalLight3D
|
||||
│ └── WorldEnvironment
|
||||
├── Player
|
||||
├── CameraRig
|
||||
├── SimulationManager
|
||||
├── WorldViewManager
|
||||
├── ActiveNPCs
|
||||
└── UI
|
||||
```
|
||||
|
||||
`JajceWorld` should contain geography, world-object presentations, and temporary
|
||||
legacy interaction locations. It should not own `SimulationManager`, simulated
|
||||
NPC data, player state, or UI.
|
||||
|
||||
Create a small look-development wrapper that instances the same world:
|
||||
|
||||
```text
|
||||
JajceLookdev
|
||||
├── JajceWorld
|
||||
└── BeautyCameraRig
|
||||
```
|
||||
|
||||
This provides a cinematic workbench without creating a second environment that
|
||||
later has to be rebuilt for gameplay.
|
||||
|
||||
## Adjusted file structure
|
||||
|
||||
Follow the repository's existing feature-oriented layout. Do not create six
|
||||
empty sub-scenes merely to match a theoretical architecture.
|
||||
|
||||
Start with:
|
||||
|
||||
```text
|
||||
world/
|
||||
└── jajce/
|
||||
├── JajceWorld.tscn
|
||||
├── JajceLookdev.tscn
|
||||
└── beauty_camera.gd
|
||||
|
||||
terrain/
|
||||
└── jajce/
|
||||
├── data/
|
||||
├── materials/
|
||||
├── textures/
|
||||
└── source/
|
||||
|
||||
assets/
|
||||
└── jajce/
|
||||
├── buildings/
|
||||
├── foliage/
|
||||
├── rocks/
|
||||
├── props/
|
||||
├── water/
|
||||
└── vfx/
|
||||
```
|
||||
|
||||
Extract `JajceWater`, `JajceVillageBlockout`, or other components into their own
|
||||
scenes only when they have meaningful internal behavior or are reused. Avoid
|
||||
scaffolding an elaborate directory tree before assets exist.
|
||||
|
||||
## Visual target
|
||||
|
||||
Build a compressed, game-readable Jajce-inspired valley:
|
||||
|
||||
| Inspiration | First-slice interpretation |
|
||||
| --- | --- |
|
||||
| Hilltop fortress | One strong blockout silhouette on the ridge |
|
||||
| Old town slope | Four to six house blocks following two terraces |
|
||||
| Pliva/Vrbas water | One main river and a suggested secondary channel |
|
||||
| Waterfall | Hero mesh/VFX feature visible from the main camera |
|
||||
| Watermills | One working mill silhouette, with room for later expansion |
|
||||
| Forested hills | Terrain3D foliage clusters and background tree masses |
|
||||
| Agricultural outskirts | Existing farm and forest jobs integrated into terrain |
|
||||
| Regional roads | One readable loop connecting world objects and legacy targets |
|
||||
|
||||
The fortress, waterfall, roofs, player, and at least two working NPCs should be
|
||||
readable in one strong composition.
|
||||
|
||||
## Scope
|
||||
|
||||
### First terrain size
|
||||
|
||||
Start around **512 m × 512 m**. The playable and polished area can be smaller
|
||||
inside it.
|
||||
|
||||
Do not begin at 1024 m simply because Terrain3D supports it. Expand only when
|
||||
the current camera, navigation routes, and composition need more space.
|
||||
|
||||
### First material set
|
||||
|
||||
Use at most six terrain surfaces:
|
||||
|
||||
1. soft grass;
|
||||
2. dirt path;
|
||||
3. warm cliff stone;
|
||||
4. wet riverbank stone;
|
||||
5. forest floor;
|
||||
6. compacted village ground.
|
||||
|
||||
The material set should establish large readable areas. Avoid high-frequency
|
||||
photorealistic noise.
|
||||
|
||||
### First architecture set
|
||||
|
||||
Use:
|
||||
|
||||
- one fortress silhouette;
|
||||
- four to six house blockouts;
|
||||
- one mill;
|
||||
- one bridge;
|
||||
- a few fences, carts, sacks, logs, and work props.
|
||||
|
||||
Do not begin with 12–20 finished houses. The first shot needs composition, not
|
||||
an asset catalog.
|
||||
|
||||
## Art direction rules
|
||||
|
||||
Translate the desired animated-film warmth into an original style:
|
||||
|
||||
| Element | Direction |
|
||||
| --- | --- |
|
||||
| Terrain | Broad painterly color regions and exaggerated silhouettes |
|
||||
| Grass | Soft masses and restrained sway, not dense visual noise |
|
||||
| Trees | Rounded canopies, varied scale, simple readable trunks |
|
||||
| Rocks | Chunky warm-gray forms with low-frequency detail |
|
||||
| Buildings | Light plaster/stone, warm roofs, dark timber accents |
|
||||
| Water | Turquoise/emerald body, strong foam shapes, soft reflection |
|
||||
| Lighting | Warm sun, cool shadows, mild atmospheric haze |
|
||||
| Characters | Simple proportions, clear profession colors and props |
|
||||
| Motion | Wind, water, smoke, leaves, cloth, birds, and purposeful NPC travel |
|
||||
|
||||
Cozy presentation does not remove scarcity, death, conflict, or ambition. It
|
||||
makes the world pleasant to inhabit and the people pleasant to watch.
|
||||
|
||||
## Implementation phases
|
||||
|
||||
### Phase 0 — Preserve and capture the baseline
|
||||
|
||||
Before replacing anything:
|
||||
|
||||
- run the current prototype;
|
||||
- record a short baseline clip or screenshots;
|
||||
- record the development machine's frame time and obvious scene statistics;
|
||||
- verify all six task locations can be reached;
|
||||
- verify starvation, work completion, and death still function;
|
||||
- note current camera framing and movement feel.
|
||||
|
||||
This becomes both a regression reference and excellent before/after material.
|
||||
|
||||
### Exit condition
|
||||
|
||||
There is a reproducible baseline showing the existing flat prototype and its
|
||||
working behaviors.
|
||||
|
||||
### Systems prerequisite — Migrate food and wood targets
|
||||
|
||||
Implement and validate the first ResourceNodes on the current flat map before
|
||||
moving the playable runtime onto Terrain3D:
|
||||
|
||||
- berry bushes for `gather_food`;
|
||||
- trees for `gather_wood`;
|
||||
- stable target IDs;
|
||||
- nearest-available selection;
|
||||
- single-user reservation;
|
||||
- extraction after work completion;
|
||||
- depletion and replanning;
|
||||
- actual extracted amount applied to the village;
|
||||
- zone fallback with visible warnings.
|
||||
|
||||
Keep the other task zones temporarily. Rest, eating, study, and patrol will
|
||||
eventually use activity, storage, or workstation targets rather than pretending
|
||||
to be resource sources.
|
||||
|
||||
### Exit condition
|
||||
|
||||
Food and wood work without their zones during normal play, resource conservation
|
||||
holds, and target failure does not leave a permanent reservation.
|
||||
|
||||
### Phase 1 — Create the reusable world scaffold
|
||||
|
||||
Create `world/jajce/JajceWorld.tscn` with:
|
||||
|
||||
- Terrain3D and dedicated terrain data;
|
||||
- placeholder `WaterRoot`;
|
||||
- placeholder `VillageRoot`;
|
||||
- placeholder `FoliageRoot`;
|
||||
- a navigation region;
|
||||
- resource-node containers plus temporary fallback markers;
|
||||
- lighting and environment.
|
||||
|
||||
Create `JajceLookdev.tscn` that instances `JajceWorld` and adds a temporary
|
||||
beauty camera.
|
||||
|
||||
Do not migrate `main.tscn` yet. Do not duplicate simulation scripts inside the
|
||||
look-development scene.
|
||||
|
||||
### Exit condition
|
||||
|
||||
The same `JajceWorld` instance can open in the lookdev scene and can be instanced
|
||||
under a temporary runtime test without errors.
|
||||
|
||||
### Phase 2 — Greybox the hero composition
|
||||
|
||||
Sculpt by hand before attempting GIS/DEM import:
|
||||
|
||||
- one dominant ridge;
|
||||
- descending town terraces;
|
||||
- main river valley;
|
||||
- waterfall drop;
|
||||
- lower pool;
|
||||
- farm shelf;
|
||||
- forest work area;
|
||||
- a walkable road loop connecting world objects and remaining legacy locations.
|
||||
|
||||
Block out the fortress, houses, mill, bridge, and waterfall with primitives or
|
||||
simple meshes.
|
||||
|
||||
Place the beauty camera early. Terrain should be judged through the intended
|
||||
game and video cameras, not only from the editor's free camera.
|
||||
|
||||
### Navigation spike
|
||||
|
||||
Do an early rough navigation bake now. Do not wait until final art.
|
||||
|
||||
The purpose is to detect:
|
||||
|
||||
- slopes that are too steep;
|
||||
- terraces that cannot connect;
|
||||
- paths too narrow for agents;
|
||||
- waterfall or river barriers that split required routes;
|
||||
- terrain collision or navigation incompatibilities.
|
||||
|
||||
The final navigation bake still happens after terrain and props stabilize.
|
||||
|
||||
### Exit condition
|
||||
|
||||
One static frame contains the ridge landmark, roofs, river/waterfall, and
|
||||
village work area. A test agent can traverse the intended task loop.
|
||||
|
||||
### Phase 3 — Establish the beauty baseline
|
||||
|
||||
Add only the highest-value presentation:
|
||||
|
||||
- six terrain materials;
|
||||
- warm `WorldEnvironment`;
|
||||
- directional light and atmospheric haze;
|
||||
- simple river surface;
|
||||
- waterfall body, foam, and mist;
|
||||
- first foliage clusters using Terrain3D instancing where appropriate;
|
||||
- restrained grass/tree motion;
|
||||
- chimney smoke;
|
||||
- slow beauty-camera drift.
|
||||
|
||||
Avoid expensive water, dense individual grass nodes, and elaborate weather at
|
||||
this stage.
|
||||
|
||||
### Exit condition
|
||||
|
||||
The lookdev scene can produce a compelling 10–20 second clip with no gameplay.
|
||||
The environment remains within the recorded prototype's agreed performance
|
||||
budget.
|
||||
|
||||
### Phase 4 — Integrate the existing game
|
||||
|
||||
Once the world composition is stable:
|
||||
|
||||
1. Instance `JajceWorld` into `main.tscn`.
|
||||
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
|
||||
`JajceWorld/LegacyTaskMarkers`.
|
||||
5. Bake navigation for the new walkable area.
|
||||
6. Test each existing task from multiple spawn positions.
|
||||
7. Verify task arrival still transitions from traveling to working.
|
||||
8. Verify task completion still changes village state.
|
||||
9. Verify depletion and reservations survive the scene migration.
|
||||
10. Verify player interaction ranges still make sense at the new scale.
|
||||
11. Verify dead NPC visuals do not block routes or retain reservations.
|
||||
12. Compare performance and behavior against the Phase 0 baseline.
|
||||
|
||||
Do not move simulation ownership into `JajceWorld` to make wiring convenient.
|
||||
|
||||
### Exit condition
|
||||
|
||||
The current three NPCs and player can perform all existing prototype behaviors
|
||||
inside the new terrain without regression.
|
||||
|
||||
### Phase 5 — Make the simulation readable on video
|
||||
|
||||
Add presentation for systems that already exist:
|
||||
|
||||
- simple stylized NPC placeholder instead of capsules;
|
||||
- profession color/prop distinctions;
|
||||
- compact task/need icon above selected or relevant NPCs;
|
||||
- name labels when useful;
|
||||
- an NPC reason inspector for development footage;
|
||||
- visible food, logs, guard, study, rest, and eating props;
|
||||
- cinematic/debug UI toggle;
|
||||
- a scenario reset and fixed seed for repeatable clips.
|
||||
|
||||
Do not fake activity that contradicts simulation state. A farmer icon should
|
||||
represent a real chosen task.
|
||||
|
||||
### Exit condition
|
||||
|
||||
A viewer can distinguish at least three professions and understand one NPC's
|
||||
need, destination, and consequence without reading console output.
|
||||
|
||||
### Phase 6 — Produce the first public demo sequence
|
||||
|
||||
Capture a short sequence with a clear story:
|
||||
|
||||
1. establish the valley and waterfall;
|
||||
2. introduce one named NPC;
|
||||
3. show the NPC choosing and traveling to work;
|
||||
4. reveal the reason through a concise overlay;
|
||||
5. show the work changing a real village resource;
|
||||
6. end on either recovery or a visible shortage consequence.
|
||||
|
||||
The best first character is one of the existing named NPCs—Amina, Tarik, or
|
||||
Jasmin—rather than an unnamed cinematic extra.
|
||||
|
||||
### Exit condition
|
||||
|
||||
The clip has an understandable beginning, decision, and consequence. It does not
|
||||
depend on a voiceover to prove that the simulation is real.
|
||||
|
||||
## Build-in-public content pillars
|
||||
|
||||
Rotate between four types of updates.
|
||||
|
||||
### 1. Transformation
|
||||
|
||||
Show visible before/after progress:
|
||||
|
||||
- flat test ground to Jajce-inspired valley;
|
||||
- blockout waterfall to mist and foam;
|
||||
- capsules to readable professions;
|
||||
- empty paths to visible work traffic.
|
||||
|
||||
### 2. Tiny autonomous stories
|
||||
|
||||
Use one named NPC and one question:
|
||||
|
||||
- Why did Amina stop guarding?
|
||||
- Can Tarik gather food before starvation?
|
||||
- Why is Jasmin resting while the village is short on wood?
|
||||
- What happens when the food route is blocked?
|
||||
|
||||
### 3. System under the beauty
|
||||
|
||||
Show a beautiful shot, then reveal the debug reason trace, event, or resource
|
||||
flow that drives it.
|
||||
|
||||
### 4. Learning Godot publicly
|
||||
|
||||
Frame honest engineering lessons:
|
||||
|
||||
- Terrain3D sculpting and material mistakes;
|
||||
- navigation problems caused by terrain;
|
||||
- making NPC simulation deterministic;
|
||||
- profiling foliage versus agent cost;
|
||||
- separating simulation data from visual scenes.
|
||||
|
||||
## Short-form video template
|
||||
|
||||
For TikTok, Shorts, or brief social posts:
|
||||
|
||||
```text
|
||||
0–2 s Show the outcome or surprising NPC behavior
|
||||
2–5 s State one question
|
||||
5–15 s Show the cause unfolding
|
||||
15–25 s Reveal the systemic consequence
|
||||
End Show the next unresolved problem
|
||||
```
|
||||
|
||||
Use captions and strong visual causality. Avoid opening with a long editor tour.
|
||||
|
||||
## Initial video backlog
|
||||
|
||||
1. **“I replaced my programmer map with a Bosnian-inspired valley.”**
|
||||
2. **“This villager chose food over their profession—and here is why.”**
|
||||
3. **“The village can starve without a scripted quest.”**
|
||||
4. **“Every NPC physically walks to the work they selected.”**
|
||||
5. **“One blocked path broke the village economy.”**
|
||||
6. **“Making a Jajce-inspired waterfall in Godot Terrain3D.”**
|
||||
7. **“The same scene in cinematic mode and simulation-debug mode.”**
|
||||
8. **“Can three autonomous villagers survive this shortage?”**
|
||||
|
||||
Each video should correspond to real repository progress. Do not build isolated
|
||||
visual tricks solely for a post unless they also support the intended game.
|
||||
|
||||
## Performance guardrails
|
||||
|
||||
- Record frame time before adding terrain.
|
||||
- Treat Terrain3D instancing as the default for broad foliage where suitable.
|
||||
- Avoid physics and navigation obstacles on distant decorative vegetation.
|
||||
- Keep waterfall mist and smoke particle counts bounded.
|
||||
- Use simple water before adding screen-space reflection or refraction.
|
||||
- Test the gameplay camera, not only the beauty camera.
|
||||
- Profile editor and exported builds separately when export work begins.
|
||||
- Recheck navigation cost after every meaningful terrain expansion.
|
||||
- Do not increase NPC population while diagnosing environment cost.
|
||||
|
||||
## Source-control guardrails
|
||||
|
||||
- Commit Terrain3D data and game-authored terrain assets.
|
||||
- Continue ignoring `.godot/` and other imported caches.
|
||||
- Keep Godot `.import` and `.uid` sidecars tracked.
|
||||
- Do not modify or reformat the third-party Terrain3D addon incidentally.
|
||||
- Keep lookdev assets under game-owned paths, not inside the addon.
|
||||
- Make environment, integration, and simulation changes separate commits where
|
||||
practical.
|
||||
|
||||
## Definition of “Jajce Lookdev 01”
|
||||
|
||||
The adjusted first milestone is complete when:
|
||||
|
||||
- Terrain3D is used by `JajceWorld`; installation itself is already complete.
|
||||
- One approximately 512 m terrain exists.
|
||||
- Fortress ridge, town terraces, river valley, and waterfall drop are readable.
|
||||
- Six or fewer terrain materials establish the major surfaces.
|
||||
- One fortress, four to six houses, one mill, and one bridge are blocked out.
|
||||
- River, waterfall foam, mist, warm lighting, and first foliage are present.
|
||||
- A beauty camera produces a strong 10–20 second shot.
|
||||
- A rough navigation test proves the main route is viable.
|
||||
- The existing simulation has not yet been duplicated or moved.
|
||||
|
||||
## Definition of “Simulation Garden 01”
|
||||
|
||||
The follow-up milestone is complete when:
|
||||
|
||||
- `JajceWorld` is instanced in `main.tscn`;
|
||||
- food and wood ResourceNodes work in the terrain;
|
||||
- remaining legacy task markers are reconnected;
|
||||
- player movement and all existing interactions work;
|
||||
- all three current NPCs navigate, work, eat, rest, starve, and die correctly;
|
||||
- one NPC's decision is readable through in-game presentation;
|
||||
- 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.
|
||||
|
||||
## 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.”
|
||||
|
||||
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
|
||||
exist.
|
||||
@@ -0,0 +1,590 @@
|
||||
# The Steward — Learning and Reusable-Systems Roadmap
|
||||
|
||||
## Purpose
|
||||
|
||||
This project is both a playable prototype and an advanced Godot curriculum.
|
||||
The goal is not merely to accumulate features. It is to understand, implement,
|
||||
measure, and document systems that can form the foundation of a later
|
||||
production game.
|
||||
|
||||
The roadmap prioritizes:
|
||||
|
||||
- learning through complete vertical behaviors;
|
||||
- separating simulation from presentation;
|
||||
- repeatable experiments and measurements;
|
||||
- systems that survive save/load and scale changes;
|
||||
- visible results suitable for building in public;
|
||||
- avoiding premature architecture that has not been tested by gameplay.
|
||||
|
||||
## How to use this roadmap
|
||||
|
||||
Each milestone should produce five outcomes:
|
||||
|
||||
1. **Concept learned** — the Godot or simulation topic being studied.
|
||||
2. **Playable proof** — behavior a player can observe or influence.
|
||||
3. **Reusable artifact** — a system, pattern, benchmark, or tool.
|
||||
4. **Exit test** — an objective condition for calling the milestone complete.
|
||||
5. **Retrospective** — what worked, what failed, and what should change.
|
||||
|
||||
Do not advance because files exist. Advance when the exit test passes.
|
||||
|
||||
## Three vertical slices
|
||||
|
||||
The long-term vision contains three major risks. Validate them separately before
|
||||
trying to combine the full game.
|
||||
|
||||
### A. Simulation slice
|
||||
|
||||
A small village runs autonomously, exposes understandable decisions, creates
|
||||
history, and produces interesting failures without scripted quests.
|
||||
|
||||
### B. Action slice
|
||||
|
||||
Movement, interaction, melee combat, companions, and small-group commands are
|
||||
fun in an isolated test environment.
|
||||
|
||||
### C. World slice
|
||||
|
||||
One village, one route, and part of a town exchange people, goods, information,
|
||||
and conflict while the player moves between simulation fidelity levels.
|
||||
|
||||
The simulation garden is the first slice. A combat sandbox should begin before
|
||||
the simulation is “finished,” because combat feel is a separate high-risk
|
||||
problem.
|
||||
|
||||
## Continuous learning practices
|
||||
|
||||
### Keep a decision record
|
||||
|
||||
For meaningful architectural choices, record:
|
||||
|
||||
- problem;
|
||||
- constraints;
|
||||
- options considered;
|
||||
- decision;
|
||||
- consequences;
|
||||
- conditions that would justify revisiting it.
|
||||
|
||||
This can later become a `docs/decisions/` collection. Do not create records for
|
||||
trivial edits.
|
||||
|
||||
### Maintain reproducible scenarios
|
||||
|
||||
Important behaviors should have fixed seeds and known initial state:
|
||||
|
||||
- normal village day;
|
||||
- food shortage;
|
||||
- blocked workplace;
|
||||
- exhausted worker;
|
||||
- path failure;
|
||||
- NPC death;
|
||||
- relationship conflict;
|
||||
- migration or faction pressure.
|
||||
|
||||
Scenarios make debugging, videos, balancing, and performance comparisons easier.
|
||||
|
||||
### Measure before optimizing
|
||||
|
||||
Maintain a small benchmark ledger:
|
||||
|
||||
| Measurement | Example |
|
||||
| --- | --- |
|
||||
| Population | 10, 100, 1,000, 10,000 data-only agents |
|
||||
| Simulated duration | one day, season, or year |
|
||||
| Wall-clock runtime | total and per simulated tick |
|
||||
| Update count | decisions and scheduled events processed |
|
||||
| Memory | state and history footprint |
|
||||
| Active visuals | navigation/animation cost |
|
||||
| Determinism | final-state checksum for a known seed |
|
||||
|
||||
### Pair systems with presentation
|
||||
|
||||
Every systems milestone should answer: “How can a viewer see this happening?”
|
||||
Every visual milestone should answer: “Which real state does this represent?”
|
||||
|
||||
## Milestone 0 — Baseline and observability
|
||||
|
||||
### Learn
|
||||
|
||||
- Godot project execution and scene-tree inspection;
|
||||
- debugger, profiler, monitors, and remote scene tree;
|
||||
- structured logging and debug overlays;
|
||||
- establishing behavioral and performance baselines.
|
||||
|
||||
### Build
|
||||
|
||||
- a simulation pause, single-step, speed control, and reset;
|
||||
- selectable NPC debug panel;
|
||||
- current need, task, task state, target, and task score display;
|
||||
- deterministic scenario seed entry;
|
||||
- concise event feed separate from verbose console logging;
|
||||
- baseline performance capture for the existing three-NPC prototype.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A simulation debug console/overlay and scenario runner.
|
||||
|
||||
### Exit test
|
||||
|
||||
From the running game, a developer can select any NPC and explain:
|
||||
|
||||
- what it is doing;
|
||||
- why it selected that task;
|
||||
- where it is going;
|
||||
- when the task should complete;
|
||||
- what state will change on completion.
|
||||
|
||||
The same seed and commands produce the same early simulation result.
|
||||
|
||||
## Milestone 1 — Simulation/presentation boundaries
|
||||
|
||||
### Learn
|
||||
|
||||
- `Node`, `RefCounted`, and `Resource` responsibilities;
|
||||
- signals versus direct calls;
|
||||
- dependency direction;
|
||||
- scene composition;
|
||||
- typed GDScript and stable identifiers.
|
||||
|
||||
### Build
|
||||
|
||||
- explicit simulation clock outside frame-dependent rules;
|
||||
- stable IDs for NPCs and locations;
|
||||
- serializable state records separated from immutable definitions;
|
||||
- an adapter interface between simulation and active visual NPCs;
|
||||
- smaller managers with focused responsibilities;
|
||||
- removal of direct task-string-to-marker coupling from the core.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A minimal headless-capable simulation kernel with a Godot presentation adapter.
|
||||
|
||||
### Exit test
|
||||
|
||||
The village can advance without instantiating `NpcVisual` scenes. Loading or
|
||||
unloading an NPC visual does not change the authoritative NPC state.
|
||||
|
||||
## Milestone 2 — Data-driven needs, professions, and actions
|
||||
|
||||
### Learn
|
||||
|
||||
- custom `Resource` definitions;
|
||||
- utility AI and consideration curves;
|
||||
- action preconditions, effects, duration, and interruption;
|
||||
- dependency injection through definitions;
|
||||
- debugging decision scores.
|
||||
|
||||
### Build
|
||||
|
||||
- need definitions;
|
||||
- profession definitions;
|
||||
- action definitions for eat, rest, gather food, gather wood, patrol, and study;
|
||||
- target discovery independent of hard-coded scene paths;
|
||||
- utility considerations with full reason traces;
|
||||
- reservations so multiple NPCs do not unrealistically claim one resource or
|
||||
workstation;
|
||||
- explicit task failure and replanning behavior.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A generic action-selection system that can evaluate defined actions against
|
||||
agent and world state.
|
||||
|
||||
### Exit test
|
||||
|
||||
A new profession and action can be added primarily through definitions and a
|
||||
small effect implementation. The inspector shows the winning score and rejected
|
||||
alternatives. NPCs recover from invalid or unavailable targets.
|
||||
|
||||
## Milestone 3 — One complete material economy
|
||||
|
||||
The staged replacement of abstract task zones begins with
|
||||
[the ResourceNode migration plan](RESOURCE_NODE_MIGRATION.md).
|
||||
|
||||
### Learn
|
||||
|
||||
- inventories and item stacks;
|
||||
- ownership, storage, reservations, and transactions;
|
||||
- production recipes;
|
||||
- world interaction points;
|
||||
- consistency and invariant testing.
|
||||
|
||||
### Build
|
||||
|
||||
Implement one honest food chain:
|
||||
|
||||
```text
|
||||
source -> gather/harvest -> carry -> store -> retrieve -> prepare/eat
|
||||
```
|
||||
|
||||
Include:
|
||||
|
||||
- item definitions;
|
||||
- personal and building inventories;
|
||||
- location-based storage;
|
||||
- physical carrying for active NPCs;
|
||||
- abstract transfer for distant agents;
|
||||
- reservation and cancellation;
|
||||
- spoilage only if it improves the initial loop;
|
||||
- player participation in the same resource rules.
|
||||
|
||||
Add wood only after the food chain is coherent.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
Inventory, reservation, transaction, and production primitives.
|
||||
|
||||
### Exit test
|
||||
|
||||
Every consumed unit of food can be traced to a source and a sequence of actions.
|
||||
No resource is created or destroyed except through an explicit, inspectable
|
||||
rule. A shortage is visible before the aggregate UI reports it.
|
||||
|
||||
## Milestone 4 — Attractive simulation garden
|
||||
|
||||
The detailed environment and public-demo sequence is maintained in
|
||||
[the build-in-public visual slice plan](BUILD_IN_PUBLIC_PLAN.md).
|
||||
|
||||
### Learn
|
||||
|
||||
- Terrain3D regions, sculpting, texturing, LOD, and instancing;
|
||||
- environment lighting, fog, sky, and post-processing;
|
||||
- modular scene construction;
|
||||
- navigation generation and validation;
|
||||
- water and vegetation presentation;
|
||||
- performance budgets for environment art.
|
||||
|
||||
### Build
|
||||
|
||||
- a compact Jajce-inspired valley composition;
|
||||
- ridge landmark, river/waterfall feature, bridge, mill area, farm, forest,
|
||||
homes, and workplaces;
|
||||
- warm painterly environment treatment;
|
||||
- replace capsules with simple stylized, animation-ready characters;
|
||||
- readable profession props/colors;
|
||||
- day/night presentation;
|
||||
- cinematic/debug display toggle;
|
||||
- stable navigation across all required work routes.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A terrain/world-building pipeline and environment performance checklist.
|
||||
|
||||
### Exit test
|
||||
|
||||
A short clip communicates the setting, player perspective, NPC professions, and
|
||||
one production loop without narration or console output. The environment stays
|
||||
inside the agreed frame-time and memory budget on the development machine.
|
||||
|
||||
## Milestone 5 — Time, schedules, and persistence
|
||||
|
||||
### Learn
|
||||
|
||||
- authoritative game time;
|
||||
- calendar and scheduled events;
|
||||
- serialization and schema versioning;
|
||||
- save migration;
|
||||
- restoring active scenes from data;
|
||||
- deterministic random streams.
|
||||
|
||||
### Build
|
||||
|
||||
- time-of-day and calendar;
|
||||
- work, meal, sleep, and discretionary schedule blocks;
|
||||
- simulation event queue;
|
||||
- versioned save format;
|
||||
- save/load for people, inventories, tasks, locations, and village state;
|
||||
- state validation after loading;
|
||||
- separate random streams where useful.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A versioned world-state persistence layer and simulation scheduler.
|
||||
|
||||
### Exit test
|
||||
|
||||
Save during travel, work, eating, and sleep; reload each save; then verify that
|
||||
the simulation resumes coherently. A deterministic headless scenario retains
|
||||
the same checksum across repeated runs.
|
||||
|
||||
## Milestone 6 — Events, memories, and relationships
|
||||
|
||||
### Learn
|
||||
|
||||
- event sourcing concepts without overcommitting to full event sourcing;
|
||||
- relationship graphs;
|
||||
- knowledge versus objective truth;
|
||||
- memory selection and decay;
|
||||
- social utility considerations;
|
||||
- tooling for history inspection.
|
||||
|
||||
### Build
|
||||
|
||||
- structured world event records;
|
||||
- actor, target, witness, location, cause, and consequence links;
|
||||
- relationship dimensions such as familiarity, affection, trust, fear,
|
||||
obligation, and hostility;
|
||||
- NPC knowledge of witnessed or communicated events;
|
||||
- memory importance and retention rules;
|
||||
- visible social reactions;
|
||||
- person and settlement history views.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
An event/history store and relationship system with query APIs.
|
||||
|
||||
### Exit test
|
||||
|
||||
Two NPCs exposed to different evidence can hold different beliefs about the
|
||||
same event. Their future choices visibly differ because of those memories and
|
||||
relationships.
|
||||
|
||||
## Milestone 7 — Rumours and emergent opportunities
|
||||
|
||||
### Learn
|
||||
|
||||
- information propagation;
|
||||
- query systems;
|
||||
- narrative framing from structured facts;
|
||||
- objective generation;
|
||||
- consequence-aware quest state;
|
||||
- natural-language presentation separated from authoritative state.
|
||||
|
||||
### Build
|
||||
|
||||
- rumour creation and transmission;
|
||||
- information accuracy, secrecy, and distortion rules;
|
||||
- detection of unresolved conditions;
|
||||
- interested-party and capable-helper queries;
|
||||
- opportunity/quest records that reference real entities and events;
|
||||
- multiple valid resolution paths;
|
||||
- consequence application to the source systems;
|
||||
- concise dialogue/event text templates.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
An emergent opportunity generator built over world-state queries.
|
||||
|
||||
### Exit test
|
||||
|
||||
A shortage, theft, injury, debt, or disappearance creates an opportunity only
|
||||
when someone knows and cares about it. Resolving it changes the originating
|
||||
people, resources, relationships, and history without spawning quest-only
|
||||
duplicates.
|
||||
|
||||
## Milestone 8 — Scalable spatial simulation and LOD
|
||||
|
||||
### Learn
|
||||
|
||||
- spatial partitioning;
|
||||
- relevance and interest management;
|
||||
- scheduled/batched updates;
|
||||
- data layout and allocation profiling;
|
||||
- active/abstract entity transitions;
|
||||
- statistical aggregation boundaries.
|
||||
|
||||
### Build
|
||||
|
||||
- spatial index for people, buildings, and events;
|
||||
- active, local-abstract, distant-individual, and settlement-aggregate modes;
|
||||
- promotion/demotion between modes;
|
||||
- abstract travel and work resolution;
|
||||
- background settlement updates;
|
||||
- performance harness for increasing population and history;
|
||||
- safeguards preserving named people and unresolved events.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A simulation-LOD framework with measured transition invariants.
|
||||
|
||||
### Exit test
|
||||
|
||||
The benchmark can simulate a target large population faster than real time while
|
||||
a smaller active population remains fully represented. Moving an NPC between
|
||||
fidelity levels preserves identity, inventory, task, relationships, and
|
||||
important history.
|
||||
|
||||
Set the target population only after collecting baseline measurements.
|
||||
|
||||
## Milestone 9 — Player interaction and social agency
|
||||
|
||||
### Learn
|
||||
|
||||
- interaction targeting;
|
||||
- context actions;
|
||||
- UI state machines;
|
||||
- dialogue presentation;
|
||||
- reputation and permission systems;
|
||||
- accessibility and feedback.
|
||||
|
||||
### Build
|
||||
|
||||
- inspect people, storage, workplaces, and events;
|
||||
- talk, trade, help, request, employ, threaten, or report where appropriate;
|
||||
- priority influence through plausible institutions rather than omniscient
|
||||
sliders;
|
||||
- reputation, authority, and social access;
|
||||
- player participation in professions;
|
||||
- feedback showing likely and actual consequences.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A context interaction framework connected to simulation actions and authority.
|
||||
|
||||
### Exit test
|
||||
|
||||
The player can understand and resolve the simulation garden's food crisis in
|
||||
multiple systemic ways without using a developer menu.
|
||||
|
||||
## Milestone 10 — Combat and companion sandbox
|
||||
|
||||
Begin this as a focused prototype before Milestones 6–9 are fully complete.
|
||||
Integrate it only after its fundamentals feel good.
|
||||
|
||||
### Learn
|
||||
|
||||
- animation state machines and blending;
|
||||
- hit detection and hurtboxes;
|
||||
- root motion versus code-driven motion;
|
||||
- input buffering;
|
||||
- camera feedback;
|
||||
- AI combat behavior;
|
||||
- group commands and formations;
|
||||
- combat profiling.
|
||||
|
||||
### Build
|
||||
|
||||
- isolated combat test scene;
|
||||
- responsive locomotion, attacks, defense, stagger, and recovery;
|
||||
- clear targeting without excessive lock-on dependence;
|
||||
- one companion with understandable autonomous behavior;
|
||||
- a small command vocabulary;
|
||||
- morale and retreat prototype;
|
||||
- simulation consequences for injury, death, witnesses, and reputation.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A combatant state model, animation interface, damage/event model, and companion
|
||||
command layer.
|
||||
|
||||
### Exit test
|
||||
|
||||
A short encounter is enjoyable when repeated without progression rewards. One
|
||||
companion can be directed without constant micromanagement, and combat outcomes
|
||||
produce valid world events.
|
||||
|
||||
## Milestone 11 — Multiple settlements, factions, and mobility
|
||||
|
||||
### Learn
|
||||
|
||||
- hierarchical simulation;
|
||||
- settlement economies;
|
||||
- faction goals and diplomacy;
|
||||
- trade routes and migration;
|
||||
- authority and governance;
|
||||
- large-group command abstraction.
|
||||
|
||||
### Build
|
||||
|
||||
- one village, one travel route, and one district or edge of the city;
|
||||
- movement of goods, people, rumours, and threats;
|
||||
- household and workplace membership;
|
||||
- faction membership and offices;
|
||||
- migration and recruitment;
|
||||
- small-scale leadership progression;
|
||||
- settlement and faction decision processes.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A regional simulation layer connecting local economies and social structures.
|
||||
|
||||
### Exit test
|
||||
|
||||
An event in one settlement creates measurable consequences elsewhere through
|
||||
real movement or communication. The player can gain responsibility through
|
||||
systemic relationships and actions rather than a fixed promotion quest.
|
||||
|
||||
## Milestone 12 — Integrated world slice
|
||||
|
||||
### Learn
|
||||
|
||||
- production hardening;
|
||||
- content pipelines;
|
||||
- onboarding complex systems;
|
||||
- balancing and telemetry;
|
||||
- regression testing;
|
||||
- profiling representative gameplay.
|
||||
|
||||
### Build
|
||||
|
||||
- the simulation, action, and world slices connected;
|
||||
- one coherent regional scenario;
|
||||
- polished onboarding for observation, work, social interaction, and combat;
|
||||
- save compatibility tests;
|
||||
- performance budgets and regression scenarios;
|
||||
- build-in-public demo mode;
|
||||
- documented extraction boundaries for reusable systems.
|
||||
|
||||
### Reusable artifact
|
||||
|
||||
A proven architecture and a set of tested subsystems ready to migrate or evolve
|
||||
into the production game.
|
||||
|
||||
### Exit test
|
||||
|
||||
The player can begin as an ordinary person, form relationships, participate in
|
||||
the economy, encounter an emergent problem, fight or negotiate through it, and
|
||||
leave persistent consequences in another settlement.
|
||||
|
||||
## Reuse checkpoints
|
||||
|
||||
At the end of each milestone, evaluate the system against this checklist:
|
||||
|
||||
- Does it run without the prototype's main scene?
|
||||
- Are definitions separate from mutable state?
|
||||
- Is state serializable and versioned where appropriate?
|
||||
- Can it be tested with a fixed seed?
|
||||
- Can presentation be replaced without rewriting its rules?
|
||||
- Does it expose reason/debug information?
|
||||
- Do measurements justify its complexity?
|
||||
- Has at least one real gameplay feature exercised the API?
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
This order strengthens the simulation while regularly producing visible
|
||||
progress suitable for public development updates.
|
||||
|
||||
## Subjects intentionally deferred
|
||||
|
||||
These are valuable future learning areas but should not distract from the first
|
||||
complete slices:
|
||||
|
||||
- multiplayer authority and replication;
|
||||
- procedural terrain generation;
|
||||
- machine-generated freeform dialogue;
|
||||
- full historical demography;
|
||||
- hundreds of item recipes;
|
||||
- siege-scale combat;
|
||||
- sophisticated market speculation;
|
||||
- native GDExtension optimization;
|
||||
- custom rendering technology.
|
||||
|
||||
Revisit them when a completed slice demonstrates a concrete need.
|
||||
@@ -0,0 +1,721 @@
|
||||
# The Steward — Project Context
|
||||
|
||||
> Agent-facing context for understanding the project quickly.
|
||||
>
|
||||
> Snapshot basis: repository state after commit `e30d208`, July 2026. Treat the
|
||||
> code as the source of truth when this document and the implementation differ.
|
||||
|
||||
## Quick orientation
|
||||
|
||||
**The Steward** is currently a small Godot prototype for an embodied village
|
||||
simulation. Its larger purpose is to become a learning laboratory for a
|
||||
performant, large-scale NPC simulation that can later power a systemic
|
||||
open-world RPG.
|
||||
|
||||
The current village is not intended to be the final game's scale. It is a
|
||||
controlled environment in which to learn and validate:
|
||||
|
||||
- NPC needs and decision-making;
|
||||
- professions, work, inventories, and economic dependencies;
|
||||
- actions, consequences, and world events;
|
||||
- relationships, memories, rumours, and persistent history;
|
||||
- emergent situations that can be surfaced as quests;
|
||||
- simulation level of detail for a much larger population;
|
||||
- readable world presentation and satisfying embodied play.
|
||||
|
||||
The desired game is not an omniscient city builder and not primarily a scripted
|
||||
quest RPG. The player exists physically inside the simulated society.
|
||||
|
||||
## North-star vision
|
||||
|
||||
> A systemic open-world RPG set around a city inspired by Jajce, Bosnia and
|
||||
> Herzegovina, and its surrounding villages. Every important NPC participates
|
||||
> in a simulated society, forms relationships, remembers events, and can affect
|
||||
> history. The player can remain an ordinary citizen, pursue a profession,
|
||||
> become a trader, criminal, warrior, or companion leader, command armies, and
|
||||
> eventually lead a faction.
|
||||
|
||||
The world should generate situations. Quests should primarily communicate,
|
||||
frame, and track those situations rather than manufacture disconnected content.
|
||||
|
||||
Example:
|
||||
|
||||
1. A harvest fails or a trade route becomes unsafe.
|
||||
2. Food scarcity raises pressure on households and professions.
|
||||
3. An NPC steals, migrates, changes work, joins a criminal group, or asks a
|
||||
relative for help.
|
||||
4. Witnesses form memories and spread partial information.
|
||||
5. Relationships, prices, safety, and faction attitudes change.
|
||||
6. The player learns about the situation through observation, conversation,
|
||||
rumours, employment, or authority.
|
||||
7. Any intervention changes the same world state that produced the problem.
|
||||
|
||||
The quest is therefore a view onto the simulation, not a parallel scripted
|
||||
reality.
|
||||
|
||||
## Product pillars
|
||||
|
||||
### 1. Simulated lives
|
||||
|
||||
NPCs should be people rather than production modifiers. Their needs,
|
||||
professions, possessions, schedules, abilities, ambitions, and circumstances
|
||||
drive their choices.
|
||||
|
||||
### 2. Persistent history
|
||||
|
||||
Important actions create structured events. Events can become memories,
|
||||
knowledge, rumours, relationships, reputations, grudges, obligations, and
|
||||
political consequences.
|
||||
|
||||
### 3. Emergent narrative
|
||||
|
||||
Authored content should provide rules, cultures, locations, characters,
|
||||
archetypes, and exceptional story beats. Ordinary quests and conflicts should
|
||||
preferably emerge from unresolved world conditions.
|
||||
|
||||
### 4. Embodied freedom
|
||||
|
||||
The player walks through the same spaces, uses the same resources, and
|
||||
participates in the same institutions as NPCs. They can play at different
|
||||
social scales without being forced toward rulership.
|
||||
|
||||
### 5. Legible autonomy
|
||||
|
||||
Complexity is valuable only when players can understand its consequences. The
|
||||
game should expose why an NPC chose an action and show resources moving through
|
||||
the world.
|
||||
|
||||
### 6. Small stories inside a large world
|
||||
|
||||
The eventual map may be large, but emotional attachment comes from recognizable
|
||||
people and local consequences. Simulation scale must not turn everyone into an
|
||||
anonymous number.
|
||||
|
||||
### 7. Enjoyable action
|
||||
|
||||
Movement and combat should be satisfying independently of the simulation.
|
||||
Companions and armies should offer expressive, enjoyable control rather than
|
||||
only statistical resolution.
|
||||
|
||||
### 8. A recognizable setting
|
||||
|
||||
The core region is inspired by Jajce: dramatic elevation, a fortified urban
|
||||
center, rivers, a waterfall, wooded slopes, lakes, watermills, roads, farms,
|
||||
and surrounding villages. This is an inspiration rather than a requirement for
|
||||
a literal historical reconstruction.
|
||||
|
||||
### 9. Cozy presentation with real stakes
|
||||
|
||||
The presentation should feel warm, painterly, pastoral, and inviting while the
|
||||
simulation remains capable of scarcity, conflict, death, political ambition,
|
||||
and social change.
|
||||
|
||||
## Build-in-public goals
|
||||
|
||||
Visual appeal and watchability are prototype requirements, not final polish.
|
||||
Each simulation feature should have a visible expression:
|
||||
|
||||
| Simulation state | Visible expression |
|
||||
| --- | --- |
|
||||
| Hunger | Looking for food, checking storage, eating, asking, stealing, or weakening |
|
||||
| Profession | Recognizable tools, clothing, workplace, route, and animation |
|
||||
| Task choice | Purposeful movement plus optional task/thought icon |
|
||||
| Production | Items visibly gathered, carried, stored, processed, and consumed |
|
||||
| Relationship | Greeting, helping, arguing, avoiding, mourning, or celebrating |
|
||||
| World event | Visible consequences and a concise event/history feed |
|
||||
| Settlement change | Construction, depletion, prosperity, damage, migration, or recovery |
|
||||
|
||||
Development clips should communicate cause and effect without requiring viewers
|
||||
to read console logs. A cinematic/debug toggle should eventually allow the same
|
||||
scenario to be shown both beautifully and analytically.
|
||||
|
||||
## Visual direction
|
||||
|
||||
The target is an original stylized look characterized by:
|
||||
|
||||
- painterly natural colors and soft, warm lighting;
|
||||
- readable, exaggerated terrain and building silhouettes;
|
||||
- lush vegetation with restrained environmental motion;
|
||||
- expressive, animation-friendly characters;
|
||||
- appealing water, mist, smoke, weather, and seasonal variation;
|
||||
- cozy settlements contrasted with a world capable of hardship;
|
||||
- a clear elevated third-person view that makes NPC activity readable.
|
||||
|
||||
Avoid generic high-fantasy spectacle and avoid treating visual style as a
|
||||
reason to hide the underlying simulation.
|
||||
|
||||
### Initial environment composition
|
||||
|
||||
The first public-facing environment should be a compressed simulation garden,
|
||||
not the complete region:
|
||||
|
||||
- a fortress or fortified landmark on an upper ridge;
|
||||
- a small settlement descending toward water;
|
||||
- a river, bridge, and waterfall or strong vertical water feature;
|
||||
- a mill channel and a small cluster of watermills;
|
||||
- farm terraces and a wooded work area;
|
||||
- a trade road and distant silhouettes that imply a larger world.
|
||||
|
||||
Terrain3D should own broad landforms, ground surfaces, distant landscape, and
|
||||
large-scale vegetation placement. Roads, river surfaces, waterfalls, cliffs
|
||||
that require overhangs, bridges, walls, buildings, and other authored landmarks
|
||||
should use dedicated meshes or appropriate spline/modular tooling.
|
||||
|
||||
## Core player loop
|
||||
|
||||
The intended loop is:
|
||||
|
||||
1. **Observe** people, places, stores, and local problems.
|
||||
2. **Understand** needs, causes, relationships, and competing priorities.
|
||||
3. **Influence** people through work, trade, conversation, policy, reputation,
|
||||
leadership, or force.
|
||||
4. **Act** personally through movement, interaction, production, exploration,
|
||||
and combat.
|
||||
5. **Witness consequences** in the same people and systems.
|
||||
6. **Adapt** to new opportunities and problems created by those consequences.
|
||||
|
||||
The current prototype implements a very early version of observe, autonomous
|
||||
task choice, physical travel, work completion, resource change, and direct
|
||||
player assistance. Its abstract task zones are explicitly transitional; the
|
||||
next world-object migration is documented in
|
||||
[the ResourceNode plan](RESOURCE_NODE_MIGRATION.md).
|
||||
|
||||
## Current technology
|
||||
|
||||
- **Engine:** Godot 4.7 project configuration
|
||||
- **Renderer feature:** Forward Plus
|
||||
- **Language:** GDScript
|
||||
- **Main scene:** `res://main.tscn`
|
||||
- **Terrain:** Terrain3D 1.0.2 is installed and enabled
|
||||
- **Terrain compatibility floor:** Godot 4.4 according to the bundled extension
|
||||
- **Version control:** Git
|
||||
- **Primary branch:** `main`
|
||||
- **Commit convention:** Conventional Commits
|
||||
|
||||
Terrain3D includes binaries, source, editor tooling, examples, and a `demo/`
|
||||
directory. Most files under `addons/terrain_3d/` and `demo/` are third-party
|
||||
plugin content, not game architecture.
|
||||
|
||||
## Current playable state
|
||||
|
||||
### World and player
|
||||
|
||||
- `main.tscn` contains a flat approximately 30×30 prototype ground.
|
||||
- The player is a `CharacterBody3D` represented by placeholder primitive
|
||||
geometry.
|
||||
- WASD movement is camera-relative.
|
||||
- The elevated third-person camera rotates with the mouse and uses smoothed
|
||||
follow/focus behavior.
|
||||
- Pressing `E` near a task zone directly contributes food, wood, safety, or
|
||||
knowledge, or consumes village food.
|
||||
- `Escape` releases captured mouse input.
|
||||
|
||||
### Village simulation
|
||||
|
||||
The simulation currently creates three NPCs:
|
||||
|
||||
- Amina
|
||||
- Tarik
|
||||
- Jasmin
|
||||
|
||||
Each receives a random profession from:
|
||||
|
||||
- farmer;
|
||||
- woodcutter;
|
||||
- guard;
|
||||
- scholar;
|
||||
- wanderer.
|
||||
|
||||
Each simulated NPC currently stores:
|
||||
|
||||
- stable integer ID for the session;
|
||||
- name and profession;
|
||||
- hunger and energy;
|
||||
- strength and intelligence;
|
||||
- current task and task state;
|
||||
- task duration and progress;
|
||||
- simulated position;
|
||||
- starvation state and duration;
|
||||
- death state.
|
||||
|
||||
The village currently tracks:
|
||||
|
||||
- food, initially `20`;
|
||||
- wood, initially `10`;
|
||||
- safety, initially `50`;
|
||||
- knowledge, initially `0`;
|
||||
- per-resource modifiers;
|
||||
- per-resource priorities.
|
||||
|
||||
### NPC task lifecycle
|
||||
|
||||
Task states are:
|
||||
|
||||
```text
|
||||
idle -> traveling -> working -> complete -> idle
|
||||
```
|
||||
|
||||
NPCs currently choose among:
|
||||
|
||||
- gather food;
|
||||
- gather wood;
|
||||
- patrol;
|
||||
- study;
|
||||
- eat;
|
||||
- rest;
|
||||
- wander.
|
||||
|
||||
Needs override ordinary work. Otherwise a utility-like score combines:
|
||||
|
||||
- village priority;
|
||||
- critical and low resource thresholds;
|
||||
- profession preference;
|
||||
- a small random contribution.
|
||||
|
||||
The visual NPC walks toward the task's marker. Arrival tells the simulation to
|
||||
start work. Work progresses on simulation ticks. The village receives the
|
||||
result only when the task duration completes.
|
||||
|
||||
Starvation can reduce productivity and eventually kill an NPC. Dead visuals
|
||||
stop moving, change appearance, and no longer collide.
|
||||
|
||||
### Current task zones
|
||||
|
||||
The main scene contains placeholder zones for:
|
||||
|
||||
- farm;
|
||||
- forest;
|
||||
- guard duty;
|
||||
- study;
|
||||
- rest;
|
||||
- food.
|
||||
|
||||
The farm, forest, guard, study, rest, and food locations are represented by
|
||||
primitive geometry and a few tree assets.
|
||||
|
||||
These markers are not the intended long-term work model. Food and wood should
|
||||
first migrate to finite world `ResourceNode` instances. 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 resource source.
|
||||
|
||||
### Current UI
|
||||
|
||||
A small village panel displays:
|
||||
|
||||
- food;
|
||||
- wood;
|
||||
- safety;
|
||||
- knowledge;
|
||||
- starving NPC count;
|
||||
- selected village modifiers.
|
||||
|
||||
Most deeper reasoning is currently visible only through verbose debug output.
|
||||
|
||||
## Runtime architecture
|
||||
|
||||
### `simulation/SimNPC.gd`
|
||||
|
||||
`SimNPC` is a `RefCounted` simulation model. It owns needs, task selection,
|
||||
task progression, profession affinity, starvation, and death.
|
||||
|
||||
This separation from the visual node is an important architectural seed and
|
||||
should be preserved.
|
||||
|
||||
### `simulation/SimVillage.gd`
|
||||
|
||||
`SimVillage` is a `RefCounted` aggregate for shared resources, modifiers,
|
||||
priorities, and applying completed NPC work.
|
||||
|
||||
### `simulation/SimulationManager.gd`
|
||||
|
||||
`SimulationManager` is currently a scene-tree `Node` that:
|
||||
|
||||
- owns the village and NPC array;
|
||||
- advances a tick approximately every 1.2 seconds;
|
||||
- creates NPCs;
|
||||
- coordinates task completion;
|
||||
- emits village, task, and death signals;
|
||||
- exposes direct resource-changing methods to the player.
|
||||
|
||||
It currently combines clock, orchestration, event publication, population
|
||||
creation, and some gameplay API responsibilities.
|
||||
|
||||
### `world/world_view_manager.gd`
|
||||
|
||||
`WorldViewManager` bridges simulation data to visible NPC nodes. It:
|
||||
|
||||
- instantiates `NpcVisual` scenes;
|
||||
- maps task strings to world markers;
|
||||
- sends targets to visuals;
|
||||
- reports arrival back to `SimulationManager`;
|
||||
- applies visual death state.
|
||||
|
||||
### `player/npc/NpcVisual.gd`
|
||||
|
||||
`NpcVisual` is the active-world representation of an NPC. It currently:
|
||||
|
||||
- owns a `NavigationAgent3D`;
|
||||
- obtains a navigation path;
|
||||
- moves and rotates toward path points;
|
||||
- reports arrival;
|
||||
- applies a simple death presentation.
|
||||
|
||||
### `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.
|
||||
|
||||
### `world/ui/ui.gd`
|
||||
|
||||
The UI subscribes to village changes and formats aggregate village state.
|
||||
|
||||
## Current runtime flow
|
||||
|
||||
```text
|
||||
SimulationManager tick
|
||||
|
|
||||
v
|
||||
SimNPC updates needs and chooses/advances a task
|
||||
|
|
||||
v
|
||||
npc_task_changed signal
|
||||
|
|
||||
v
|
||||
WorldViewManager selects a task-zone marker
|
||||
|
|
||||
v
|
||||
NpcVisual navigates through the active world
|
||||
|
|
||||
v
|
||||
arrived_at_target signal
|
||||
|
|
||||
v
|
||||
SimulationManager marks the NPC as working
|
||||
|
|
||||
v
|
||||
Later ticks complete work
|
||||
|
|
||||
v
|
||||
SimVillage applies production/consumption
|
||||
|
|
||||
v
|
||||
village_changed signal updates the UI
|
||||
```
|
||||
|
||||
## Repository map
|
||||
|
||||
```text
|
||||
.
|
||||
├── addons/terrain_3d/ Third-party Terrain3D plugin
|
||||
├── assets/foliage/ Early tree assets
|
||||
├── demo/ Terrain3D's bundled demo, not the game
|
||||
├── docs/ Project context and plans
|
||||
├── player/
|
||||
│ ├── camera_rig.gd
|
||||
│ ├── player.gd
|
||||
│ ├── PlayerInteraction.gd Currently an empty placeholder
|
||||
│ └── npc/
|
||||
│ ├── NpcVisual.gd
|
||||
│ └── NpcVisual.tscn
|
||||
├── simulation/
|
||||
│ ├── SimNPC.gd
|
||||
│ ├── SimVillage.gd
|
||||
│ └── SimulationManager.gd
|
||||
├── world/
|
||||
│ ├── world_view_manager.gd
|
||||
│ └── ui/ui.gd
|
||||
├── main.tscn
|
||||
└── project.godot
|
||||
```
|
||||
|
||||
## Important limitations and technical debt
|
||||
|
||||
These are expected prototype constraints, not necessarily isolated bugs:
|
||||
|
||||
- Task names and task-to-zone mappings are duplicated strings.
|
||||
- Task zones are abstract destinations rather than real usable world objects.
|
||||
- Mutable simulation state is not serializable through a defined save schema.
|
||||
- Randomness is not seeded for deterministic replay.
|
||||
- Simulation time depends on `_process` and a scene-tree node.
|
||||
- There is no automated test or headless simulation harness.
|
||||
- Resources are global floating-point counters rather than items in locations
|
||||
and inventories.
|
||||
- NPCs do not have homes, schedules, possessions, memories, relationships,
|
||||
goals, or social knowledge.
|
||||
- NPC reasoning is logged but not presented through an in-game inspector.
|
||||
- Active navigation is used as if all agents are local; no simulation LOD exists.
|
||||
- There is no spatial query/index layer for large populations.
|
||||
- Simulation, orchestration, and player-facing mutation APIs are concentrated
|
||||
in `SimulationManager`.
|
||||
- Path failure and interruption behavior is minimal.
|
||||
- Terrain3D is enabled but not yet used by the main game scene.
|
||||
- Combat, companions, factions, politics, trade, rumours, quests, persistence,
|
||||
and regional travel do not yet exist.
|
||||
- Placeholder geometry is sufficient for debugging but not for build-in-public
|
||||
presentation.
|
||||
|
||||
## Target simulation architecture
|
||||
|
||||
### Separate definitions, state, systems, and presentation
|
||||
|
||||
Use four conceptual layers:
|
||||
|
||||
1. **Definitions** — immutable data for needs, actions, professions, items,
|
||||
traits, event types, and locations.
|
||||
2. **State** — serializable runtime records for NPCs, inventories,
|
||||
relationships, settlements, factions, and history.
|
||||
3. **Systems** — clocks, scoring, action resolution, economy, relationships,
|
||||
events, rumours, and persistence.
|
||||
4. **Presentation adapters** — Godot nodes that render nearby state, accept
|
||||
player input, play animation, and provide UI.
|
||||
|
||||
Do not make the simulation core depend on `Node3D`, scene paths, animation,
|
||||
physics frames, or a currently loaded map.
|
||||
|
||||
### Stable identity
|
||||
|
||||
Every persistent entity should eventually have a stable ID:
|
||||
|
||||
- person;
|
||||
- household;
|
||||
- item stack or significant item;
|
||||
- building;
|
||||
- workplace;
|
||||
- settlement;
|
||||
- faction;
|
||||
- location;
|
||||
- event.
|
||||
|
||||
References between simulation records should use IDs rather than live node
|
||||
references.
|
||||
|
||||
### Fixed and deterministic time
|
||||
|
||||
The simulation should advance with an explicit clock and controlled random
|
||||
source. Given the same starting state, seed, and player commands, a headless
|
||||
run should be reproducible.
|
||||
|
||||
This enables:
|
||||
|
||||
- debugging;
|
||||
- automated scenario tests;
|
||||
- balancing;
|
||||
- replaying build-in-public demonstrations;
|
||||
- comparing performance before and after optimization.
|
||||
|
||||
### Scheduled work rather than per-frame thinking
|
||||
|
||||
At scale, agents should wake for relevant decisions or scheduled updates rather
|
||||
than running full reasoning every frame. Examples include:
|
||||
|
||||
- need threshold crossed;
|
||||
- action completed or interrupted;
|
||||
- new information received;
|
||||
- path or workplace became unavailable;
|
||||
- daily schedule boundary;
|
||||
- relationship or faction event;
|
||||
- periodic low-frequency maintenance.
|
||||
|
||||
### Simulation fidelity levels
|
||||
|
||||
The eventual world needs multiple representations:
|
||||
|
||||
1. **Active:** full node, physics, navigation, perception, animation, and combat.
|
||||
2. **Local abstract:** individual position and scheduled actions without
|
||||
continuous physics.
|
||||
3. **Distant individual:** data-only people resolving travel and work by time.
|
||||
4. **Settlement aggregate:** carefully chosen economic or demographic
|
||||
aggregation for populations that do not currently need individual detail.
|
||||
|
||||
Moving between levels must preserve identity and important state. Aggregation
|
||||
must not erase named relationships or unresolved history.
|
||||
|
||||
### Action model
|
||||
|
||||
Actions should become data-driven definitions with:
|
||||
|
||||
- preconditions;
|
||||
- candidate targets;
|
||||
- utility considerations;
|
||||
- expected duration;
|
||||
- reservations;
|
||||
- resource costs;
|
||||
- effects;
|
||||
- interruption rules;
|
||||
- visible presentation hints;
|
||||
- reason tracing.
|
||||
|
||||
The first implementation can remain utility-based. Do not add a complex
|
||||
planner until current action scoring and sequencing demonstrate a concrete need.
|
||||
|
||||
### Events and history
|
||||
|
||||
Important outcomes should create structured facts rather than prose-only logs.
|
||||
A future event record might contain:
|
||||
|
||||
```text
|
||||
event_id
|
||||
event_type
|
||||
simulation_time
|
||||
location_id
|
||||
actor_ids
|
||||
target_ids
|
||||
witness_ids
|
||||
cause_event_ids
|
||||
resource_changes
|
||||
relationship_changes
|
||||
visibility/secrecy
|
||||
tags
|
||||
```
|
||||
|
||||
Memories, rumours, reputation, and quests should reference or transform these
|
||||
facts. Generated text is presentation; structured state remains authoritative.
|
||||
|
||||
### Emergent quest principle
|
||||
|
||||
A quest candidate should normally require:
|
||||
|
||||
- a real unresolved condition;
|
||||
- an NPC or institution that knows or cares about it;
|
||||
- a plausible way to communicate it;
|
||||
- one or more achievable interventions;
|
||||
- consequences that update the source simulation.
|
||||
|
||||
Avoid creating a duplicate quest-only bandit, item, victim, or relationship
|
||||
when an existing simulated entity can provide the situation.
|
||||
|
||||
### Performance principle
|
||||
|
||||
Design for scale, but optimize measured bottlenecks:
|
||||
|
||||
- keep headless benchmarks;
|
||||
- record agent count, simulated duration, tick cost, and allocations;
|
||||
- prefer event-driven/scheduled updates;
|
||||
- use spatial partitioning for local queries;
|
||||
- batch homogeneous work when profiling justifies it;
|
||||
- avoid premature native extensions or data-oriented rewrites before the
|
||||
behavior model stabilizes.
|
||||
|
||||
## Development strategy
|
||||
|
||||
The project has two interleaved tracks.
|
||||
|
||||
### Living simulation
|
||||
|
||||
- deterministic clock and state;
|
||||
- data-driven needs, professions, and actions;
|
||||
- inventories and economic flow;
|
||||
- events, history, relationships, and rumours;
|
||||
- simulation LOD and performance;
|
||||
- emergent opportunities and quests.
|
||||
|
||||
### Living presentation
|
||||
|
||||
- Jajce-inspired terrain composition;
|
||||
- attractive lighting, water, foliage, and weather;
|
||||
- readable characters and professions;
|
||||
- visible work, transport, and consequences;
|
||||
- interaction UI and simulation inspection;
|
||||
- combat feel, companions, and command feedback.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
The next coherent visual slice should then aim for:
|
||||
|
||||
- one attractive valley section;
|
||||
- six named villagers;
|
||||
- three visibly distinct workplaces;
|
||||
- food and wood as location-based resources;
|
||||
- visible gathering, carrying, storing, and consuming;
|
||||
- hunger and energy;
|
||||
- one understandable shortage crisis;
|
||||
- direct player assistance and priority influence;
|
||||
- day/night presentation;
|
||||
- an in-game reason inspector;
|
||||
- deterministic replay or scenario reset;
|
||||
- save/load for the slice;
|
||||
- a stable 20–30 minute session.
|
||||
|
||||
Safety and knowledge can remain present, but their deeper production chains
|
||||
should follow a complete food loop rather than grow in parallel.
|
||||
|
||||
## Out of scope until the simulation garden works
|
||||
|
||||
- full regional map;
|
||||
- large city population;
|
||||
- multiplayer;
|
||||
- procedural world generation;
|
||||
- generations and inheritance;
|
||||
- complete market simulation;
|
||||
- kingdom-scale diplomacy;
|
||||
- large battles;
|
||||
- broad crafting catalog;
|
||||
- fully generated dialogue;
|
||||
- multiple large production chains;
|
||||
- production-quality character customization.
|
||||
|
||||
These remain part of the vision, not the next implementation target.
|
||||
|
||||
## Agent working guidelines
|
||||
|
||||
1. Read this document, [the learning roadmap](LEARNING_ROADMAP.md),
|
||||
[the ResourceNode migration](RESOURCE_NODE_MIGRATION.md), and
|
||||
[the build-in-public plan](BUILD_IN_PUBLIC_PLAN.md) before proposing a large
|
||||
architectural or world-production change.
|
||||
2. Inspect `git status` and preserve unrelated user changes.
|
||||
3. Treat `addons/terrain_3d/` and `demo/` as third-party code unless a task
|
||||
explicitly concerns the plugin.
|
||||
4. Preserve Godot `.uid` and asset `.import` sidecars. They are tracked project
|
||||
metadata; `.godot/` is the disposable cache.
|
||||
5. Keep simulation rules independent of visuals and loaded scenes.
|
||||
6. Prefer small vertical behavior slices over broad scaffolding.
|
||||
7. When adding a decision, add a way to inspect why it occurred.
|
||||
8. When adding persistent state, define how it saves and migrates.
|
||||
9. When optimizing, include a reproducible benchmark or measurement.
|
||||
10. Keep new systems data-driven only where it improves reuse or iteration;
|
||||
avoid abstraction without a demonstrated consumer.
|
||||
11. Use Conventional Commits.
|
||||
12. Update these documents when a decision materially changes the vision,
|
||||
architecture, milestones, or current-state description.
|
||||
|
||||
## Definition of “reusable for the future game”
|
||||
|
||||
A system is reusable when:
|
||||
|
||||
- it has no dependency on this prototype's scene paths or placeholder zones;
|
||||
- definitions can be supplied as data;
|
||||
- mutable state is serializable;
|
||||
- behavior can be exercised headlessly;
|
||||
- presentation communicates through an adapter or events;
|
||||
- performance characteristics are measured;
|
||||
- its public API is documented by real use, not speculative abstraction.
|
||||
|
||||
Reusable does not necessarily mean a separate Godot plugin. Extract a library
|
||||
only after the API has stabilized through use.
|
||||
|
||||
## Glossary
|
||||
|
||||
- **Active NPC:** A fully represented nearby character with a Godot scene node.
|
||||
- **Agent:** A simulated decision-making entity, usually an NPC.
|
||||
- **Event:** A structured fact that something happened in world time.
|
||||
- **History:** Persisted events and their enduring consequences.
|
||||
- **Memory:** An NPC's retained interpretation or knowledge of events.
|
||||
- **Presentation adapter:** Code that translates simulation state into scenes,
|
||||
animation, audio, UI, and player input.
|
||||
- **Quest:** A player-facing framing and tracking mechanism for an opportunity
|
||||
or unresolved condition.
|
||||
- **Reason trace:** Data explaining the inputs and scores behind a decision.
|
||||
- **Simulation garden:** A small, attractive, controlled world used to validate
|
||||
deep systems and make them watchable.
|
||||
- **Simulation LOD:** Changing computational fidelity based on relevance while
|
||||
preserving important identity and state.
|
||||
- **World event:** A consequential state transition that may be witnessed,
|
||||
remembered, communicated, and acted upon.
|
||||
@@ -0,0 +1,517 @@
|
||||
# The Steward — ResourceNode Migration Plan
|
||||
|
||||
## Decision
|
||||
|
||||
The current task zones are temporary prototype scaffolding.
|
||||
|
||||
NPCs and the player should ultimately interact with actual world objects rather
|
||||
than travel to one abstract marker per task:
|
||||
|
||||
```text
|
||||
Current:
|
||||
gather_food -> FarmZone -> village food increases
|
||||
|
||||
First migration:
|
||||
gather_food -> choose BerryBush_01 -> travel to its interaction point
|
||||
-> extract berries -> bush amount decreases
|
||||
-> village food increases by the extracted amount
|
||||
```
|
||||
|
||||
This migration should happen on the current flat map before the Jajce
|
||||
environment is integrated. It is easier to debug target selection, reservation,
|
||||
depletion, and task completion without terrain and navigation changes happening
|
||||
at the same time.
|
||||
|
||||
The old zones remain only as a temporary fallback while actions are migrated.
|
||||
They are not part of the target architecture.
|
||||
|
||||
## Why this is the next systems step
|
||||
|
||||
Resource nodes provide the first concrete bridge between:
|
||||
|
||||
- abstract simulation decisions;
|
||||
- spatial target selection;
|
||||
- active-world navigation;
|
||||
- finite world state;
|
||||
- visible cause and effect;
|
||||
- player and NPC use of the same objects;
|
||||
- future inventories, ownership, regeneration, and persistence.
|
||||
|
||||
They also make build-in-public footage more legible. A viewer can understand a
|
||||
villager walking to a specific berry bush and depleting it more easily than a
|
||||
villager entering an invisible “food zone.”
|
||||
|
||||
## Scope the first version correctly
|
||||
|
||||
The first `ResourceNode` supports only depletable material sources:
|
||||
|
||||
- berry bush or crop source -> food;
|
||||
- tree or wood pile -> wood.
|
||||
|
||||
Do not initially use `ResourceNode` for:
|
||||
|
||||
- beds or campfires;
|
||||
- guard posts;
|
||||
- study locations;
|
||||
- food storage;
|
||||
- homes;
|
||||
- generic workstations.
|
||||
|
||||
Those objects share target-selection behavior but not resource-extraction
|
||||
semantics.
|
||||
|
||||
The likely family of world targets is:
|
||||
|
||||
```text
|
||||
WorldActionTarget
|
||||
├── ResourceNode finite extraction: bush, tree, ore
|
||||
├── ActivitySite rest, patrol, study, socialize
|
||||
├── StorageNode deposit and withdraw items
|
||||
└── Workstation transform inputs into outputs
|
||||
```
|
||||
|
||||
Do not implement this complete inheritance tree now. Build `ResourceNode` from
|
||||
real requirements, then extract shared target behavior when a second target
|
||||
type proves what is actually common.
|
||||
|
||||
## Fit with the current code
|
||||
|
||||
The existing flow is:
|
||||
|
||||
```text
|
||||
SimNPC chooses a task string
|
||||
-> SimulationManager emits npc_task_changed
|
||||
-> WorldViewManager maps the task to one Marker3D
|
||||
-> NpcVisual travels to that marker
|
||||
-> arrival tells SimulationManager to start work
|
||||
-> task duration completes
|
||||
-> SimVillage applies a hard-coded task result
|
||||
```
|
||||
|
||||
The migrated flow should become:
|
||||
|
||||
```text
|
||||
SimNPC chooses an action
|
||||
-> target resolver finds available matching ResourceNodes
|
||||
-> one target is reserved for the NPC
|
||||
-> NPC simulation stores the target's stable ID
|
||||
-> NpcVisual travels to the target interaction point
|
||||
-> arrival begins work
|
||||
-> completion extracts the actual available amount
|
||||
-> village receives exactly that amount
|
||||
-> target updates or becomes depleted
|
||||
-> reservation is released
|
||||
```
|
||||
|
||||
During migration:
|
||||
|
||||
```text
|
||||
gather_food -> prefer matching ResourceNode -> fallback FarmZone
|
||||
gather_wood -> prefer matching ResourceNode -> fallback ForestZone
|
||||
other tasks -> existing zones
|
||||
```
|
||||
|
||||
Fallbacks should log clearly so accidental reliance on zones is visible.
|
||||
|
||||
## Repository-specific file layout
|
||||
|
||||
Keep scripts beside their feature scenes, matching the repository's existing
|
||||
feature-oriented structure:
|
||||
|
||||
```text
|
||||
world/
|
||||
└── resource_nodes/
|
||||
├── ResourceNode.gd
|
||||
├── ResourceNode.gd.uid
|
||||
└── ResourceNode.tscn
|
||||
```
|
||||
|
||||
Add instances under the current `main.tscn` while developing:
|
||||
|
||||
```text
|
||||
Main
|
||||
├── ResourceNodes
|
||||
│ ├── BerryBush_01
|
||||
│ ├── BerryBush_02
|
||||
│ ├── Tree_01
|
||||
│ └── Tree_02
|
||||
└── TaskZone temporary fallback
|
||||
```
|
||||
|
||||
When `JajceWorld` is integrated, move or recreate the world-object instances
|
||||
under:
|
||||
|
||||
```text
|
||||
JajceWorld
|
||||
└── WorldObjects
|
||||
└── ResourceNodes
|
||||
```
|
||||
|
||||
Target discovery must not depend on that exact scene path. Resource nodes should
|
||||
register through a group or a small registry.
|
||||
|
||||
## First ResourceNode contract
|
||||
|
||||
The first node should answer:
|
||||
|
||||
- What is my stable world-object ID?
|
||||
- Which action can use me?
|
||||
- Which resource do I yield?
|
||||
- How much remains?
|
||||
- How much can one completed action extract?
|
||||
- Am I enabled and usable?
|
||||
- Who, if anyone, has reserved me?
|
||||
- Where should an active character stand?
|
||||
- Did extraction change or deplete me?
|
||||
|
||||
Recommended initial data:
|
||||
|
||||
```gdscript
|
||||
class_name ResourceNode
|
||||
extends Node3D
|
||||
|
||||
signal amount_changed(node_id: StringName, amount_remaining: float)
|
||||
signal depleted(node_id: StringName)
|
||||
signal reservation_changed(node_id: StringName, agent_id: int)
|
||||
|
||||
@export var node_id: StringName
|
||||
@export var action_id: StringName = &"gather_food"
|
||||
@export var resource_id: StringName = &"food"
|
||||
@export var amount_remaining: float = 10.0
|
||||
@export var yield_per_action: float = 2.0
|
||||
@export var enabled: bool = true
|
||||
@export var can_npcs_use: bool = true
|
||||
@export var can_player_use: bool = true
|
||||
@export var hide_visual_when_depleted: bool = false
|
||||
|
||||
@onready var interaction_point: Marker3D = $InteractionPoint
|
||||
```
|
||||
|
||||
Use `StringName` IDs as a small migration step away from duplicated free-form
|
||||
`String` values. Later, action and resource definitions can become custom
|
||||
`Resource` assets without changing every world node's conceptual contract.
|
||||
|
||||
### Avoid duplicated state
|
||||
|
||||
Do not store a separately mutable `is_depleted` flag in the first version.
|
||||
Derive it:
|
||||
|
||||
```gdscript
|
||||
func is_depleted() -> bool:
|
||||
return amount_remaining <= 0.0
|
||||
```
|
||||
|
||||
If regeneration or non-depleting sources later require more states, introduce
|
||||
them deliberately.
|
||||
|
||||
### Extraction result is authoritative
|
||||
|
||||
Extraction must return the amount actually removed:
|
||||
|
||||
```gdscript
|
||||
func extract(requested_amount: float = yield_per_action) -> float:
|
||||
if not can_extract():
|
||||
return 0.0
|
||||
|
||||
var extracted := minf(requested_amount, amount_remaining)
|
||||
amount_remaining -= extracted
|
||||
# Emit signals and update presentation.
|
||||
return extracted
|
||||
```
|
||||
|
||||
The village receives this returned amount. Do not let both `ResourceNode` and
|
||||
`SimVillage.apply_npc_task()` independently award the configured yield.
|
||||
|
||||
### Stable IDs
|
||||
|
||||
`node_id` must be:
|
||||
|
||||
- non-empty;
|
||||
- unique inside the world;
|
||||
- stable across save/load;
|
||||
- independent of display name and scene path.
|
||||
|
||||
For the first hand-authored nodes, explicit IDs such as
|
||||
`&"berry_bush_01"` are acceptable. Add startup validation for duplicates.
|
||||
|
||||
## Scene structure
|
||||
|
||||
The first reusable scene can remain small:
|
||||
|
||||
```text
|
||||
ResourceNode (Node3D)
|
||||
├── Visual (Node3D)
|
||||
├── InteractionPoint (Marker3D)
|
||||
└── DebugLabel (Label3D)
|
||||
```
|
||||
|
||||
Use `Node3D` for `Visual` rather than requiring `MeshInstance3D`; this permits a
|
||||
mesh, imported model, particles, or multiple visual children later.
|
||||
|
||||
The debug label should be controlled by a project/debug setting or inspector
|
||||
toggle rather than a compile-time constant. It should show:
|
||||
|
||||
- node ID;
|
||||
- resource;
|
||||
- remaining amount;
|
||||
- reservation owner;
|
||||
- depleted/disabled state.
|
||||
|
||||
## Reservation rules
|
||||
|
||||
Without reservations, several NPCs can choose one nearly depleted bush and all
|
||||
walk toward it.
|
||||
|
||||
The first version needs a single-user reservation:
|
||||
|
||||
```text
|
||||
available -> reserved by agent -> in use -> released
|
||||
```
|
||||
|
||||
A reservation must be released when:
|
||||
|
||||
- the task completes;
|
||||
- the NPC dies;
|
||||
- the target depletes;
|
||||
- travel fails;
|
||||
- the action is interrupted or replaced;
|
||||
- the target is disabled;
|
||||
- the NPC or visual is removed.
|
||||
|
||||
Reservation is not ownership. Ownership, permission, crime, and social
|
||||
consequences belong to later systems.
|
||||
|
||||
## Target selection
|
||||
|
||||
The first resolver may choose the nearest available matching node. It must still
|
||||
return a reason trace:
|
||||
|
||||
```text
|
||||
candidate BerryBush_01: accepted, distance 8.2
|
||||
candidate BerryBush_02: rejected, reserved by NPC 2
|
||||
candidate BerryBush_03: rejected, depleted
|
||||
selected BerryBush_01
|
||||
```
|
||||
|
||||
Future scoring can include:
|
||||
|
||||
- travel cost;
|
||||
- remaining yield;
|
||||
- danger;
|
||||
- tool requirements;
|
||||
- ownership and permission;
|
||||
- crowding;
|
||||
- profession;
|
||||
- expected completion time;
|
||||
- knowledge of the target.
|
||||
|
||||
Do not implement those before the nearest-available version works.
|
||||
|
||||
## Simulation-state boundary
|
||||
|
||||
The first `ResourceNode` is a Godot world node and may temporarily own its
|
||||
remaining amount. That is acceptable for the migration prototype, but it is not
|
||||
the final persistence boundary.
|
||||
|
||||
Preserve these rules now:
|
||||
|
||||
- `SimNPC` stores a target ID, not a `Node` reference;
|
||||
- simulation decisions do not store `NodePath`;
|
||||
- visual movement receives only a resolved position;
|
||||
- target extraction is coordinated through one adapter/registry;
|
||||
- node state has an obvious serialization representation.
|
||||
|
||||
Later, authoritative resource state can move into serializable simulation
|
||||
records while `ResourceNode` becomes its active-world presentation.
|
||||
|
||||
## Required changes by existing file
|
||||
|
||||
### `simulation/SimNPC.gd`
|
||||
|
||||
- add a selected target ID;
|
||||
- clear it when returning to idle or changing actions;
|
||||
- do not store `ResourceNode` references;
|
||||
- preserve current task lifecycle during the first migration.
|
||||
|
||||
### `world/world_view_manager.gd`
|
||||
|
||||
- query available resource nodes for `gather_food` and `gather_wood`;
|
||||
- reserve the selected target;
|
||||
- send its interaction position to `NpcVisual`;
|
||||
- use the old marker only when no valid node exists;
|
||||
- distinguish arrival at a specific target from arrival at a generic task zone.
|
||||
|
||||
Target discovery can begin here, but should move into a focused resolver or
|
||||
registry once selection has meaningful rules.
|
||||
|
||||
### `simulation/SimulationManager.gd`
|
||||
|
||||
- coordinate target completion and reservation release;
|
||||
- extract from the selected node once;
|
||||
- give `SimVillage` the actual result;
|
||||
- handle interruption, death, and failure cleanup;
|
||||
- prevent old hard-coded production from also firing.
|
||||
|
||||
### `simulation/SimVillage.gd`
|
||||
|
||||
- add an explicit resource-delta method;
|
||||
- separate generic resource application from task-name matching;
|
||||
- retain current action effects for non-migrated tasks.
|
||||
|
||||
### `player/player.gd`
|
||||
|
||||
- eventually resolve and use the same world targets as NPCs;
|
||||
- do not add a second player-only harvest path with different rules.
|
||||
|
||||
Player use can follow NPC migration rather than block its first test.
|
||||
|
||||
## Migration phases
|
||||
|
||||
### Phase 1 — ResourceNode scene and registration
|
||||
|
||||
- create `ResourceNode.gd` and `ResourceNode.tscn`;
|
||||
- create a `ResourceNodes` parent in `main.tscn`;
|
||||
- place two bushes and two trees;
|
||||
- give every node a stable unique ID;
|
||||
- show debug state;
|
||||
- expose group/registry discovery.
|
||||
|
||||
**Exit:** nodes register, validate IDs, change amount, deplete, and update debug
|
||||
presentation without involving NPC logic.
|
||||
|
||||
### Phase 2 — Food target selection and reservation
|
||||
|
||||
- migrate only `gather_food`;
|
||||
- find nearest available bush;
|
||||
- reserve it;
|
||||
- store its ID on the NPC;
|
||||
- navigate to its interaction point;
|
||||
- release on interruption and death;
|
||||
- retain `FarmZone` fallback with a visible warning.
|
||||
|
||||
**Exit:** two NPCs do not select the same single-user bush, and an NPC can
|
||||
replan when its chosen bush becomes unavailable.
|
||||
|
||||
### Phase 3 — Authoritative completion
|
||||
|
||||
- extract only after work duration completes;
|
||||
- return actual extracted amount;
|
||||
- apply that amount to village food;
|
||||
- prevent double production;
|
||||
- deplete and hide/alter the source as configured;
|
||||
- choose a new source for later tasks.
|
||||
|
||||
**Exit:** resource conservation holds:
|
||||
|
||||
```text
|
||||
total bush decrease == total village food increase
|
||||
```
|
||||
|
||||
for the initial gather-food scenario.
|
||||
|
||||
### Phase 4 — Wood and player parity
|
||||
|
||||
- migrate `gather_wood`;
|
||||
- configure tree visuals and yields;
|
||||
- route player interaction through the same extraction contract;
|
||||
- add clear feedback for unavailable or depleted targets.
|
||||
|
||||
**Exit:** food and wood no longer require their abstract zones during normal
|
||||
play. NPC and player extraction obey the same availability and depletion rules.
|
||||
|
||||
### Phase 5 — Jajce world placement
|
||||
|
||||
- place bushes and trees as real world objects in `JajceWorld`;
|
||||
- keep their IDs stable;
|
||||
- validate interaction points against terrain and navigation;
|
||||
- use the old task zones only for rest, eat, patrol, and study;
|
||||
- verify target discovery does not rely on parent scene paths.
|
||||
|
||||
**Exit:** the existing food and wood loops work after moving from the flat map
|
||||
to Terrain3D.
|
||||
|
||||
### Phase 6 — Remove the remaining zone model
|
||||
|
||||
This is not part of the first ResourceNode implementation.
|
||||
|
||||
Introduce the next concrete target types:
|
||||
|
||||
- storage for eating and item transfer;
|
||||
- activity sites for rest, study, and guard work;
|
||||
- workstations when production recipes begin.
|
||||
|
||||
Remove each old zone only when its replacement has:
|
||||
|
||||
- target selection;
|
||||
- active interaction position;
|
||||
- reservation/capacity;
|
||||
- completion or ongoing-use behavior;
|
||||
- failure/interruption handling;
|
||||
- debug visibility;
|
||||
- save representation.
|
||||
|
||||
**Exit:** `TaskZone` and task-to-marker mapping are deleted, not merely unused.
|
||||
|
||||
## Test scenarios
|
||||
|
||||
At minimum, exercise:
|
||||
|
||||
1. one NPC and one bush;
|
||||
2. two NPCs and one bush;
|
||||
3. one NPC and two bushes at different distances;
|
||||
4. selected bush depletes before arrival;
|
||||
5. selected bush depletes exactly on completion;
|
||||
6. NPC dies while traveling;
|
||||
7. NPC dies while working;
|
||||
8. navigation fails;
|
||||
9. node is disabled while reserved;
|
||||
10. fallback zone is used because no matching node exists;
|
||||
11. player and NPC contend for the same source;
|
||||
12. duplicate node IDs are detected.
|
||||
|
||||
Use a fixed seed and concise reason tracing where possible.
|
||||
|
||||
## Video opportunities
|
||||
|
||||
The migration naturally creates strong short-form demonstrations:
|
||||
|
||||
- “My NPCs stopped walking to invisible work zones.”
|
||||
- “Two hungry villagers want the same berry bush.”
|
||||
- “This bush contains the food—the UI counter no longer creates it.”
|
||||
- “What happens when the closest resource is already reserved?”
|
||||
- “A depleted forest changes what every woodcutter decides.”
|
||||
|
||||
Show the beautiful result first, then reveal target selection, reservation, and
|
||||
resource conservation through debug presentation.
|
||||
|
||||
## Immediate implementation order
|
||||
|
||||
1. Create `world/resource_nodes/ResourceNode.gd`.
|
||||
2. Create `world/resource_nodes/ResourceNode.tscn`.
|
||||
3. Add `Main/ResourceNodes`.
|
||||
4. Place `BerryBush_01`, `BerryBush_02`, `Tree_01`, and `Tree_02`.
|
||||
5. Add stable IDs and registration validation.
|
||||
6. Verify extraction and depletion manually.
|
||||
7. Add target ID to `SimNPC`.
|
||||
8. Migrate `gather_food` target selection.
|
||||
9. Add reservation and cleanup.
|
||||
10. Apply actual extracted yield on completion.
|
||||
11. Add fixed-seed regression scenarios.
|
||||
12. Migrate wood.
|
||||
13. Give the player the same extraction path.
|
||||
14. Continue with the Jajce world scaffold.
|
||||
|
||||
## Definition of done for the first migration
|
||||
|
||||
- Food and wood use actual finite world objects.
|
||||
- NPCs select available targets and reserve them.
|
||||
- NPC state stores stable target IDs rather than nodes or scene paths.
|
||||
- Active visuals navigate to explicit interaction points.
|
||||
- Work duration completes before extraction.
|
||||
- Village resources increase only by the amount actually extracted.
|
||||
- Depletion changes availability and presentation.
|
||||
- Failure, interruption, and death release reservations.
|
||||
- Old food and forest zones remain only as logged fallbacks.
|
||||
- The player and NPCs can use the same extraction contract.
|
||||
- Behavior is inspectable and covered by reproducible scenarios.
|
||||
|
||||
Reference in New Issue
Block a user