Files
gamedev-the-steward/docs/PROJECT_CONTEXT.md
T
2026-07-30 23:03:15 +02:00

1104 lines
48 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# The Steward — Project Context
> Agent-facing context for understanding the project quickly.
>
> Snapshot basis: repository state on July 16, 2026. Treat the code as the
> source of truth when this document and the implementation differ.
See the [documentation map](README.md) for the authority and scope of each plan.
## Quick orientation
**The Steward** is currently a small Godot prototype for an embodied village
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. NPC `gather_food` and `gather_wood` tasks now use finite
world `ResourceNode` instances (berry bushes and trees) rather than abstract
zone markers. The obsolete farm, forest, and activity markers have been
removed. Eating and food transfer target the typed village pantry, while rest,
study, and patrol target typed activity sites. The 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 (`gdformat`, `gdlint`, headless Godot 4.7 scenarios,
and GUT run through the local quality gate)
- **Main scene:** `res://main.tscn`
- **Terrain:** Terrain3D 1.0.2 is installed and enabled
- **Jajce runtime:** reusable 512 m Terrain3D seed, stable ResourceNode
placement, larger citadel/village-center composition, terrain-following river
ribbon, reactive camera-local grass, exact indexed finite-resource discovery,
and Terrain3D-derived runtime navigation with collision guardrails
- **Lookdev baseline:** `Jajce Lookdev 01` is captured at
`docs/baselines/jajce_lookdev_01.png` with
`tools/capture_jajce_lookdev.gd`
- **Matched center baseline:** `Jajce Center 02` preserves a fixed before/after
overview plus a close grass-readability capture under `docs/baselines/`
- **Runtime baseline:** `Simulation Garden 01` is captured as paired debug and
cinematic `main.tscn` images plus an empty/restocked pantry close pair under
`docs/baselines/` with `tools/capture_simulation_garden.gd`
- **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` instances the reusable Jajce Terrain3D world.
- The player is a `CharacterBody3D` with a compact multi-part stylized visual,
velocity-driven walk motion, and unchanged primitive collision.
- WASD movement is camera-relative.
- The elevated third-person camera rotates with the mouse, uses smoothed
follow/focus behavior, and exposes an opt-in presentation preset for
reproducible runtime captures.
- Pressing `E` near a berry bush or tree extracts its configured yield into the
village through the same `ResourceNode` contract used by NPCs.
- Guard, study, rest, and food interactions now use typed world sites.
- `Escape` releases captured mouse input.
### Village simulation
The simulation currently creates six NPCs:
- Amina
- Tarik
- Jasmin
- Elma
- Mirza
- Lejla
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;
- home position and carried inventory;
- last action and mourning duration;
- 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
|
+-> navigation_failed -> wander -> idle
```
NPCs currently choose among:
- gather food;
- gather wood;
- deposit carried food or wood;
- withdraw and eat food;
- patrol;
- study;
- sleep;
- 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 typed target position. 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 world targets
The former farm, forest, food, guard, study, and rest markers have been deleted.
The runtime now uses semantic world targets:
**Migration status:** NPC `gather_food` and `gather_wood` target `ResourceNode`
instances (berry bushes and trees), with no marker fallback. Non-resource
actions route through typed sites:
- patrol → `ActivitySite` (`guard_post`);
- study → `ActivitySite` (`study_desk`);
- rest → `ActivitySite` (`rest_bench`);
- eat/deposit/withdraw → `StorageNode` (`village_pantry`).
The player also harvests food and wood directly from nearby `ResourceNode`
instances. Extraction returns the actual amount removed, updates the village by
that amount, and releases an NPC reservation if the source is depleted.
Future resource expansion should add many finite `ResourceNode` instances rather
than broad resource zones: trees in foliage clusters, berry patches, animal
camps, and village stockpiles can be ranked by reachability, distance, safety,
profession, and NPC comfort range. The current resolver already combines
distance with resource `safety_risk`, `comfort_distance`, and
`discovery_priority` metadata. Loaded anchors are indexed by
`ActiveWorldAdapter`; exact expanding queries usually inspect only nearby cells
but retain far sources whenever their authoritative metadata can still win.
### Jajce scaffold
`world/jajce/JajceWorld.tscn` provides the reusable environment instanced by
`main.tscn`:
- a centered 512 m Terrain3D landscape split across four regions;
- deterministic shaped terrain data and six game-owned surface layers;
- a larger summit citadel, eight cascading houses, mill, full-span bridge, and
a deterministic Terrain3D watercourse with an upper stream, raised waterfall
shelf, rock-framed drop, plunge basin, mist, and curved downstream ribbon;
- authored dirt path strips that make the current village task loop readable;
- compact silhouette props for the ridge landmark, guard, study, and rest
sites, plus a physical pantry whose empty/low/stocked arrangement follows
authoritative food storage;
- warm sky, fog, shadows, coherent wind-reactive foliage, and breeze-aligned
chimney smoke;
- short patchy camera-local grass that receives at most eight real player/NPC
transforms, authored conifer clusters, and oversized ambient butterflies;
- one sparse terrain-aware calligraphic gust field with two or three soft
tapered strokes per burst;
- eighteen ResourceNodes preserving stable food/wood discovery IDs, including
one riverbank cluster that nests two finite anchors among 28 decorative
fern/flower/stone instances in three bounded MultiMesh batches;
- typed village pantry storage and typed guard, study, and rest activity sites;
- a Terrain3D-derived baked navigation mesh covering the current playable loop;
- base collision/navigation guardrails that keep Terrain3D collision enabled,
keep the old greybox ground out of runtime physics, require paths to reach
their targets, and compare required navigation paths against the Terrain3D
height field;
- a look-development scene and camera;
- reproducible lookdev and runtime capture scripts plus review notes under
`docs/baselines/`.
This is a runtime integration proof, not the final terrain composition.
Terrain3D startup requires several physics frames before reliable
NavigationServer path queries; the scaffold and runtime tests capture that
synchronization requirement.
### Current UI
A small village panel displays:
- food;
- wood;
- safety;
- knowledge;
- starving NPC count;
- selected village modifiers.
- a Tab-cycled NPC inspector with profession, needs, task state, destination,
decision reason, utility scores, directed familiarity/trust, and the exact
completed event that last changed trust;
- a compact selected-person history that separates up to four importance-ranked
retained memories from the NPC's three latest objective personal actions;
- a cardless active `Village need` line sourced from the real pantry target,
food progress, and interested villager, with open/resolved detail only in
that person's inspector.
NPC name/profession labels, definition-driven colors and props, carried-food
visuals, compact task glyphs, and a brief amber blossom on real trust gains make
active simulation state readable in the world. The F10 cinematic mode hides
debug labels while preserving task glyphs and transient social reactions. An
open pantry opportunity adds a restrained empty-bowl concern cue only to its
interested villager; a real refill changes the pantry props, clears concern,
and produces one brief pantry response.
## Runtime architecture
### `simulation/SimNPC.gd`
`SimNPC` is a `RefCounted` simulation model. It owns needs, task state,
profession identity, carried inventory, starvation, and death. Focused systems
select and execute actions against that state.
This separation from the visual node is an important architectural seed and
should be preserved.
### `simulation/SimVillage.gd`
`SimVillage` is a `RefCounted` aggregate for synchronized village resource
views, modifiers, and priorities.
### `simulation/SimulationManager.gd`
`SimulationManager` is currently a scene-tree `Node` that:
- owns the village and NPC array;
- advances deterministic ticks through `SimulationClock`;
- creates NPCs;
- coordinates selection, travel, reservations, and task completion;
- emits village, task, and death signals;
- exposes the bounded player/simulation command API.
Focused `RefCounted` collaborators keep rule ownership visible:
- action systems own selection, execution progress, and target resolution;
- `SimulationPopulationView` owns the disposable all/living/starving stable-ID
query indexes rebuilt at deterministic tick boundaries;
- `VillageEconomy` owns storage/inventory transactions and synchronized
village resource views;
- `SimulationEventLog` owns deterministic event history and queries;
- `EventKnowledgeSystem` owns per-NPC known-event references, immutable
first-acquisition time/provenance, actor/nearby evidence capture, bounded
one-hop communication, deterministic recent-memory retention, and stable
importance ranking for presentation/communication queries;
- `RelationshipSystem` owns directed relationship state, event-driven trust
consequences, and deterministic social queries;
- `VillageOpportunitySystem` projects the proven pantry-food and blocked-work
wood conditions into persisted open/resolved/invalidated records without
changing resources or assigning work.
`SimulationManager` remains the scene-tree façade and signal boundary rather
than duplicating these responsibilities across additional manager nodes.
### `world/world_view_manager.gd`
`WorldViewManager` bridges simulation data to visible NPC nodes. It:
- instantiates `NpcVisual` scenes;
- supplies active visual positions for simulation-owned target resolution;
- sends resolved travel destinations to visuals;
- reports arrival and navigation failure back to `SimulationManager`;
- synchronizes successful visual movement into authoritative NPC position;
- applies visual death state;
- turns authoritative relationship-change signals into observer-only transient
presentation cues without queuing or persisting them;
- derives pantry stock props and interested-villager concern from authoritative
storage/opportunity state, including state-only rebuilding after restore.
### `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;
- presents definition-driven profession silhouettes, carried resources, task
glyphs, walk motion, brief trust-gain blossoms, opportunity concern, and
death state.
### `player/player.gd` and `player/camera_rig.gd`
These implement camera-relative character movement, physical interaction
proximity checks, ResourceNode harvesting, mouse capture, and the elevated
follow camera.
### `world/ui/ui.gd`
The UI subscribes to village, task, event, knowledge, relationship, and
opportunity changes. It formats aggregate state and resolves known facts,
relationship causes, and opportunity lifecycle details through manager queries
without owning or recomputing simulation facts. `village_whisper_hud.gd` is a
separate transient player layer that formats the same authoritative signals and
remains independent of the development overlays.
## Current runtime flow
```text
SimulationManager tick
-> ActionExecutionSystem advances needs/work
-> ActionSelectionSystem chooses an action for idle NPCs
-> npc_target_requested
-> WorldViewManager supplies the active visual position
-> ActionTargetResolver consumes ActiveWorldAdapter facts
-> SimulationManager stores/reserves the target
-> npc_travel_requested
-> WorldViewManager commands visual travel
|
v
NpcVisual navigates through the active world
|
+-- arrived_at_target signal
| |
| v
| SimulationManager marks NPC as working
| -> at a shared activity, one nearby worker may communicate one direct fact
| |
| v
| Later ticks complete work
| |
| v
| ResourceStateRecord.extract() -> NPC inventory
| -> VillageEconomy transfers inventory/storage as actions complete
| -> SimulationEventLog appends completed facts
| -> EventKnowledgeSystem captures actor/nearby knowledge
| -> RelationshipSystem applies evidence-gated social consequences
| -> VillageOpportunitySystem may open, resolve, or invalidate a real need
| |
| v
| village_changed signal updates the UI
|
+-- navigation_failed signal
|
v
SimulationManager releases reservation, sets last_task, sends NPC to wander
```
## 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
│ ├── PlayerVisual.tscn
│ ├── player.gd
│ ├── player_visual.gd
│ └── npc/
│ ├── NpcVisual.gd
│ └── NpcVisual.tscn
├── simulation/
│ ├── SimNPC.gd
│ ├── SimVillage.gd
│ ├── SimulationClock.gd
│ ├── SimulationManager.gd
│ ├── actions/ Selection, execution, and target resolution
│ ├── animals/ Animal needs, routines, reservations, and care
│ ├── benchmark/ Population/history and resource-query workloads
│ ├── definitions/ Stable IDs and custom definition resources
│ ├── economy/ Inventory and storage transactions
│ ├── events/ Ordered event history and queries
│ ├── knowledge/ Per-NPC facts, provenance, transfer, and retention
│ ├── opportunities/ Knowledge-gated unresolved-condition projection
│ ├── population/ Transient per-tick NPC query indexes
│ ├── persistence/ Validated local save-slot storage
│ ├── relationships/ Directed social consequences and queries
│ └── state/ Versioned simulation-state records
├── tests/
│ ├── action_system_boundaries_test.gd
│ ├── communicated_knowledge_consequence_test.gd
│ ├── deterministic_simulation_test.gd
│ ├── food_storage_loop_test.gd
│ ├── food_shortage_opportunity_test.gd
│ ├── jajce_world_scaffold_test.gd
│ ├── knowledge_retention_consequence_test.gd
│ ├── jajce_runtime_integration_test.gd
│ ├── loaded_resource_spatial_query_test.gd
│ ├── npc_visual_lifecycle_test.gd
│ ├── opportunity_communication_helper_test.gd
│ ├── relationship_consequence_test.gd
│ ├── resource_node_player_parity_test.gd
│ ├── simulation_definitions_test.gd
│ ├── simulation_state_serialization_test.gd
│ ├── unit/test_village_opportunity_system.gd
│ ├── wood_shortage_opportunity_test.gd
│ └── witnessed_knowledge_consequence_test.gd
├── terrain/jajce/ Dedicated Terrain3D seed data and assets
├── tools/
│ ├── benchmark_loaded_resource_discovery.gd
│ └── generate_jajce_terrain_seed.gd
├── world/
│ ├── animals/
│ │ ├── animal_node.gd
│ │ ├── animal_routine_site.gd
│ │ └── goat/ Goat scene, habitat, visual, and lookdev assets
│ ├── jajce/
│ │ ├── JajceWorld.tscn
│ │ ├── JajceLookdev.tscn
│ │ ├── jajce_world.gd
│ │ ├── beauty_camera.gd
│ │ └── vfx/WindGustField.tscn
│ ├── resource_nodes/
│ │ ├── LoadedResourceSpatialIndex.gd
│ │ ├── ResourceNode.gd
│ │ ├── ResourceNode.gd.uid
│ │ └── ResourceNode.tscn
│ ├── active_world_adapter.gd
│ ├── world_view_manager.gd
│ └── ui/
│ ├── ui.gd
│ └── village_whisper_hud.gd
├── main.tscn
└── project.godot
```
## Important limitations and technical debt
These are expected prototype constraints, not necessarily isolated bugs:
- Action and profession IDs are stable and definition-backed, but several
action effects remain hard-coded.
- Temporary activity markers have been removed; NPC and player food/wood
gathering use `ResourceNode` instances with no fallback, food transfer uses
the typed pantry `StorageNode`, and patrol/study/rest use `ActivitySite`.
- Current NPC, village, resource, storage, animal, event, knowledge,
relationship, opportunity, clock, and RNG state serialize through world
schema v11. F5/F9 provide one validated local quicksave; a save menu,
metadata, and player-transform persistence remain deferred.
- Simulation-owned resource records retain live amounts, reservations, and
usage definitions while ResourceNode scenes are unloaded.
- An explicit fixed-step clock converts frame delta into simulation ticks, but
orchestration still lives on the scene-tree `SimulationManager`.
- Automated coverage includes deterministic same-seed and save/restore
continuation checks, player-parity/resource-contention, flat-map, and Jajce
scaffold scenarios; broader gameplay coverage is still missing.
- Food and wood now move through finite sources, NPC inventory, and typed
village storage. Other village metrics remain aggregate values rather than
located items.
- NPCs have home positions, schedule periods, carried food/wood, and directed
familiarity/trust. They retain direct or one-hop communicated knowledge of a
food deposit or NPC pantry withdrawal, plus direct missing-wood blocked-work
facts, with first-acquisition provenance.
Current trust causes and the trigger of an open opportunity are lasting;
other knowledge is capped and reviewed after one simulated day. NPCs do not
yet have wider social dimensions, goals, line-of-sight/hearing evidence,
personalized reinforcement/decay, false beliefs, or multi-hop rumours.
- The bounded opportunity family supports one open `restock_empty_pantry` or
`supply_missing_wood` need from exact known evidence. Both have exact NPC and
player supply resolutions; the wood need also closes deterministically on
interested-party death or one-day staleness. One read-only query derives and
explains a capable helper, and the matching idle NPC can consume it through
ordinary action selection after urgent self-care and schedule precedence.
There is still no helper assignment, acceptance, rewards, free-form dialogue,
or quest log.
- The reason inspector exposes current decisions, utility rejections, one exact
relationship cause, and a compact person-history view that distinguishes
importance-ranked retained memories from objective personal actions.
- Active navigation is used as if all agents are local; no simulation LOD exists.
- Unloaded traveling NPCs preserve their state but do not yet advance through
abstract travel time.
- Loaded finite-resource anchors have one measured active-world spatial index;
people, buildings, events, and unloaded simulation still have no spatial/LOD
layer.
- SimulationManager still coordinates the tick lifecycle and bounded
player-facing commands, while action rules, active-world queries, economic
transactions, and event history have focused collaborators.
- Path failure and interruption emit a `navigation_failed` signal and send the NPC to wander; this is functional but not yet polished.
- The old greybox navigation source has been replaced by a project-owned
Terrain3D-derived navigation resource. The current bake is still a first
playable-loop pass, so future terrain sculpting should rerun the bake tool and
recheck reachability rather than hand-editing navigation polygons.
- Terrain3D and the bounded Jajce beauty baseline now run in the main game
scene; `Jajce Lookdev 01` and the runtime `Simulation Garden 01` are captured
as reproducible presentation baselines.
- Combat, companions, factions, politics, trade, generalized/multi-hop rumours,
a general quest framework, and regional travel do not yet exist.
- Stylized player/NPC silhouettes, water, foliage, and VFX support the current
build-in-public baseline, while blockout buildings and several work/resource
props remain visibly prototype-grade.
## 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.
The authoritative-boundary decision is recorded in
[ADR 0001](decisions/0001-simulation-authority-boundary.md). The current
`ResourceNode` binding and the `WorldViewManager` active-position bridge follow
this boundary; new inventories, schedules, relationships, and knowledge should
remain scene-independent records and systems.
### Authority and active-world adapters
Persistent mutable state belongs in versioned, serializable simulation records.
Systems mutate those records. Godot nodes:
- present nearby records;
- expose active-world interaction transforms and navigation results;
- translate player input into simulation commands;
- synchronize active position through an explicit adapter;
- never become the only owner of a persistent amount, reservation, action, or
identity.
Target selection may consume facts supplied by the active world, but the
presentation bridge must not author an NPC's decision or persistent target.
### Stable identity
Every persistent entity should eventually have a stable ID:
- 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: scaffold, architecture gate, then simulation garden
Food and wood migration, the minimal `JajceWorld` proof, and the mandatory
architecture gate are complete:
- explicit fixed-step simulation clock;
- seeded per-NPC decision and wander random streams;
- headless fixed-seed scenario with a final-state checksum;
- versioned JSON records for NPC, village, resource, clock, and RNG state;
- deterministic save/restore continuation with exact 64-bit RNG preservation;
- simulation-owned resource amount/reservation state with ResourceNode
presentation binding and unload/rebind coverage;
- stable StringName action/profession IDs plus validated custom definition
resources used by simulation, targeting, generation, and persistence;
- separate selection, execution, target resolution, active-world query, and
visual travel responsibilities;
- authoritative active position and persisted travel destinations;
- checksum-invariant NPC visual unload/reload with reservation preservation.
The location-based food loop is complete and traceable: gathering creates
carried food, depositing fills the pantry, withdrawal retrieves one unit, and
eating consumes it. Each successful transfer creates a persisted structured
event, and active NPCs visibly carry food through presentation derived from
their inventory. The bounded save-slot slice is also complete, including
validation, atomic replacement recovery, and active-visual rebuilding.
Terrain3D runtime integration, the bounded Jajce beauty pass, and the first
simulation-garden runtime capture are complete.
The first relationship and knowledge consequences are also complete:
food-deposit events become separate known facts for their actor and nearby
living NPCs; only an informed hungry familiar NPC gains directed trust. At a
shared non-storage activity, an already-working direct knower can tell one fact
to an arriving nearby villager. The same event remains visible as known fact
and relationship cause, the inspector names the speaker, and the listener's
future work can change without duplicating event history. Importance and
retention now keep current relationship causes lasting, cap other memories,
and forget routine facts at deterministic daily-sized reviews without deleting
the objective event. The selected-person inspector now shows lasting-first
retained memories beside objective personal history, and real trust changes
produce a short observer-only amber blossom without altering saved state.
The first bounded opportunity proof is complete. A positive NPC pantry
withdrawal plus current pantry emptiness opens one need only for a critically
hungry villager who knows that exact event. The persisted record retains its
stable trigger, interested villager, pantry/food target, status, and later
resolution event; active evidence remains lasting. A real later NPC deposit or
player harvest into the pantry resolves it without quest-only history, economy
mutation by the generator, or AI assignment. The compact village/inspector UI
shows this lifecycle without changing the elevated follow camera. The same
facts now have a cardless world expression: empty/low/stocked pantry props, one
interested-villager concern cue, and a brief refill response. Save/load rebuilds
the stable state without replaying the response.
The outcome-defined pantry-crisis demo loop is complete. `F11` reloads a fixed
authored start and packages a measured 2030 second cinematic story with brief
captions: real withdrawal and consumption expose the shortage, a worried
informed villager remains at the empty pantry, and a trusted helper selects a
finite berry source, visibly carries its yield, deposits it, and causes the
physical recovery. A headless lifecycle scenario and an unassisted runtime
timing validator cover the complete path.
The second bounded opportunity proof is complete. Patrol or study that cannot
pay its wood cost records a stable zero-transfer `task_blocked` fact and opens
one `supply_missing_wood` need for its performer. A real NPC wood deposit or
player tree harvest resolves it; interested-party death or one simulated day
of unresolved evidence invalidates it without quest-only history. World schema
v9 and nested opportunity schema v2 preserve open, resolved, and invalidated
history. The two consumers now share `VillageOpportunitySystem`, while their
evidence and care rules remain explicit.
The first capable-helper query is complete. An open food or wood need now
derives one living informed villager with a familiar trusted directed tie and a
real inventory-deposit or finite-resource gather route. Inventory readiness,
trust, profession fit, familiarity, finite-source availability, and stable IDs
produce one deterministic result. The village summary explains that result;
save/load re-derives it, and querying changes no task, reservation, RNG stream,
resource, event, or checksum.
The first autonomous helper consumer is complete. At each idle decision
boundary the manager re-derives capability, and only the matching helper may
select the reported ordinary gather/deposit action. Urgent self-care and
sleep/meal behavior still win; accepted supply work uses the existing target
resolver, finite-node reservation, travel, inventory, and transaction paths.
The ordinary in-progress NPC task can save normally, but no helper assignment,
quest acceptance, reward, or opportunity-specific event is persisted; ordinary
task-start history remains unchanged.
The first direct information-to-help path is complete. At shared activity, a
performer or direct witness now discusses the active need's exact trigger before
newer unrelated facts. The original event and first-source provenance remain
authoritative and one-hop. A newly informed trusted, supplied villager is then
re-derived and autonomously responds through ordinary action selection. A
single cardless warm-amber HUD ribbon presents the real need, named report,
helper response, and resolution without entering simulation or save state.
The bounded Milestone 7 player response is complete. When no capable helper
exists, an ephemeral query now proves an enabled player-usable finite source and
real destination with capacity. The warm-amber whisper briefly explains the
ordinary direct harvest route, then yields immediately when a helper emerges or
the need closes. The result and HUD add no quest acceptance, waypoint, tracker,
save field, RNG draw, or simulation mutation. This completes the Milestone 7
simulation-garden exit proof.
The first Milestone 8 measurement slice is complete. A reusable schema-valid
headless fixture and CLI runner now measure full-fidelity simulation throughput,
phase timing, serialized-state growth, retained knowledge, objective event
growth, and deterministic checksums across 6, 60, and 600 NPCs plus 600 and
6,000 seeded histories. The reviewed Apple M1 Max baseline reaches 65.84 ticks
per second for 600 data-only NPCs, above the initial local 50-ticks-per-second
reference target, while exposing superlinear population cost and rapid
objective-log growth. Workload details and raw samples live in
[`docs/benchmarks/`](benchmarks/SIMULATION_SCALING_BASELINE_01.md).
The first two measured optimizations are complete. A disposable per-tick
population view preserves continuation checksums and improves the 600-NPC
fixture by 23.3%. A separate resource-specific grid inside
`ActiveWorldAdapter` preserves exact selected targets while reducing the
reviewed 1,800-loaded-anchor resolution from 6,448.00 to 46.94 microseconds.
Raw samples and workload exclusions live in
[Simulation scaling baseline 02](benchmarks/SIMULATION_SCALING_BASELINE_02.md)
and [Loaded Resource Discovery 01](benchmarks/LOADED_RESOURCE_DISCOVERY_01.md).
The authored Jajce watercourse, navigation rebake, amount-derived resource
visuals, and two bounded foliage/resource placement proofs are complete. The
riverbank and forest edge preserve stable finite-resource IDs, separate
decorative density from simulation authority, support discovery beyond the
first 24 m range, and reconstruct sparse/depleted visuals from authoritative
amount. Dunja now proves the first identity-backed animal contract: stable
animal identity, simulation-owned position and hunger, a loaded visual binding,
and the same exact pantry-conserving feed operation for NPC and player.
World-schema v10 restore reconstructs her persistent state without replaying
the transient response. Dunja now also alternates between a stable shelter and
pasture through real loaded navigation. World-schema v11 preserves exact
mid-route position, destination, and schedule through restore or presentation
unload/reload without consuming decision RNG. Zora now proves the bounded
multi-animal contract: her independent stable record and private shelter share
Dunja's pasture, nearest loaded care targeting supports two simultaneous exact
claims, and feeding one goat cannot mutate the other. World-schema v11
preserves both claim pairings without serializing shelter ownership. Do not
generalize animal discovery or introduce herd scheduling, products, breeding,
or active/abstract animal LOD until playtest or measurement exposes a concrete
need.
The remaining simulation-garden target still aims 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 2030 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.
13. Follow the authority order in [the documentation map](README.md); do not
let a focused visual or migration plan silently redefine system ownership.
## Definition of “reusable for the future game”
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.