docs: add current developer feature index
This commit is contained in:
@@ -66,6 +66,8 @@ troubleshooting.
|
||||
|
||||
## Project guide
|
||||
|
||||
- [`docs/DEVELOPER_INDEX.md`](docs/DEVELOPER_INDEX.md) — current developer
|
||||
onboarding index, feature map, extension workflow, and remaining work;
|
||||
- [`AGENTS.md`](AGENTS.md) — development loop, architecture rules, validation,
|
||||
documentation, and Git expectations;
|
||||
- [`docs/PROJECT_CONTEXT.md`](docs/PROJECT_CONTEXT.md) — vision, current
|
||||
|
||||
@@ -5,6 +5,11 @@ Serializable simulation records are authoritative; loaded Godot nodes present
|
||||
that state and contribute active-world facts such as positions and navigation
|
||||
results.
|
||||
|
||||
For onboarding and feature-specific implementation guides, use the
|
||||
[developer index](DEVELOPER_INDEX.md). This file remains the concise ownership
|
||||
and dependency reference; it intentionally does not repeat every field and
|
||||
test case from the focused guides.
|
||||
|
||||
## Emergent content and narrative boundary
|
||||
|
||||
Definitions, authored placements, mutable records, systems, and presentation
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# The Steward — Build-in-Public Visual Slice Plan
|
||||
|
||||
> **Current-status note (2026-08-13):** This document remains the scoped Jajce
|
||||
> visual-production plan. The simulation has since added authored content
|
||||
> packs, shared player/NPC activity commands, generated situations/dialogue,
|
||||
> regional records, and reversible High/Balanced/Low presentation profiles.
|
||||
> Use the [developer index](DEVELOPER_INDEX.md) and
|
||||
> [presentation guide](FEATURE_PRESENTATION_PERFORMANCE.md) for the current
|
||||
> implementation map. The visual plan's phase history is retained for capture
|
||||
> provenance and does not claim that regional gameplay is production-wired.
|
||||
|
||||
## Purpose
|
||||
|
||||
This plan adapts the proposed “Jajce simulation garden” to the repository as it
|
||||
@@ -630,7 +639,9 @@ The adjusted first milestone is complete when:
|
||||
- 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.
|
||||
- The existing simulation remains in one `SimulationManager`; regional records
|
||||
and the caravan proof are additive and have not replaced the local Jajce
|
||||
facade.
|
||||
|
||||
## Definition of “Simulation Garden 01”
|
||||
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
# The Steward developer index
|
||||
|
||||
This is the shortest reliable route into the current codebase. It describes
|
||||
what is implemented today, where the implementation lives, which document owns
|
||||
each contract, and what remains intentionally incomplete. It is written from
|
||||
the Godot 4.7 source and the current headless test/benchmark suite, not from
|
||||
the original prototype plan.
|
||||
|
||||
If a statement here disagrees with code or a focused test, update this index
|
||||
after fixing the code. Do not make this document a second implementation.
|
||||
|
||||
## What the project is
|
||||
|
||||
The Steward is a deterministic, embodied village-simulation prototype set in a
|
||||
Jajce-inspired valley. The player, NPCs, animals, enemies, resources, storage,
|
||||
events, memories, relationships, situations, and commitments use the same
|
||||
authoritative world state. Godot scenes are optional loaded-world adapters:
|
||||
they provide geometry, navigation, visual feedback, and input, but they do not
|
||||
own persistent quantities, travel completion, or quest progress.
|
||||
|
||||
The long-term direction is one regional simulation containing settlements,
|
||||
routes, caravans, named people, aggregate cohorts, and polities. The current
|
||||
repository has the regional records, deterministic scheduler, one exact
|
||||
caravan transfer service, chunked persistence, and a 20-caravan structural
|
||||
benchmark. It does not yet run that regional service as the production
|
||||
`SimulationManager` facade or provide a complete market, settlement-growth, or
|
||||
kingdom gameplay loop. That distinction is important when extending the game.
|
||||
|
||||
## Start here
|
||||
|
||||
| Goal | Read first | Then inspect |
|
||||
| --- | --- | --- |
|
||||
| Understand authority and module ownership | [Architecture overview](ARCHITECTURE_OVERVIEW.md) | `simulation/SimulationManager.gd`, `world/active_world_adapter.gd` |
|
||||
| Add a new item, animal, enemy, resource, storage, action, situation, or dialogue intent | [Authored content and definitions](FEATURE_CONTENT_AND_AUTHORED_DATA.md) | `simulation/definitions/`, `simulation/animals/definitions/`, `world/presentation/catalogs/` |
|
||||
| Add or change a player/NPC interaction | [Commands, targets, and economy](FEATURE_COMMANDS_TARGETS_AND_ECONOMY.md) | `simulation/commands/`, `world/targets/`, `ActiveWorldAdapter`, `SimulationManager` |
|
||||
| Make a world event influence memory, relationships, a situation, or dialogue | [Events through dialogue](FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md) | `simulation/events/`, `simulation/knowledge/`, `simulation/situations/`, `simulation/dialogue/` |
|
||||
| Add caravans, routes, scheduled work, or regional saves | [Regional simulation and persistence](FEATURE_REGIONAL_SIMULATION_AND_PERSISTENCE.md) | `simulation/regional/`, `simulation/state/*StateRecord.gd` |
|
||||
| Add an enemy or animal using an existing behavior | [Entity families](FEATURE_ENTITIES_COMBAT_ANIMALS.md) | `CombatantFactory.gd`, `AnimalFactory.gd`, shared visual roots |
|
||||
| Change rendering or support weaker PCs | [Presentation and performance](FEATURE_PRESENTATION_PERFORMANCE.md) | `world/jajce/jajce_world.gd`, `world/presentation/` |
|
||||
| Change a saved field or migration | [Save schema and migrations](FEATURE_SAVE_SCHEMA_AND_MIGRATIONS.md) | `SimulationStateRecord.gd`, nested state records, `SaveSlotStore.gd` |
|
||||
| Add a regression, benchmark, or run the gate | [Testing and benchmarks](FEATURE_TESTING_AND_BENCHMARKS.md) | `tests/`, `tools/`, `docs/benchmarks/` |
|
||||
|
||||
## Current implementation at a glance
|
||||
|
||||
| Area | Current implementation | Boundary to keep visible |
|
||||
| --- | --- | --- |
|
||||
| Definitions | Transactionally validated `.tres` packs and a sorted `ContentCatalog` | New mechanics still require one explicit reusable handler; data-only combinations are the supported extension surface |
|
||||
| Actions | Definition-backed actions, typed effects, copy-only commands/offers/results, shared activity command service | Do not let UI or a scene mutate authority directly |
|
||||
| Targets | Context-scoped `WorldTargetRegistry` with stable IDs, capabilities, generation handles, and provider lookup | Registry handles are transient; target identity in saves remains primitive and contextual |
|
||||
| Economy | Exact resource, inventory, storage, player-citizen, and animal-care transactions | Village pantry/woodpile are still the production economy; regional markets are not wired |
|
||||
| World facts | `WorldEventRecord`/`WorldEventStore` plus compatibility `EconomicEventRecord`/`SimulationEventLog` | Facts are appended after successful mutation and are never quest-only substitutes |
|
||||
| Memory/social | Bounded knowledge with provenance, one-hop communication, seven relationship dimensions, causal event IDs | Objective history and broader rumours still need retention/rollup policy at regional scale |
|
||||
| Situations/quests | Definition-driven bounded situations, derived progress, journal metadata, commitments and idempotent outcomes | The initial Jajce slice is bounded; it is not a universal objective scripting language |
|
||||
| Dialogue | Deterministic semantic `ConversationService`, authored intent/template resources, Dialogue Manager v3 presenter | Dialogue Manager renders planned turns; it is not an authority or save format |
|
||||
| Entities | Shared definition → instance/state → presentation contracts for resources, animals, enemies, items, storage | New behavior profiles and genuinely new mechanics still need typed code and tests |
|
||||
| Regional kernel | Primitive records, due-job heap, keyed random, analytical updates, caravan proof, chunk/file store | Regional service and 20-caravan trade are currently integration fixtures, not the live Jajce loop |
|
||||
| Presentation | Active-world adapters, context registries, relevance cap of 40, navigation budget of 2/frame, High/Balanced/Low profiles | Hardware frame-time/VRAM evidence is still pending; structural benchmarks are not rendered claims |
|
||||
| Persistence | Local save schema v16 with migrations and scope preflight; regional chunk generations with recovery | No save menu/profile system; regional chunk store is not yet the local `SaveSlotStore` backend |
|
||||
|
||||
## The authority pipeline
|
||||
|
||||
```text
|
||||
player input or NPC decision
|
||||
|
|
||||
v
|
||||
ActionCommand / domain service
|
||||
|
|
||||
v
|
||||
validate actor, target, capability, range, revision, cost, permission
|
||||
|
|
||||
v
|
||||
mutate authoritative records atomically
|
||||
|
|
||||
+--> append WorldEventRecord / EconomicEventRecord
|
||||
| |
|
||||
| +--> knowledge and relationship consequences
|
||||
| +--> SituationSystem and derived journal progress
|
||||
| +--> SocialCommitmentSystem outcomes
|
||||
| +--> semantic ConversationService context
|
||||
|
|
||||
v
|
||||
signals and copied results to presentation
|
||||
```
|
||||
|
||||
The important ordering rule is **mutation first, fact second, projection last**.
|
||||
A situation, journal entry, conversation line, HUD card, or visual cue may
|
||||
explain an event, but it may not manufacture the inventory, damage, enemy,
|
||||
relationship, or reward that the event claims happened.
|
||||
|
||||
## Repository map
|
||||
|
||||
### Authoritative simulation
|
||||
|
||||
- `simulation/SimulationManager.gd` — scene-tree facade and tick boundary;
|
||||
coordinates the current Jajce simulation and exposes player/NPC-facing APIs.
|
||||
- `simulation/SimNPC.gd`, `simulation/SimVillage.gd` — local person and
|
||||
settlement state used by the playable slice.
|
||||
- `simulation/SimulationClock.gd` — fixed-step simulation time, speed, and
|
||||
capped catch-up.
|
||||
- `simulation/actions/` — utility selection, progress, and target resolution.
|
||||
- `simulation/commands/` — command values, typed effects, activity handler,
|
||||
catalog interaction offers, and transactional effect planning.
|
||||
- `simulation/economy/` — exact inventory/storage transfers and routing.
|
||||
- `simulation/animals/` and `simulation/conflict/` — reusable animal and enemy
|
||||
domain systems.
|
||||
- `simulation/events/`, `knowledge/`, `relationships/`, `situations/`, and
|
||||
`dialogue/` — causal history and emergent narrative layers.
|
||||
- `simulation/state/` — versioned primitive records and validation.
|
||||
- `simulation/persistence/` — local quicksave safety.
|
||||
- `simulation/regional/` — regional records, scheduler, caravan proof, chunk
|
||||
codec, and file generations.
|
||||
|
||||
### Loaded world and presentation
|
||||
|
||||
- `world/active_world_adapter.gd` — context identity, target registry, loaded
|
||||
geometry, and spatial query boundary.
|
||||
- `world/targets/` — stable target descriptors, capabilities, and transient
|
||||
generation-checked handles.
|
||||
- `world/resource_nodes/`, `world/storage/`, `world/activity/`, and
|
||||
`world/animals/` — reusable interaction providers bound to simulation state.
|
||||
- `world/creatures/creature_visual.gd` — shared navigation/death visual root;
|
||||
`world/combat/HostileCombatant.gd` specializes it for enemies.
|
||||
- `world/dialogue/` — player dialogue mode and the Dialogue Manager adapter.
|
||||
- `world/presentation/` — cue catalog, relevance selection, and path-request
|
||||
budget.
|
||||
- `world/jajce/` — authored Terrain3D valley, environment, grass, clusters,
|
||||
day/night, and quality profiles.
|
||||
- `world/ui/`, `world/world_view_manager.gd`, and `player/` — presentation and
|
||||
input only; they query copied results/signals from authority.
|
||||
|
||||
### Definitions and authored resources
|
||||
|
||||
`simulation/definitions/` contains action, item, resource, storage, profession,
|
||||
enemy, event, social-consequence, situation, dialogue, and pack resources.
|
||||
`world/presentation/catalogs/` contains visual cue mappings. A `.tres` file
|
||||
must never be treated as a mutable save record; current-build definition values
|
||||
are used when an existing save is loaded.
|
||||
|
||||
## Extension workflow
|
||||
|
||||
1. Decide whether the request is a new combination of existing capabilities
|
||||
and effects or a genuinely new mechanic.
|
||||
2. For a data-only combination, create a typed definition resource, add it to a
|
||||
pack, validate the catalog, and add a focused headless test.
|
||||
3. Give placed instances contextual stable IDs and register them with the
|
||||
active adapter. Do not add a process-global registry or a scene-path lookup.
|
||||
4. For a new mechanic, add one bounded typed handler/strategy, its validation,
|
||||
reason trace, save semantics, and a real consumer test. Do not add a script
|
||||
per item, quest, animal, or enemy.
|
||||
5. If the action changes meaningful state, append an exact world fact after the
|
||||
mutation and connect any knowledge, relationship, situation, or commitment
|
||||
projection to that fact.
|
||||
6. If state changes, update `SimulationStateRecord` and its nested migration,
|
||||
checksum, tamper, and continuation tests before wiring presentation.
|
||||
7. If loaded geometry is involved, prove loaded and abstract execution use the
|
||||
same authority and that unload/reload does not alter the checksum.
|
||||
8. Update the narrow feature guide and this index, then run the changed gate
|
||||
and full gate before committing.
|
||||
|
||||
## Current next work
|
||||
|
||||
The following are deliberately **not** claimed as complete:
|
||||
|
||||
- wire `RegionalCaravanService` into the production regional facade and local
|
||||
save manifest;
|
||||
- run 20 real caravan trades across five settlement economies with atomic
|
||||
cargo/stock ledgers;
|
||||
- replace local unloaded travel freezes with authoritative route-time work;
|
||||
- integrate event retention/rollups/chunked history into one long-horizon save;
|
||||
- add settlement projects, cohort promotion/demotion, offices, diplomacy,
|
||||
armies, campaigns, and aggregate conflict;
|
||||
- add visual relevance streaming to the live world view rather than only the
|
||||
pure policy/benchmark contract;
|
||||
- record weak-PC High/Low gameplay-camera CPU/GPU frame-time, draw-call,
|
||||
memory, and VRAM captures.
|
||||
|
||||
See [the regional contract](REGIONAL_SIMULATION.md), [the roadmap](LEARNING_ROADMAP.md),
|
||||
and [the performance guide](FEATURE_PRESENTATION_PERFORMANCE.md) before
|
||||
starting one of these slices.
|
||||
|
||||
## Documentation authority
|
||||
|
||||
1. Code and focused tests define current behavior.
|
||||
2. [ADR 0001](decisions/0001-simulation-authority-boundary.md) and
|
||||
[ADR 0002](decisions/0002-emergent-world-content-and-narrative.md) define
|
||||
durable architectural decisions.
|
||||
3. [Architecture overview](ARCHITECTURE_OVERVIEW.md) defines ownership and
|
||||
dependency boundaries.
|
||||
4. The focused contracts define their module: [definitions](SIMULATION_DEFINITIONS.md),
|
||||
[state](SIMULATION_STATE_SCHEMA.md), [actions](ACTION_SYSTEM_ARCHITECTURE.md),
|
||||
and [regional simulation](REGIONAL_SIMULATION.md).
|
||||
5. The [learning roadmap](LEARNING_ROADMAP.md) and [build-in-public plan](BUILD_IN_PUBLIC_PLAN.md)
|
||||
describe sequencing and presentation goals; they do not override current
|
||||
code behavior.
|
||||
|
||||
## Verification commands
|
||||
|
||||
```bash
|
||||
./tools/quality.sh --changed
|
||||
./tools/quality.sh
|
||||
git diff --check
|
||||
```
|
||||
|
||||
For a focused test, use the Godot binary configured by the local quality
|
||||
scripts and pass the test script through the repository's isolated profile.
|
||||
The complete test and benchmark map is in
|
||||
[Testing and benchmarks](FEATURE_TESTING_AND_BENCHMARKS.md).
|
||||
+20
-9
@@ -10,6 +10,10 @@ resource_extracted
|
||||
storage_deposited
|
||||
storage_withdrawn
|
||||
item_consumed
|
||||
npc_slept
|
||||
npc_died
|
||||
task_started
|
||||
resource_depleted
|
||||
animal_fed
|
||||
villager_weak
|
||||
home_damaged
|
||||
@@ -19,6 +23,13 @@ raid_started
|
||||
war_resolved
|
||||
war_aborted
|
||||
wolf_hunt
|
||||
activity_completed
|
||||
task_blocked
|
||||
commitment_accepted
|
||||
commitment_fulfilled
|
||||
commitment_broken
|
||||
commitment_released
|
||||
commitment_superseded
|
||||
```
|
||||
|
||||
Each record contains a monotonically increasing event ID, event type,
|
||||
@@ -75,17 +86,17 @@ transfer occurred.
|
||||
|
||||
## Persistence and determinism
|
||||
|
||||
`SimulationStateRecord` schema v11 stores the ordered event stream,
|
||||
`SimulationStateRecord` schema v16 stores the ordered event stream,
|
||||
`next_event_id`, directed relationships that may reference an exact event, and
|
||||
per-NPC known-event references with first-acquisition provenance, plus
|
||||
opportunity records that reference exact trigger/resolution events. Schema v1
|
||||
and v2 saves migrate to an empty stream beginning at ID zero; world schemas
|
||||
v1–v7 migrate to an empty opportunity list, while world schemas v8–v10
|
||||
preserve and normalize opportunity history. World v9 adds an empty animal list
|
||||
during migration; world v10 preserves and upgrades its animal records. Parsing
|
||||
rejects duplicate event IDs, invalid or duplicate knowledge/opportunity
|
||||
references, impossible communicator sources, relationship causes the observer
|
||||
does not know, and next IDs that could collide with restored history.
|
||||
opportunity, situation, journal, commitment, and conversation records that
|
||||
reference exact trigger/resolution/outcome events. Historical world schemas
|
||||
migrate explicitly through nested record versions; current v16 adds non-empty
|
||||
world/location scope and rejects a save whose scope differs from the active
|
||||
adapter before mutating the simulation. Parsing rejects duplicate event IDs,
|
||||
invalid or duplicate knowledge/situation/commitment references, impossible
|
||||
communicator sources, relationship causes the observer does not know, forged
|
||||
activity facts, and next IDs that could collide with restored history.
|
||||
|
||||
Animal-feed facts receive an additional cross-record check: actor is either an
|
||||
existing NPC or the player sentinel, destination is an existing animal, item
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
# Feature slice: commands, targets, and economy
|
||||
|
||||
This slice makes player and NPC interactions converge on one authority path.
|
||||
The main pieces are `ActionCommand`, `ActionOffer`, `ActionResult`,
|
||||
`ActionCommandService`, `CatalogInteractionService`,
|
||||
`ActivityActionCommandService`, `WorldTargetRegistry`, `ActiveWorldAdapter`,
|
||||
`StorageRoutingPolicy`, and `VillageEconomy`.
|
||||
|
||||
## Offer versus command
|
||||
|
||||
An offer is a read-only, copied description of what an actor could attempt.
|
||||
It may contain stable action/target IDs, capability data, copy text, a reason
|
||||
trace, expected state revision, target generation, context identity, and
|
||||
registry-instance identity. It must not contain a `Node`, provider reference,
|
||||
callable, or authoritative result.
|
||||
|
||||
The actor submits an `ActionCommand` with stable actor/action/target IDs,
|
||||
optional item and amount, and an expected state revision. The service rechecks
|
||||
everything at execution time. A valid offer is not permission to execute after
|
||||
the world changes.
|
||||
|
||||
```text
|
||||
query -> copied ActionOffer
|
||||
|
|
||||
v
|
||||
player/NPC command
|
||||
|
|
||||
v
|
||||
revalidate revision + registry instance + generation + provider
|
||||
|
|
||||
v
|
||||
revalidate actor life + capability + range + target + reservation + cost
|
||||
|
|
||||
v
|
||||
atomic mutation -> exact world fact -> copied ActionResult
|
||||
```
|
||||
|
||||
## Context-scoped targets
|
||||
|
||||
`ActiveWorldAdapter` has explicit `world_id`, `location_id`, and `context_id`
|
||||
identity. It owns one `WorldTargetRegistry` for that context. Resource,
|
||||
storage, activity, and animal providers register a `WorldTargetDescriptor`
|
||||
containing a canonical target ID, target kind, capability descriptors, and a
|
||||
transient provider binding.
|
||||
|
||||
The registry provides:
|
||||
|
||||
- O(1) canonical ID lookup;
|
||||
- cross-kind duplicate rejection within a context;
|
||||
- deterministic sorted IDs and capability filtering;
|
||||
- generation-checked transient `WorldTargetHandle` values;
|
||||
- provider registration/unregistration and stale-provider pruning.
|
||||
|
||||
The target ID and contextual scope are the authority. A handle is only a
|
||||
short-lived geometry/provider reference. Rebuilding a context restarts local
|
||||
generations, so player results also carry a registry-instance token to prevent
|
||||
ABA execution against a replacement registry.
|
||||
|
||||
`LoadedResourceSpatialIndex` accelerates finite resource queries by action and
|
||||
horizontal cell. It is disposable presentation state; amounts, reservations,
|
||||
yield, risk, and discovery priority remain in simulation records.
|
||||
|
||||
## The current shared handler
|
||||
|
||||
`ActivityActionCommandService` is the first production shared command handler.
|
||||
Patrol and study are authored `activity_metric_delta` actions. The handler:
|
||||
|
||||
1. validates the actor and expected revision;
|
||||
2. validates the action's typed handler/effect contract;
|
||||
3. validates activity target kind, live provider, registry scope/instance,
|
||||
capability, range, capacity, and task authorization;
|
||||
4. preflights and withdraws any authored completion cost through
|
||||
`VillageEconomy` and `StorageRoutingPolicy`;
|
||||
5. applies the bounded safety or knowledge metric delta;
|
||||
6. appends one scoped `activity_completed` fact;
|
||||
7. returns exact event IDs, final revision, and reason trace.
|
||||
|
||||
If the cost is unavailable, no effect is applied and one structured
|
||||
`task_blocked` fact records the action, source storage, item, and required
|
||||
amount. A capped metric does not consume a cost or emit a false delta. The
|
||||
primary event keeps the command revision; synchronous situation/commitment
|
||||
consequences may append a causal suffix, and the result reports the final
|
||||
revision.
|
||||
|
||||
NPCs must use their actual current action, target, task state, completion flag,
|
||||
alive state, and context scope. An idle, dead, downed, wrong-target, or
|
||||
wrong-world direct command fails without mutation. Players use the dedicated
|
||||
player boundary, which requires all stale-offer tokens rather than accepting
|
||||
sentinel defaults. Both paths share definition validation, economy, event, and
|
||||
state checks.
|
||||
|
||||
## Typed effects and transactional planning
|
||||
|
||||
`ActionEffectPlanner` turns authored `ActionEffect` resources into an explicit
|
||||
`ActionEffectPlan` with stable operation IDs, authored order, parameters, and a
|
||||
reason trace. It supports the bounded typed effects currently registered:
|
||||
metric/need changes, exact inventory/storage/cargo transfers, damage/healing,
|
||||
relationship changes, scheduling ordinary work, and site-condition changes.
|
||||
|
||||
`TransactionalActionEffectCommitter` is the extension seam for a mechanic that
|
||||
needs more than the built-in activity handler. A committer must apply one whole
|
||||
plan atomically, return unique event IDs on success, or return a rollback-safe
|
||||
failure with no event IDs. Plans reject unknown kinds, duplicate/reordered
|
||||
operations, non-primitive values, non-finite numbers, same-role transfers, and
|
||||
empty effect sets.
|
||||
|
||||
## Economy and routing
|
||||
|
||||
`VillageEconomy` owns exact storage/NPC/player inventory mutations. The
|
||||
pantry, woodpile, apothecary, resource yields, animal feeding, player carry
|
||||
loop, and action costs use the same transaction boundary. `village.food` and
|
||||
`village.wood` are synchronized aggregate views, not second mutation paths.
|
||||
|
||||
`StorageRoutingPolicy` selects compatible storage by accepted item ID/tag,
|
||||
priority, capacity, settlement scope, and stable target ID. The herb →
|
||||
apothecary route proves that routing is no longer a food/wood switch. The
|
||||
production Jajce economy still has one village settlement; regional stockpiles
|
||||
and markets are future work.
|
||||
|
||||
## Adding a new interaction
|
||||
|
||||
1. Add or reuse an `ActionDefinition` with target/capability/handler/effect
|
||||
fields.
|
||||
2. Add target capability data to the provider definition or scene provider.
|
||||
3. Register the provider through `ActiveWorldAdapter`.
|
||||
4. Add an offer query and a command service/handler only if the existing typed
|
||||
handler cannot express the mechanic.
|
||||
5. Revalidate all authority at command time.
|
||||
6. Mutate records, append the exact event, and test both player and NPC paths.
|
||||
7. Add loaded/abstract and stale-offer regressions where applicable.
|
||||
|
||||
Do not put persistent amounts on `StorageNode`, use abstract Vector3 fallback
|
||||
targets, or let the HUD call `SimulationManager` mutation methods directly.
|
||||
|
||||
## Reference tests and contracts
|
||||
|
||||
- `tests/world_target_registry_test.gd`
|
||||
- `tests/context_scoped_world_targets_test.gd`
|
||||
- `tests/unit/test_catalog_interaction_service.gd`
|
||||
- `tests/unit/test_activity_action_command_service.gd`
|
||||
- `tests/unit/test_activity_content_catalog_contract.gd`
|
||||
- `tests/unit/test_action_effect_planning.gd`
|
||||
- `tests/resource_node_player_parity_test.gd`
|
||||
- `tests/food_storage_loop_test.gd`
|
||||
- `tests/animal_food_delivery_test.gd`
|
||||
|
||||
For the complete action lifecycle and active-position rules, read
|
||||
[Action System Architecture](ACTION_SYSTEM_ARCHITECTURE.md). For definition
|
||||
fields, read [Simulation Definitions](SIMULATION_DEFINITIONS.md).
|
||||
@@ -0,0 +1,139 @@
|
||||
# Feature slice: authored content and presentation data
|
||||
|
||||
This slice is the no-code extension boundary for content that reuses existing
|
||||
behavior. It is implemented by `SimulationContentPack`, `ContentCatalog`, the
|
||||
typed definition resources under `simulation/definitions/`, and the separate
|
||||
`PresentationCatalog` under `world/presentation/`.
|
||||
|
||||
## The four layers
|
||||
|
||||
| Layer | Lives in | Contains | Never contains |
|
||||
| --- | --- | --- | --- |
|
||||
| Definition | `.tres` resources and typed `Resource` classes | immutable IDs, balance, capabilities, effects, handlers, cue IDs | mutable amount, owner, reservation, node references |
|
||||
| Instance descriptor | placement/provider nodes and regional records | stable runtime ID, context/location, authored overrides | script/callable/`NodePath` authority |
|
||||
| State record | `simulation/state/` | primitive mutable values, IDs, history/event references | scene assets or resource paths |
|
||||
| Presentation binding | `world/presentation/` and scene providers | cue-to-scene/material/icon/animation metadata | simulation quantities or quest authority |
|
||||
|
||||
Definitions are current-build balance. A save stores the definition ID and
|
||||
mutable instance state; it does not freeze the `.tres` path or copy the full
|
||||
resource. Renaming an ID requires an alias/migration, not a silent replacement.
|
||||
|
||||
## Content packs and catalog publication
|
||||
|
||||
`SimulationContentPack` groups typed arrays for:
|
||||
|
||||
- actions, professions, capability tags;
|
||||
- items, resources, storages;
|
||||
- enemies and animals;
|
||||
- situations, dialogue intents, and template catalogs;
|
||||
- event types and social consequences;
|
||||
- required pack IDs and required handler IDs.
|
||||
|
||||
`ContentCatalog.create_core()` loads `simulation/definitions/packs/core.tres`.
|
||||
`ContentCatalog.rebuild()` sorts packs and every definition by stable ID,
|
||||
collects references into temporary dictionaries, validates the complete graph,
|
||||
and publishes only if there are no errors. A failed rebuild clears the
|
||||
published catalog; it never exposes a partially valid pack.
|
||||
|
||||
Validation currently rejects duplicate IDs, unknown references, missing
|
||||
handlers, unsupported situation predicates, missing presentation cues, invalid
|
||||
categories, invalid event/consequence references, duplicate template keys, and
|
||||
malformed typed action contracts. `get_authoring_report()` is the deterministic
|
||||
machine-readable inventory used by tests and tooling.
|
||||
|
||||
The first built-in handler contract is `activity_metric_delta`. It requires an
|
||||
activity target, exactly one positive safety/knowledge metric effect, typed
|
||||
optional `player_multiplier`/`npc_productivity` values, a known completion
|
||||
event, and a routable completion-cost item. This closes the gap where an
|
||||
authored action could publish but produce a fact that the validator could not
|
||||
restore.
|
||||
|
||||
## Adding data-only content
|
||||
|
||||
### New item and route
|
||||
|
||||
1. Add an `ItemDefinition` with a category and stable `item_id`.
|
||||
2. Add a `StorageDefinition` that accepts the item ID or one of its tags, or
|
||||
update an existing typed storage route.
|
||||
3. Add both to a pack and make sure the `StorageRoutingPolicy` can rank a
|
||||
compatible storage.
|
||||
4. Add a `PresentationCueDefinition` only if the item needs a visual.
|
||||
5. Add a conservation/routing test. The herb/apothecary route is the reference
|
||||
example; food/pantry and wood/woodpile preserve legacy coverage.
|
||||
|
||||
### New resource
|
||||
|
||||
1. Add a `ResourceDefinition` with yielded item, gather action, capacity/yield,
|
||||
regrowth, access policy, capability tags, and a cue ID.
|
||||
2. Place a `ResourceNode` with a unique contextual ID and meaningful
|
||||
`safety_risk`, `comfort_distance`, `discovery_priority`, and interaction
|
||||
point.
|
||||
3. Register it through the nearest `ActiveWorldAdapter`; do not add a global
|
||||
array or manager branch.
|
||||
4. Test player/NPC selection, depletion, reservation, unload/rebind, and
|
||||
save/restore authority.
|
||||
|
||||
### New animal
|
||||
|
||||
1. Add an `AnimalDefinition` with behavior/routine/feed capability IDs and a
|
||||
stable presentation cue.
|
||||
2. Add it to `core_animals.tres` or an explicit content pack.
|
||||
3. Spawn through `AnimalFactory` and persist its `animal_definition_id` in
|
||||
`AnimalStateRecord`.
|
||||
4. Reuse `AnimalNode`, `AnimalRoutineSite`, and the grazer visual where the
|
||||
existing contract fits. The goat/sheep pair proves this path.
|
||||
|
||||
### New enemy
|
||||
|
||||
1. Add an `EnemyDefinition` with `behavior_profile_id`, faction, item/weapon
|
||||
references, hostile flag, and cue ID.
|
||||
2. Register it in a pack. `CombatantFactory` owns deterministic per-prefix ID
|
||||
allocation and restore collision checks.
|
||||
3. Spawn through `ConflictSystem.spawn_enemy()`; keep `spawn_wolf()` only as a
|
||||
compatibility wrapper.
|
||||
4. Reuse a behavior profile when possible. `enemy_boar` deliberately reuses
|
||||
`wolf_hunt`; no combat switch was added.
|
||||
|
||||
### New situation or dialogue content
|
||||
|
||||
See [Events through dialogue](FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md).
|
||||
The authored resources must reference existing predicate IDs, event types,
|
||||
intent IDs, template catalogs, and action/item definitions. A definition may
|
||||
describe an unresolved condition, but it cannot create substitute world facts.
|
||||
|
||||
## Presentation catalogs
|
||||
|
||||
`PresentationCatalog` accepts `PresentationCatalogResource` entries whose
|
||||
`PresentationCueDefinition` contains stable cue metadata and optional asset
|
||||
paths. It validates metadata headlessly and loads scenes only at the world
|
||||
boundary. `AnimalDefinition`, enemy definitions, resource definitions, and
|
||||
other simulation content carry only a cue ID. This keeps headless tests and
|
||||
saves independent of imported meshes/materials.
|
||||
|
||||
Presentation catalogs may be absent in a headless `AnimalFactory` or regional
|
||||
simulation. Missing optional presentation is an explicit no-visual result, not
|
||||
a reason to fail simulation state loading.
|
||||
|
||||
## What requires code
|
||||
|
||||
Data-only authoring is guaranteed only when the new combination uses existing
|
||||
typed predicates, capabilities, effects, handlers, behavior profiles, and cue
|
||||
contracts. Add one reusable typed handler when a new mechanic needs a new
|
||||
authority rule. The handler must provide validation, a reason trace, atomic
|
||||
mutation semantics, world facts, save fields/migration if needed, and a real
|
||||
consumer test. Do not solve a new mechanic with a reflection DSL or a script
|
||||
per content asset.
|
||||
|
||||
## Reference tests
|
||||
|
||||
- `tests/content_catalog_test.gd`
|
||||
- `tests/simulation_definitions_test.gd`
|
||||
- `tests/unit/test_authored_situation_dialogue_content.gd`
|
||||
- `tests/unit/test_activity_content_catalog_contract.gd`
|
||||
- `tests/unit/test_content_routing_foundations.gd`
|
||||
- `tests/animal_definition_contract_test.gd`
|
||||
- `tests/unit/test_combatant_factory.gd`
|
||||
- `tests/unit/test_presentation_catalog.gd`
|
||||
|
||||
The [simulation definitions contract](SIMULATION_DEFINITIONS.md) is the
|
||||
authoritative field-level reference; this guide explains the extension path.
|
||||
@@ -0,0 +1,84 @@
|
||||
# Feature slice: reusable entity families
|
||||
|
||||
Resources, animals, enemies, items, and storage follow a common extension
|
||||
pattern. A definition describes behavior; a state record owns mutable facts; a
|
||||
factory/system creates or advances the instance; a presentation binding uses a
|
||||
stable cue ID.
|
||||
|
||||
## Resources and storage
|
||||
|
||||
`ResourceDefinition` describes yielded item, gather action, capacity/yield,
|
||||
regrowth, access policy, capability tags, and presentation cue. A placed
|
||||
`ResourceNode` binds its unique ID to `ResourceStateRecord`; amount,
|
||||
reservation, enabled state, risk, comfort, priority, and regrowth survive scene
|
||||
unload. `LoadedResourceSpatialIndex` only accelerates loaded anchor queries.
|
||||
|
||||
`StorageDefinition` describes accepted items/tags, capacity, policy priority,
|
||||
settlement scope, actions, and cue. `StorageNode` supplies interaction geometry;
|
||||
`StorageStateRecord` owns quantities. The current authored storages are pantry,
|
||||
woodpile, and apothecary.
|
||||
|
||||
## Animals
|
||||
|
||||
`AnimalDefinition` owns stable definition ID, species, feed capability,
|
||||
behavior/routine profile, and presentation cue. `AnimalStateRecord` v3 stores
|
||||
the mutable animal ID, definition ID, position, hunger, routine/travel target,
|
||||
reservation, and feed history. `AnimalFactory` creates/restores by definition;
|
||||
`AnimalCareSystem` advances needs, routines, claims, and exact feeding.
|
||||
|
||||
`AnimalNode` binds a loaded provider to the saved state and follows an
|
||||
authoritative destination via navigation. `AnimalRoutineSite` handles private
|
||||
resident shelters versus shared species context. The goat and sheep resources
|
||||
prove two definitions can reuse the same grazer root without Dunja-specific
|
||||
simulation branches.
|
||||
|
||||
## Enemies and combatants
|
||||
|
||||
`EnemyDefinition` carries enemy ID, behavior profile, faction, item/weapon
|
||||
references, hostile flag, and cue. `CombatantFactory` owns per-prefix stable ID
|
||||
allocation and rebuilds occupied IDs after restore. `CombatantStateRecord` v2
|
||||
persists `enemy_definition_id`; legacy hostile kinds migrate to current raider
|
||||
or wolf definitions.
|
||||
|
||||
`ConflictSystem` owns authoritative health, weapon readiness, factions,
|
||||
hostility, raids, war motivation, damage, death, and conflict facts. It creates
|
||||
combatants through the factory and exposes generic `spawn_enemy()` while keeping
|
||||
compatibility wrappers for old wolf/raid callers. `HostileCombatant` is a
|
||||
presentation specialization of `CreatureVisual`; it must not become the owner
|
||||
of health or death authority.
|
||||
|
||||
The boar definition deliberately reuses `wolf_hunt` behavior. A new enemy that
|
||||
needs a new decision pattern adds one bounded behavior strategy plus tests; it
|
||||
does not add a switch in the manager or a duplicate combat system.
|
||||
|
||||
## Shared visual contract
|
||||
|
||||
`CreatureVisual` follows a simulation-owned target position, retargets only
|
||||
when needed, rate-limits failed navigation retries, reports position/arrival,
|
||||
and plays death presentation. NPC, animal, and hostile visuals use this
|
||||
boundary. A visual may report local blockage, but it may not decide that
|
||||
simulation travel completed or mutate combat/resource state.
|
||||
|
||||
## Adding an entity safely
|
||||
|
||||
1. Identify whether an existing definition/profile/root already expresses the
|
||||
behavior.
|
||||
2. Add the definition and presentation cue, then register it in a pack/catalog.
|
||||
3. Add the mutable definition ID to the nested state record if it is not
|
||||
already present, including a legacy migration.
|
||||
4. Route creation/restoration through the factory/system and stable allocator.
|
||||
5. Bind the presentation at the world boundary and test unload/reload.
|
||||
6. Prove a third data-only consumer before generalizing a bespoke handler.
|
||||
|
||||
## Reference tests
|
||||
|
||||
- `tests/animal_definition_contract_test.gd`
|
||||
- `tests/animal_feeding_vertical_slice_test.gd`
|
||||
- `tests/animal_routine_vertical_slice_test.gd`
|
||||
- `tests/animal_pair_vertical_slice_test.gd`
|
||||
- `tests/unit/test_combatant_factory.gd`
|
||||
- `tests/combat_patterns_test.gd`
|
||||
- `tests/conflict_war_system_test.gd`
|
||||
- `tests/creature_visual_path_retry_test.gd`
|
||||
- `tests/resource_regrowth_test.gd`
|
||||
- `tests/jajce_resource_presentation_state_test.gd`
|
||||
@@ -0,0 +1,173 @@
|
||||
# Feature slice: events, memory, situations, quests, and dialogue
|
||||
|
||||
This is the emergent narrative pipeline. It turns real world mutations into
|
||||
evidence, social meaning, unresolved situations, commitments, and semantic
|
||||
conversation options without creating a parallel scripted world.
|
||||
|
||||
## One causal chain
|
||||
|
||||
```text
|
||||
authoritative mutation
|
||||
-> WorldEventRecord / EconomicEventRecord
|
||||
-> indexed WorldEventStore + compatibility SimulationEventLog
|
||||
-> performed/witnessed knowledge with provenance
|
||||
-> relationship dimensions with exact causal event IDs
|
||||
-> SituationSystem evaluates unresolved predicates
|
||||
-> QuestJournalSystem exposes discovery/tracking metadata
|
||||
-> SocialCommitmentSystem records promises and outcomes
|
||||
-> ConversationService plans semantic intents/topics/options
|
||||
-> Dialogue Manager presenter renders one derived turn
|
||||
```
|
||||
|
||||
The event is the shared join key. A quest, journal entry, relationship, or
|
||||
dialogue line may reference it, but none of those layers may invent an item,
|
||||
resource, damage result, enemy, or reward.
|
||||
|
||||
## World facts
|
||||
|
||||
`WorldEntityRef` identifies an actor/participant by typed stable ID.
|
||||
`SpatialAddress` identifies `(world_id, location_id, local_position)` and keeps
|
||||
coincident local coordinates from crossing contexts. `WorldEventRecord` stores
|
||||
event ID/type/tick, participants, optional location, and JSON-safe payload.
|
||||
`WorldEventStore` provides O(1) ID lookup plus deterministic indexes by type,
|
||||
participant, location, exact tick, and tick range.
|
||||
|
||||
`SimulationEventLog` remains the local Jajce compatibility façade. It records
|
||||
economic and activity facts, enforces the configured world/location scope, and
|
||||
refuses to reinterpret retained events under a different active context.
|
||||
`ActivityEventValidator` validates definition-backed success and blocked
|
||||
facts, including legacy markers. Older unstructured blocked facts remain
|
||||
loadable only with explicit migration provenance and cannot become new
|
||||
knowable evidence.
|
||||
|
||||
## Knowledge and relationships
|
||||
|
||||
`EventKnowledgeSystem` stores a bounded `(knower, event)` record, not copied
|
||||
prose. Each memory carries acquisition method, source actor, hop count,
|
||||
confidence, salience, pinning, and acquisition tick. Direct actor/witness
|
||||
observation happens when the event is recorded; restore never recomputes old
|
||||
witnesses from current positions. Communication is one hop from a performed or
|
||||
witnessed fact, and the player is a valid knower/source sentinel.
|
||||
|
||||
Ordinary recent memories are bounded to three per knower; pinned causal facts
|
||||
and facts referenced by situations/commitments are protected. The retention
|
||||
system changes memory references only; it never deletes objective event facts.
|
||||
|
||||
`RelationshipSystem` stores sparse directed edges. The seven dimensions are
|
||||
familiarity, trust, affection, respect, fear, obligation, and hostility. Each
|
||||
non-neutral dimension can retain its exact causal event ID. Consequences are
|
||||
bounded and replay-safe: for example, food aid can increase a hungry familiar
|
||||
villager's trust toward the actor, while commitment lifecycle consequences
|
||||
adjust obligation/trust/hostility by commitment and outcome identity.
|
||||
|
||||
## Situations and journal entries
|
||||
|
||||
`SituationDefinition` declares triggering predicates, interested-party and
|
||||
participant context, dedupe fields, severity/priority, alternatives, valid
|
||||
resolution patterns, expiry/invalidation rules, topics, and commitment terms.
|
||||
`SituationSystem` evaluates definitions in deterministic order, caps the
|
||||
initial Jajce slice at three active situations, deduplicates by configured
|
||||
context, and stores only a `SituationStateRecord` with exact trigger and
|
||||
resolution event IDs. Progress is derived live from current state and ordinary
|
||||
events.
|
||||
|
||||
`QuestJournalSystem` stores `QuestJournalEntryStateRecord`: situation ID,
|
||||
discovery tick, selected alternative, tracking preference, and close/archive
|
||||
state. It never copies objectives or progress. The journal remains empty until
|
||||
the player acquires knowledge of the situation through an ordinary path.
|
||||
|
||||
The current authored pantry shortage is in
|
||||
`simulation/situations/resources/pantry_shortage.tres`. Four legacy local
|
||||
opportunity types are retained as a compatibility family in
|
||||
`VillageOpportunitySystem`; the generic situation system is the direction for
|
||||
new content. Roof repair remains disabled until authoritative home-condition
|
||||
state exists.
|
||||
|
||||
## Commitments
|
||||
|
||||
`SocialCommitmentSystem` creates a `CommitmentStateRecord` when a social promise
|
||||
is accepted. It stores debtor/creditor refs, situation, terms, deadline, status,
|
||||
and exact acceptance/outcome event IDs. Acceptance does not reserve stock or
|
||||
prevent another actor from resolving the situation.
|
||||
|
||||
`CommitmentLifecycleService` records accepted, fulfilled, broken, released, and
|
||||
superseded facts and applies relationship consequences idempotently. A matching
|
||||
outcome performed by the debtor fulfills; an outcome performed by another actor
|
||||
supersedes without penalty. A still-achievable deadline reached at or after its
|
||||
due tick breaks the promise. Release and external impossibility are explicit
|
||||
outcomes. Untracking a journal entry is not cancellation.
|
||||
|
||||
## Deterministic conversations
|
||||
|
||||
`ConversationService` owns transient conversation records and semantic turns:
|
||||
|
||||
- `begin(speaker, listener, context)` validates typed participants and context;
|
||||
- `get_turn(conversation_id)` returns a copied current turn;
|
||||
- `select_option(conversation_id, option_id, expected_revision)` revalidates
|
||||
the revision and recomputes the next turn/action;
|
||||
- `end()` or `invalidate()` closes the transient session.
|
||||
|
||||
The planner reads current relationship dimensions/causes, knowledge, performed
|
||||
and witnessed history, task/need/profession/role, known situations,
|
||||
commitments, and retained conversation acts. Intent definitions provide
|
||||
preconditions, deterministic scoring, response intents, cooldowns, and optional
|
||||
authoritative actions. Current Jajce intents include greeting, work/wellbeing,
|
||||
what happened, sharing a fact, describing a need, offering help, commitment
|
||||
accept/decline/renegotiation, progress, thanks/reproach, supersession, and
|
||||
goodbye.
|
||||
|
||||
Only `ConversationActStateRecord` is persisted: typed speaker/listener refs,
|
||||
intent ID, topic IDs, tick, and a bounded history. Conversation IDs, revision,
|
||||
options, rendered text, and balloon state are transient.
|
||||
|
||||
## Dialogue Manager boundary
|
||||
|
||||
The project vendors Dialogue Manager v3.10.4 under `addons/dialogue_manager`
|
||||
with provenance/checksum and MIT license in `addons/dialogue_manager/UPSTREAM.md`.
|
||||
`DialogueManagerConversationPresenter` receives one planned `ConversationTurn`,
|
||||
selects a stable template variant, escapes dynamic names/topics, and creates an
|
||||
ephemeral resource. It does not execute game mutations, conditions, or
|
||||
authority shortcuts. Controlled option tags map back to stable option IDs and
|
||||
the presented revision.
|
||||
|
||||
`DialogueModeController` owns the loaded player mode: nearest-NPC Talk has
|
||||
priority, movement/combat/ordinary interaction lock while open, simulation
|
||||
speed is normalized to 1×, stale option selections refresh safely, and the
|
||||
mode closes if the speaker dies, unloads, or leaves range. The fake presenter
|
||||
tests keep domain tests renderer-independent; parser and mapping tests cover
|
||||
the vendored plugin.
|
||||
|
||||
## Vertical slice and extension recipe
|
||||
|
||||
The complete Jajce proof is in `tests/emergent_jajce_slice_test.gd` and
|
||||
`tests/conversation_domain_test.gd`:
|
||||
|
||||
1. exact pantry shortage evidence opens a situation;
|
||||
2. an NPC knows it while the player does not;
|
||||
3. speaking transfers knowledge and discovers the journal entry;
|
||||
4. generated options reflect hunger, relationship, evidence, and need;
|
||||
5. accepting creates a commitment without reserving stock;
|
||||
6. ordinary food gather/deposit resolves the real shortage;
|
||||
7. the commitment fulfills or, in variants, breaks/supersedes;
|
||||
8. later conversation references the actual outcome;
|
||||
9. save/reload preserves semantic history and deterministic options.
|
||||
|
||||
To add a new emergent story, author an event type and situation definition,
|
||||
ensure the authoritative action emits the event, add any social consequence or
|
||||
dialogue intent/template, and test the complete causal chain. Do not begin with
|
||||
a quest-only enemy/item or a dialogue graph that mutates state behind the
|
||||
simulation.
|
||||
|
||||
## Reference tests and deeper contracts
|
||||
|
||||
- `tests/unit/test_world_event_store.gd`
|
||||
- `tests/unit/test_social_foundations.gd`
|
||||
- `tests/unit/test_situation_system.gd`
|
||||
- `tests/unit/test_commitment_lifecycle_service.gd`
|
||||
- `tests/conversation_domain_test.gd`
|
||||
- `tests/dialogue_manager_conversation_presenter_test.gd`
|
||||
- `tests/dialogue_mode_controller_test.gd`
|
||||
- `tests/emergent_jajce_slice_test.gd`
|
||||
- [Economic event stream](ECONOMIC_EVENTS.md)
|
||||
- [Simulation state schema](SIMULATION_STATE_SCHEMA.md)
|
||||
- [ADR 0002](decisions/0002-emergent-world-content-and-narrative.md)
|
||||
@@ -0,0 +1,101 @@
|
||||
# Feature slice: presentation, relevance, and weak-PC performance
|
||||
|
||||
Presentation is deliberately replaceable and bounded. The simulation can run
|
||||
headless; loaded scenes provide geometry, navigation, animation, cues, and
|
||||
input. This guide records the current performance controls and the evidence we
|
||||
do and do not have.
|
||||
|
||||
## Loaded-world boundary
|
||||
|
||||
`ActiveWorldAdapter` owns a context identity `(world_id, location_id,
|
||||
context_id)`, a `WorldTargetRegistry`, loaded resource spatial index, and
|
||||
provider handles for resource/storage/activity/animal nodes. It is the only
|
||||
place where a simulation target is paired with loaded geometry. Multiple
|
||||
contexts must use separate ancestor containers; duplicate stable IDs are valid
|
||||
only when they belong to different explicit contexts.
|
||||
|
||||
`WorldViewManager` owns active NPC visual instances and forwards target/arrival/
|
||||
navigation callbacks. `NpcVisual`, `CreatureVisual`, and `AnimalNode` follow
|
||||
authoritative positions. They do not own elapsed travel or saved quantities.
|
||||
|
||||
## Relevance and navigation budgets
|
||||
|
||||
`PresentationRelevancePolicy.select_detailed_visuals()` rejects foreign world,
|
||||
context, or location candidates before ranking and returns at most 40 detailed
|
||||
visuals. Explicit pins include named/important people, player-affecting
|
||||
threats, situation/commitment participants, leaders, and unique owners. If
|
||||
mandatory pins exceed the cap, the policy fails closed instead of silently
|
||||
dropping identities. Decisions include score, distance, pin reasons, and
|
||||
rejection traces.
|
||||
|
||||
`PresentationNavRequestBudget` admits at most two new navigation requests per
|
||||
frame. It exposes pending/in-flight IDs and deterministic priority order. The
|
||||
budget is a pure policy contract today; wiring it into every production visual
|
||||
spawn is a next integration.
|
||||
|
||||
## Jajce quality profiles
|
||||
|
||||
`JajceWorld` owns reversible High, Balanced, and Low presentation profiles with
|
||||
instance-local mutable environment/grass resources and viewport-scale ownership.
|
||||
|
||||
| Profile | 3D scale | Shadow distance | Volumetric/glow | Grass |
|
||||
| --- | ---: | ---: | --- | --- |
|
||||
| High | authored | authored (currently 180 m) | authored when renderer supports it | authored density/interactors |
|
||||
| Balanced (default) | 0.85 cap | 120 m cap | authored ordinary lookdev; unsupported volumetric disabled | reduced spacing/interactors/update rate |
|
||||
| Low | 0.70 cap | 80 m, orthogonal | volumetric/glow/adjustment disabled; ordinary fog retained | hidden/stopped, emitters off, shader interactors zero |
|
||||
|
||||
UI remains at native resolution. High/Low switches restore captured authored
|
||||
values; viewport scale restoration is guarded by the current quality owner so a
|
||||
second world cannot clobber the active owner. Compatibility/mobile feature
|
||||
selection never forces unsupported volumetric fog on.
|
||||
|
||||
## Runtime hot paths already bounded
|
||||
|
||||
- Player interaction and villager inspection probes are throttled/event-driven;
|
||||
they no longer rebuild all candidate data every rendered frame.
|
||||
- `LoadedResourceSpatialIndex` bounds finite-resource discovery.
|
||||
- `SimulationPopulationView` gives stable-ID all/living/starving indexes once
|
||||
per tick.
|
||||
- `WorldTargetRegistry` gives O(1) target lookup and deterministic iteration.
|
||||
- Creature path failures retain the failed target and use bounded backoff.
|
||||
- Hostile hit flashes are health-change driven, not position-change driven.
|
||||
- Day/night, status, time dial, storage/debug labels, and grass updates run at
|
||||
human-readable rates or only on state changes.
|
||||
- Regional scheduled work uses a due-job heap rather than a permanent scan.
|
||||
|
||||
## What the benchmarks prove
|
||||
|
||||
- Simulation baseline 03: 600 full-fidelity data-only NPC/combatant records at
|
||||
about 90.6 ticks/s on the reviewed Apple M1 Max capture, with matching
|
||||
checksums across samples.
|
||||
- Loaded Resource Discovery 01: indexed 1,800-anchor queries preserve exact
|
||||
selection checksums while reducing resolution work dramatically.
|
||||
- Regional scale baseline 01: five settlements, 20 caravans, 2,000 named
|
||||
people, 50,000 aggregate residents, 2,025 jobs, budget/checksum parity.
|
||||
|
||||
These are headless/structural measurements. They do **not** prove 600 rendered
|
||||
visuals, a 30-day regional economy, or weak-PC GPU frame time.
|
||||
|
||||
## Remaining evidence gap
|
||||
|
||||
The project still needs a recorded reference weak-PC active-world workload at a
|
||||
fixed gameplay camera, including High and Low p50/p95/p99 CPU/GPU frame time,
|
||||
draw calls/primitives, memory/VRAM, active detailed visuals, and navigation
|
||||
queue depth. The CI gate should keep structural profile assertions and the
|
||||
two-request policy; hardware measurements belong in a reviewed benchmark
|
||||
ledger, not brittle cross-machine CI thresholds.
|
||||
|
||||
## Performance extension rules
|
||||
|
||||
1. Measure a representative workload before optimizing.
|
||||
2. Keep simulation and presentation results checksum-identical across loaded,
|
||||
unloaded, and load/unload runs.
|
||||
3. Add indexes, dirty sets, analytical updates, or scheduled jobs before adding
|
||||
more per-frame scans.
|
||||
4. Keep allocations out of render-frame probes and avoid sorting when a stable
|
||||
bounded comparison is sufficient.
|
||||
5. Any new visual must declare relevance/pin behavior and obey the navigation
|
||||
request budget.
|
||||
|
||||
See [the benchmark ledger](benchmarks/README.md), [regional contract](REGIONAL_SIMULATION.md),
|
||||
and [the build-in-public visual plan](BUILD_IN_PUBLIC_PLAN.md).
|
||||
@@ -0,0 +1,117 @@
|
||||
# Feature slice: regional simulation and persistence
|
||||
|
||||
The regional package is the scale foundation for one authority spanning
|
||||
settlements, routes, caravans, named people, aggregate cohorts, and polities.
|
||||
It is intentionally additive: the current Jajce `SimulationManager` remains
|
||||
the playable local facade while the regional contracts prove deterministic
|
||||
unloaded work and conservation in isolation.
|
||||
|
||||
## Regional record model
|
||||
|
||||
`RegionalWorldState` is a primitive-only, versioned aggregate with deterministic
|
||||
indexes for:
|
||||
|
||||
- `LocationStateRecord` — world/location identity, type, address, and history;
|
||||
- `SettlementStateRecord` — location/polity, tier, founding group, stockpile;
|
||||
- `RouteStateRecord` — endpoints, travel ticks, direction, history;
|
||||
- `MobileGroupStateRecord` — caravan/army identity, membership, route state,
|
||||
cargo ledger, capacity, arrival/departure ticks, and cargo event cursor;
|
||||
- `PersonStateRecord` — globally unique named people and memberships;
|
||||
- `PopulationCohortRecord` — conserved aggregate residents;
|
||||
- `PolityStateRecord` and `DiplomaticRelationRecord` — sparse regional politics.
|
||||
|
||||
Membership is explicit and validated: a person is at one location or in one
|
||||
mobile group, routes connect existing locations, groups reference existing
|
||||
routes/members, and IDs are globally unique and append-only. Records contain
|
||||
stable IDs and primitive values only; no scene, `NodePath`, resource, or
|
||||
callable can enter the regional payload.
|
||||
|
||||
## Deterministic scheduled work
|
||||
|
||||
`ScheduledJobRecord` and `RegionalJobScheduler` order due work by:
|
||||
|
||||
```text
|
||||
(due_tick, phase, entity_id, stable_sequence)
|
||||
```
|
||||
|
||||
The scheduler supports O(log n) insertion/cancellation, deterministic due
|
||||
draining, repeats, dedupe keys, a serialized cursor, and strict restore
|
||||
validation. A frame or service budget may process one, eight, or unlimited jobs
|
||||
per call, but all budgets must produce the same order, checksum, and final
|
||||
backlog. Dynamic jobs inserted while draining are ordered into the same queue,
|
||||
not handled by an ad-hoc frame loop.
|
||||
|
||||
`KeyedRandom` derives values from `(world_seed, system_id, entity_id,
|
||||
occurrence)`, so update order and save/load do not consume another entity's
|
||||
random stream. `AnalyticalRegionalUpdates` advances elapsed needs, growth, and
|
||||
periodic work from last-updated ticks instead of scanning every entity each
|
||||
tick.
|
||||
|
||||
## The caravan proof
|
||||
|
||||
`RegionalCaravanService` owns an envelope containing `RegionalWorldState`,
|
||||
`RegionalJobScheduler`, and `WorldEventStore`. `depart()` validates origin,
|
||||
destination, route, cargo capacity, group status, and exact state; it withdraws
|
||||
the cargo and schedules a typed arrival. The arrival handler updates the group,
|
||||
deposits the exact cargo into the destination settlement, and appends the causal
|
||||
load/depart/arrive/deposit chain. Presentation mode is an input label for the
|
||||
test, never an authority branch.
|
||||
|
||||
The service is transactional: invalid jobs, forged event pairs, stale event
|
||||
cursors, duplicate departure pairs, and malformed restore envelopes fail with
|
||||
no partial mutation. `to_dictionary()`, `from_dictionary()`, and `checksum()`
|
||||
provide deterministic save/restore. The test runs always-loaded, never-loaded,
|
||||
and load/unload presentation modes through the same authoritative service.
|
||||
|
||||
## Chunked persistence
|
||||
|
||||
`RegionalChunkedPersistence` captures the service into a manifest plus fixed
|
||||
primitive chunks:
|
||||
|
||||
- one global index;
|
||||
- one location chunk per location;
|
||||
- one mobile-group chunk per group;
|
||||
- one scheduler chunk;
|
||||
- fixed-size event segments.
|
||||
|
||||
Each descriptor contains record count, byte size, and SHA-256 checksum. Restore
|
||||
rejects missing, duplicated, unknown, reordered, tampered, out-of-scope, or
|
||||
non-primitive chunks. `load_active_location_metadata()` reads the global index
|
||||
and one location while retaining authoritative references to unloaded chunks.
|
||||
|
||||
`RegionalChunkedFileStore` writes immutable fixed-width generation directories,
|
||||
validates a temporary generation before install, updates a small current
|
||||
pointer, recovers the newest valid generation when the pointer is stale, and
|
||||
keeps at least two valid generations when pruning. It uses Godot's available
|
||||
flush/close/rename primitives; a platform fsync is not exposed by this layer.
|
||||
The store has explicit path, file-count, chunk-size, generation-size, and
|
||||
primitive-tree bounds.
|
||||
|
||||
## Current integration boundary
|
||||
|
||||
The regional package is not yet the production authority for `main.tscn`:
|
||||
|
||||
- Jajce local saves still use `SaveSlotStore` and `SimulationStateRecord` v16;
|
||||
- `RegionalCaravanService` is a complete isolated transfer proof, not the live
|
||||
economy's 20-trade scheduler;
|
||||
- event retention/rollups and regional chunk files are not yet one integrated
|
||||
long-horizon save transaction;
|
||||
- loaded/unloaded local NPC travel still has the old active-visual boundary;
|
||||
- cohort promotion, settlement growth, offices, diplomacy, armies, and
|
||||
aggregate conflict remain planned.
|
||||
|
||||
Do not create one `SimulationManager` per settlement or caravan. The next
|
||||
production step is an explicit regional facade that delegates to these records
|
||||
and services, while the active adapter presents only a bounded relevant context.
|
||||
|
||||
## Scale evidence
|
||||
|
||||
`RegionalScaleBenchmark` builds five settlements, 20 caravans × 12 named
|
||||
members, 2,000 named people, 50,000 aggregate residents, and 2,025 jobs. It
|
||||
proves conservation, canonical roundtrip, budget parity, and repeatable
|
||||
checksums. It does **not** claim rendered frame time, a complete market, a
|
||||
30-day economy, or weak-PC GPU performance.
|
||||
|
||||
See [Regional simulation contract](REGIONAL_SIMULATION.md),
|
||||
[regional baseline 01](benchmarks/REGIONAL_SCALE_BASELINE_01.md), and
|
||||
[Testing and benchmarks](FEATURE_TESTING_AND_BENCHMARKS.md).
|
||||
@@ -0,0 +1,98 @@
|
||||
# Feature slice: saves, schema, migrations, and continuation
|
||||
|
||||
The local playable world and the regional proof use different persistence
|
||||
boundaries. Both are primitive-only, versioned, deterministic, and validated
|
||||
before mutation.
|
||||
|
||||
## Local save boundary
|
||||
|
||||
`SimulationStateRecord` is currently schema **v16**. It contains the local
|
||||
simulation seed/clock scope, village/NPC/animal/resource/storage/player/
|
||||
combatant/faction records, ordered economic events, relationships, knowledge,
|
||||
legacy opportunities, situations, journal entries, commitments, and bounded
|
||||
semantic conversation acts. `SimulationManager.create_state_record()` creates
|
||||
it; `serialize_state()` emits canonical JSON; `restore_state()` preflights and
|
||||
then atomically restores dependent systems.
|
||||
|
||||
Top-level v16 adds non-empty `world_id` and `location_id`. Activity success and
|
||||
blocked facts carry the same scope. A save recorded under another active adapter
|
||||
is rejected before clock, economy, NPC, or event state is mutated. This closes
|
||||
the context-reinterpretation hole where equal local coordinates could be
|
||||
treated as the same world.
|
||||
|
||||
The record stores IDs, primitive values, event IDs, and semantic topic IDs. It
|
||||
never stores scripts, nodes, `NodePath`s, callables, imported assets, dialogue
|
||||
prose, or transient HUD/balloon state.
|
||||
|
||||
## Migration policy
|
||||
|
||||
Nested records migrate at their own version; the top-level schema accepts an
|
||||
explicit historical range and normalizes old fields before cross-record
|
||||
validation. Current supported migrations include:
|
||||
|
||||
- legacy village/storage and event streams;
|
||||
- directed relationships and causal knowledge provenance;
|
||||
- opportunity history and its v2 lifecycle;
|
||||
- animal routine/definition IDs;
|
||||
- player citizen needs/health;
|
||||
- combatants, factions, and enemy definition IDs;
|
||||
- situations, journal entries, commitments, and conversation acts;
|
||||
- world/location scope v16;
|
||||
- explicitly marked legacy unstructured `task_blocked` facts.
|
||||
|
||||
Old definition values are not snapshotted. The current build supplies balance
|
||||
and handler definitions while mutable saved state is preserved. Unknown future
|
||||
schema versions fail closed until a migration exists.
|
||||
|
||||
## Validation invariants
|
||||
|
||||
Restore checks include:
|
||||
|
||||
- unique IDs and next-ID cursors above restored history;
|
||||
- valid definition/action/item/storage references;
|
||||
- actor/target/cost/effect contracts for activity facts;
|
||||
- animal reservations and feed event agreement;
|
||||
- relationship causes pointing at valid known events;
|
||||
- knowledge provenance and one-hop communication rules;
|
||||
- situation/journal/commitment references and statuses;
|
||||
- scope consistency for the event log and activity facts;
|
||||
- no future event tick or forged actor/source/destination fields.
|
||||
|
||||
The test suite deliberately removes derived knowledge/opportunity state and
|
||||
tamper-tests facts, so validation does not rely on a secondary projection to
|
||||
catch corruption.
|
||||
|
||||
## Local file safety
|
||||
|
||||
`SaveSlotStore` validates the complete JSON before replacement, restricts slot
|
||||
names and size, preserves a previous file, and can recover a backup after an
|
||||
interrupted replacement. `F5`/`F9` use the current quicksave path in `main.tscn`.
|
||||
The player transform and presentation-only scene state are intentionally not
|
||||
saved.
|
||||
|
||||
## Regional persistence boundary
|
||||
|
||||
`RegionalChunkedPersistence` and `RegionalChunkedFileStore` are the regional
|
||||
counterpart. They serialize a `RegionalCaravanService` envelope into global,
|
||||
location, mobile-group, scheduler, and event-segment chunks, with manifest and
|
||||
per-file checksums. The file store uses immutable generations, a current
|
||||
pointer, recovery scanning, and conservative pruning. Partial active-location
|
||||
loads are metadata-only and cannot silently resurrect a removed location.
|
||||
|
||||
This regional codec is not yet the backend for local `SaveSlotStore`. Integrate
|
||||
it only after the production regional facade, event retention, and lazy context
|
||||
loading have one atomic manifest contract.
|
||||
|
||||
## How to change state safely
|
||||
|
||||
1. Add the field to the narrow nested record first.
|
||||
2. Define `SCHEMA_VERSION`, validation, canonical `to_dictionary()`, and an
|
||||
explicit migration from the prior version.
|
||||
3. Update top-level construction/restore/checksum only after the nested record
|
||||
round-trips.
|
||||
4. Add malformed/tamper, old-save migration, save/load, and deterministic
|
||||
continuation tests.
|
||||
5. Update [SIMULATION_STATE_SCHEMA.md](SIMULATION_STATE_SCHEMA.md) and this
|
||||
guide with the actual version and compatibility range.
|
||||
|
||||
The full field-by-field history remains in [Simulation State Schema](SIMULATION_STATE_SCHEMA.md).
|
||||
@@ -0,0 +1,101 @@
|
||||
# Feature slice: tests, quality, and performance evidence
|
||||
|
||||
The project uses deterministic headless scenarios, GUT unit tests, formatting/
|
||||
lint checks, and reviewed benchmark ledgers. Tests are part of the architecture:
|
||||
they prove authority boundaries, conservation, migration, parity, and
|
||||
deterministic continuation.
|
||||
|
||||
## Quality gate
|
||||
|
||||
Run from the repository root:
|
||||
|
||||
```bash
|
||||
./tools/quality.sh --changed # fast iteration
|
||||
./tools/quality.sh # full gate before commit
|
||||
git diff --check
|
||||
```
|
||||
|
||||
The gate currently runs Godot 4.7 platform/import checks, `gdformat`,
|
||||
`gdlint`, headless project checks, standalone scenarios, GUT, and a dedicated
|
||||
Compatibility presentation smoke. It uses an isolated Godot profile under
|
||||
`logs/quality/godot_profile`. On macOS, Godot's certificate-store diagnostic,
|
||||
Terrain3D interpolation deprecation, and the exact known dummy-shader exit
|
||||
diagnostic are classified by the gate; new error classes must not be hidden.
|
||||
|
||||
## Scenario families
|
||||
|
||||
| Concern | Representative tests |
|
||||
| --- | --- |
|
||||
| Definitions and packs | `content_catalog_test`, `simulation_definitions_test`, `test_activity_content_catalog_contract` |
|
||||
| Targets and interaction parity | `world_target_registry_test`, `context_scoped_world_targets_test`, `resource_node_player_parity_test`, `test_activity_action_command_service` |
|
||||
| Economy and resources | `food_storage_loop_test`, `resource_regrowth_test`, `animal_food_delivery_test` |
|
||||
| Animals and enemies | `animal_definition_contract_test`, `animal_pair_vertical_slice_test`, `test_combatant_factory`, `conflict_war_system_test` |
|
||||
| Events and social facts | `test_world_event_store`, `test_social_foundations`, `witnessed_knowledge_consequence_test`, `relationship_consequence_test` |
|
||||
| Situations and dialogue | `test_situation_system`, `emergent_jajce_slice_test`, `conversation_domain_test`, `dialogue_manager_conversation_presenter_test`, `dialogue_mode_controller_test` |
|
||||
| Save/migration | `test_emergent_state_validation`, `simulation_state_serialization_test`, `save_slot_persistence_test`, `test_commitment_lifecycle_service` |
|
||||
| Regional records | `test_regional_world_state`, `test_regional_scheduler`, `test_regional_caravan_service`, `test_regional_chunked_persistence`, `test_regional_chunked_file_store` |
|
||||
| Presentation | `jajce_world_scaffold_test`, `jajce_presentation_quality_test`, `jajce_runtime_integration_test`, `test_presentation_relevance_policy`, `creature_visual_path_retry_test` |
|
||||
|
||||
When a change affects state, target selection, saves, navigation reachability,
|
||||
player/NPC parity, deterministic continuation, or a fact-representing UI,
|
||||
extend a scenario rather than relying on a parser/lint pass.
|
||||
|
||||
## Benchmark runners
|
||||
|
||||
```bash
|
||||
# local simulation population/history fixture
|
||||
godot --headless --path "$PWD" \
|
||||
--script res://tools/benchmark_simulation_scaling.gd
|
||||
|
||||
# loaded finite-resource spatial discovery
|
||||
godot --headless --path "$PWD" \
|
||||
--script res://tools/benchmark_loaded_resource_discovery.gd
|
||||
|
||||
# regional records and scheduler (20 caravans / 50k cohorts)
|
||||
godot --headless --path "$PWD" \
|
||||
--script res://tools/benchmark_regional_scale.gd
|
||||
```
|
||||
|
||||
Reviewed reports live in `docs/benchmarks/` beside machine-readable JSON. A
|
||||
benchmark must record seed, Godot version, host label, workload/schema ID,
|
||||
sample count, warmup, simulated ticks, checksums, and exclusions. Structural
|
||||
headless measurements cannot be presented as rendered frame-time claims.
|
||||
|
||||
## Determinism and conservation checklist
|
||||
|
||||
For a new system, add tests for:
|
||||
|
||||
- same seed/run produces the same canonical checksum;
|
||||
- save/load at the important boundary continues identically;
|
||||
- execution budgets `{1, 8, unlimited}` preserve order and result where a
|
||||
scheduler is involved;
|
||||
- loaded, unloaded, and load/unload presentation produce identical authority;
|
||||
- people, cargo, inventory, storage, unique items, and event IDs conserve;
|
||||
- stale offers, duplicate IDs, unknown definitions, forged facts, and scope
|
||||
mismatches fail without partial mutation;
|
||||
- important identities remain pinned through relevance/aggregation decisions.
|
||||
|
||||
## Current evidence and gaps
|
||||
|
||||
The current full suite passes 154/154 tests with 2,047 assertions. Baseline 03
|
||||
measures 600 full-fidelity data-only NPC/combatant records at about 90.6 ticks/s
|
||||
on the reviewed development host. The regional baseline proves the target
|
||||
record counts and scheduler parity. Neither measures a complete regional
|
||||
economy or weak-PC rendering.
|
||||
|
||||
The next performance evidence should capture High and Low at a fixed gameplay
|
||||
camera on a named weak-PC reference: p50/p95/p99 CPU/GPU frame time, draw calls,
|
||||
primitives, memory/VRAM, active detailed visuals, and navigation queue depth.
|
||||
Keep those measurements in a reviewed ledger instead of adding brittle hardware
|
||||
limits to CI.
|
||||
|
||||
## Test authoring conventions
|
||||
|
||||
- Use stable IDs and fixed seeds.
|
||||
- Prefer exact assertions over prose or frame timing.
|
||||
- Make test fixtures isolate duplicate stable-ID registries and world scopes.
|
||||
- Use fake presenters for semantic dialogue; reserve plugin/parser tests for the
|
||||
adapter boundary.
|
||||
- Keep benchmark fixtures independent of production managers unless the test is
|
||||
explicitly an integration proof.
|
||||
- Run focused tests while editing, then the full gate before committing.
|
||||
@@ -72,11 +72,14 @@ the unit never consults pantry stock again before delivery.
|
||||
|
||||
## Deliberate limits
|
||||
|
||||
The current bounded economy has one authored pantry and one woodpile with
|
||||
simple food/wood stacks. It does not yet add:
|
||||
The current playable economy still has one authored village pantry and one
|
||||
woodpile, but it now also has typed item definitions, an apothecary route,
|
||||
persisted player inventory, and definition-backed activity costs. It does not
|
||||
yet add:
|
||||
|
||||
- player inventory;
|
||||
- storage reservations or access capacity;
|
||||
- regional storage/market ledgers;
|
||||
- storage reservations or ownership/access policy beyond authored capability
|
||||
routing;
|
||||
- multiple households or ownership;
|
||||
- spoilage, item quality, weight, or stack definitions.
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# The Steward — Learning and Reusable-Systems Roadmap
|
||||
|
||||
> **Current implementation checkpoint (2026-08-13):** The roadmap below is a
|
||||
> chronological learning record. The current code has completed the authored
|
||||
> content/catalog, shared target/command, event/social, situation/dialogue,
|
||||
> entity-family, context-scoping, and first regional record/caravan/chunk
|
||||
> slices. For a source-based status matrix and the remaining integration work,
|
||||
> start with [`DEVELOPER_INDEX.md`](DEVELOPER_INDEX.md). Do not infer current
|
||||
> behavior from an older milestone paragraph when the index or code disagrees.
|
||||
|
||||
## Purpose
|
||||
|
||||
This project is both a playable prototype and an advanced Godot curriculum.
|
||||
|
||||
+24
-18
@@ -2,8 +2,10 @@
|
||||
|
||||
> 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.
|
||||
> Snapshot basis: repository state on August 13, 2026. This document preserves
|
||||
> the product context and learning history; the current implementation matrix
|
||||
> is maintained in [`DEVELOPER_INDEX.md`](DEVELOPER_INDEX.md). Treat code and
|
||||
> tests as the source of truth when a historical paragraph differs.
|
||||
|
||||
See the [documentation map](README.md) for the authority and scope of each plan.
|
||||
|
||||
@@ -663,7 +665,8 @@ These are expected prototype constraints, not necessarily isolated bugs:
|
||||
the typed pantry `StorageNode`, and patrol/study/rest use `ActivitySite`.
|
||||
- Current NPC, village, resource, storage, animal, event, knowledge,
|
||||
relationship, opportunity, clock, RNG, player-citizen, combatant, and
|
||||
faction state serialize through world schema v14. F5/F9 provide one validated
|
||||
faction, situation, journal, commitment, and semantic conversation state
|
||||
serialize through world schema v16. F5/F9 provide one validated
|
||||
local quicksave; a save menu, metadata, and player-transform persistence
|
||||
remain deferred.
|
||||
- Combatants and factions are deterministic simulation records. NPC defenders,
|
||||
@@ -702,20 +705,20 @@ These are expected prototype constraints, not necessarily isolated bugs:
|
||||
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 need from exact known
|
||||
evidence: `restock_empty_pantry`, `supply_missing_wood`,
|
||||
`feed_weak_villager`, and `repair_home_roof`. The pantry and weak-villager
|
||||
needs resolve through real food supply (the weak need only when the
|
||||
interested villager actually eats), the wood needs through the real
|
||||
wood-deposit path, and all close 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 legacy bounded opportunity family supports one open need from exact
|
||||
known evidence: `restock_empty_pantry`, `supply_missing_wood`,
|
||||
`feed_weak_villager`, and `repair_home_roof`. The newer `SituationSystem`
|
||||
supports up to three authored active situations in the initial Jajce slice,
|
||||
a player journal projection, social commitments, deterministic semantic
|
||||
dialogue, and idempotent fulfilled/broken/released/superseded consequences.
|
||||
Progress remains derived from real state and ordinary events; no layer
|
||||
manufactures quest-only stock or rewards.
|
||||
- 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.
|
||||
- Active navigation is still used as if all detailed agents are local; the
|
||||
regional relevance policy and 40-visual/navigation-budget contracts exist,
|
||||
but production simulation LOD/streaming is not yet wired into the live view.
|
||||
- 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;
|
||||
@@ -732,8 +735,11 @@ These are expected prototype constraints, not necessarily isolated bugs:
|
||||
- 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.
|
||||
- Companions, a complete market/trade economy, settlement growth, offices,
|
||||
politics, generalized/multi-hop rumours, production regional travel
|
||||
integration, and kingdom-scale conflict do not yet exist. Regional records,
|
||||
scheduled work, one exact caravan transfer, situations, commitments, and
|
||||
generated semantic dialogue do exist as tested foundations.
|
||||
- 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.
|
||||
@@ -1112,7 +1118,7 @@ parallel.
|
||||
|
||||
## Out of scope until the simulation garden works
|
||||
|
||||
- full regional map;
|
||||
- production-wired full regional map and travel facade;
|
||||
- large city population;
|
||||
- multiplayer;
|
||||
- procedural world generation;
|
||||
@@ -1121,7 +1127,7 @@ parallel.
|
||||
- kingdom-scale diplomacy;
|
||||
- large battles;
|
||||
- broad crafting catalog;
|
||||
- fully generated dialogue;
|
||||
- free-form generated prose (semantic deterministic dialogue is implemented);
|
||||
- multiple large production chains;
|
||||
- production-quality character customization.
|
||||
|
||||
|
||||
+23
-8
@@ -1,35 +1,50 @@
|
||||
# Documentation map
|
||||
|
||||
Start with [`DEVELOPER_INDEX.md`](DEVELOPER_INDEX.md). It is the developer
|
||||
onboarding index: a current feature matrix, repository map, extension workflow,
|
||||
verification commands, and links into the detailed contracts below.
|
||||
|
||||
The project uses a small hierarchy so overlapping plans do not become competing
|
||||
sources of truth.
|
||||
|
||||
This directory is intentionally covered by `.gdignore`: plans and baseline
|
||||
captures are review artifacts, not runtime Godot resources.
|
||||
|
||||
1. [`PROJECT_CONTEXT.md`](PROJECT_CONTEXT.md) is the canonical description of
|
||||
1. [`DEVELOPER_INDEX.md`](DEVELOPER_INDEX.md) is the current implementation
|
||||
index and the fastest route to a feature slice.
|
||||
2. [`PROJECT_CONTEXT.md`](PROJECT_CONTEXT.md) is the canonical description of
|
||||
the vision, current implementation, target architecture, and active
|
||||
constraints.
|
||||
2. [`ARCHITECTURE_OVERVIEW.md`](ARCHITECTURE_OVERVIEW.md) is the concise map of
|
||||
3. [`ARCHITECTURE_OVERVIEW.md`](ARCHITECTURE_OVERVIEW.md) is the concise map of
|
||||
runtime ownership, folder responsibilities, and dependency rules.
|
||||
3. [`LEARNING_ROADMAP.md`](LEARNING_ROADMAP.md) owns milestone order,
|
||||
4. [`LEARNING_ROADMAP.md`](LEARNING_ROADMAP.md) owns milestone order,
|
||||
architecture gates, reusable-system exit tests, and intentionally deferred
|
||||
work.
|
||||
4. [`BUILD_IN_PUBLIC_PLAN.md`](BUILD_IN_PUBLIC_PLAN.md) owns the scoped Jajce
|
||||
5. [`BUILD_IN_PUBLIC_PLAN.md`](BUILD_IN_PUBLIC_PLAN.md) owns the scoped Jajce
|
||||
visual slice. It must respect the architecture gates in the learning
|
||||
roadmap.
|
||||
5. [`RESOURCE_NODE_MIGRATION.md`](RESOURCE_NODE_MIGRATION.md) is a focused
|
||||
6. [`RESOURCE_NODE_MIGRATION.md`](RESOURCE_NODE_MIGRATION.md) is a focused
|
||||
migration plan. Phases 1–6 are complete; follow-up work should expand
|
||||
resource discovery without reintroducing abstract resource zones.
|
||||
6. [`ACTION_SYSTEM_ARCHITECTURE.md`](ACTION_SYSTEM_ARCHITECTURE.md),
|
||||
7. [`ACTION_SYSTEM_ARCHITECTURE.md`](ACTION_SYSTEM_ARCHITECTURE.md),
|
||||
[`ECONOMIC_EVENTS.md`](ECONOMIC_EVENTS.md),
|
||||
[`FOOD_STORAGE_ARCHITECTURE.md`](FOOD_STORAGE_ARCHITECTURE.md),
|
||||
[`REGIONAL_SIMULATION.md`](REGIONAL_SIMULATION.md),
|
||||
[`SIMULATION_DEFINITIONS.md`](SIMULATION_DEFINITIONS.md), and
|
||||
[`SIMULATION_STATE_SCHEMA.md`](SIMULATION_STATE_SCHEMA.md) document the
|
||||
current data contracts.
|
||||
7. [`decisions/`](decisions/) contains durable architectural decisions,
|
||||
8. The implementation guides explain the larger slices without replacing the
|
||||
narrow contracts: [authored content](FEATURE_CONTENT_AND_AUTHORED_DATA.md),
|
||||
[commands and economy](FEATURE_COMMANDS_TARGETS_AND_ECONOMY.md),
|
||||
[events through dialogue](FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md),
|
||||
[regional simulation](FEATURE_REGIONAL_SIMULATION_AND_PERSISTENCE.md),
|
||||
[entity families](FEATURE_ENTITIES_COMBAT_ANIMALS.md),
|
||||
[presentation/performance](FEATURE_PRESENTATION_PERFORMANCE.md),
|
||||
[saves/migrations](FEATURE_SAVE_SCHEMA_AND_MIGRATIONS.md), and
|
||||
[testing/benchmarks](FEATURE_TESTING_AND_BENCHMARKS.md).
|
||||
9. [`decisions/`](decisions/) contains durable architectural decisions,
|
||||
including consequences and revisit conditions.
|
||||
8. [`benchmarks/`](benchmarks/) contains reviewed, workload-specific
|
||||
10. [`benchmarks/`](benchmarks/) contains reviewed, workload-specific
|
||||
performance ledgers and their machine-readable samples. Measurements are
|
||||
local evidence, not portable CI limits.
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Regional simulation contract
|
||||
|
||||
> **Implementation status (2026-08-13):** The record, scheduler, caravan,
|
||||
> chunk, file-generation, relevance, and navigation-budget contracts are
|
||||
> implemented and tested. They are still an additive regional package; the
|
||||
> playable Jajce `SimulationManager` and `SaveSlotStore` remain the local
|
||||
> production authority until the integrations listed at the end land.
|
||||
|
||||
The regional layer extends the Jajce simulation without multiplying scene-tree
|
||||
managers. One authority owns every loaded and unloaded location, settlement,
|
||||
route, mobile group, named person, population cohort, polity, scheduled job,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Current contract
|
||||
|
||||
`SimulationStateRecord` is the versioned JSON boundary for the current
|
||||
`SimulationStateRecord` is the versioned JSON boundary for the current local
|
||||
simulation. The current world schema is v16 and captures:
|
||||
|
||||
- simulation seed, stable regional world/location scope, tick interval, tick
|
||||
@@ -445,7 +445,7 @@ replayed after restore.
|
||||
|
||||
## Local quicksave boundary
|
||||
|
||||
`SaveSlotStore` writes the existing versioned JSON record to
|
||||
`SaveSlotStore` writes the existing versioned local JSON record to
|
||||
`user://saves/quicksave.json`. It validates the serialized record before
|
||||
replacement, limits file size, restricts slot names, preserves the previous
|
||||
file during replacement, and can recover that backup if replacement is
|
||||
@@ -461,7 +461,7 @@ This phase does not yet provide:
|
||||
|
||||
- a save-slot menu, metadata, thumbnails, autosaves, or multiple profiles;
|
||||
- migrations from any historical world schema other than the explicitly
|
||||
supported v1-v14 layouts;
|
||||
supported v1-v16 layouts;
|
||||
- line-of-sight/hearing evidence, personalized confidence decay,
|
||||
reinforcement, false beliefs, or multi-hop rumours;
|
||||
- the full regional situation predicate library, regional quest bounds,
|
||||
@@ -470,8 +470,8 @@ This phase does not yet provide:
|
||||
- persistence of a currently open dialogue UI/turn. Semantic conversation
|
||||
history and commitment authority persist, while a balloon is regenerated
|
||||
after restore;
|
||||
- chunked regional saves, lazy location loading, or aggregate population
|
||||
persistence;
|
||||
- production integration of the regional chunked save manifest, lazy location
|
||||
loading, or aggregate population promotion/persistence;
|
||||
- persistence for the player transform or presentation-only scene state.
|
||||
|
||||
Those features should build on this boundary rather than inventing parallel
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Simulation benchmark ledger
|
||||
|
||||
The [testing and benchmarks guide](../FEATURE_TESTING_AND_BENCHMARKS.md)
|
||||
explains how to add a workload, what each current result proves, and which
|
||||
rendered-performance claims are intentionally still unmeasured.
|
||||
|
||||
This directory stores reviewed benchmark snapshots. Each snapshot must name the
|
||||
workload, seed, Godot version, hardware context, sample count, simulated tick
|
||||
count, and important exclusions so later comparisons remain honest.
|
||||
|
||||
@@ -10,3 +10,14 @@ plans. Use the next sequential number and include:
|
||||
- conditions for revisiting the decision.
|
||||
|
||||
Do not create records for routine edits or choices that are still exploratory.
|
||||
|
||||
## Accepted records
|
||||
|
||||
| ADR | Scope | Current consequence |
|
||||
| --- | --- | --- |
|
||||
| [0001 — simulation authority boundary](0001-simulation-authority-boundary.md) | Fixed-step simulation, scene/presentation boundary, stable IDs, save authority | Loaded nodes may present and report geometry, but they do not own persistent facts or completion |
|
||||
| [0002 — emergent world content and narrative](0002-emergent-world-content-and-narrative.md) | Typed packs, shared commands, causal facts, situations, dialogue, and one regional authority | New reusable content is data-first; new mechanics add bounded handlers; quests/dialogue project real world state |
|
||||
|
||||
The [developer index](../DEVELOPER_INDEX.md) summarizes how these decisions
|
||||
appear in the current modules. Add a new ADR only when a choice should survive
|
||||
multiple feature plans and has explicit revisit conditions.
|
||||
|
||||
Reference in New Issue
Block a user