diff --git a/README.md b/README.md index 9e8e74a..ea4d61d 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/docs/ARCHITECTURE_OVERVIEW.md b/docs/ARCHITECTURE_OVERVIEW.md index d385fe9..1a06f48 100644 --- a/docs/ARCHITECTURE_OVERVIEW.md +++ b/docs/ARCHITECTURE_OVERVIEW.md @@ -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 diff --git a/docs/BUILD_IN_PUBLIC_PLAN.md b/docs/BUILD_IN_PUBLIC_PLAN.md index b173c72..e5d7307 100644 --- a/docs/BUILD_IN_PUBLIC_PLAN.md +++ b/docs/BUILD_IN_PUBLIC_PLAN.md @@ -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” diff --git a/docs/DEVELOPER_INDEX.md b/docs/DEVELOPER_INDEX.md new file mode 100644 index 0000000..41d2dab --- /dev/null +++ b/docs/DEVELOPER_INDEX.md @@ -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). diff --git a/docs/ECONOMIC_EVENTS.md b/docs/ECONOMIC_EVENTS.md index 9797dee..7f7a40b 100644 --- a/docs/ECONOMIC_EVENTS.md +++ b/docs/ECONOMIC_EVENTS.md @@ -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 diff --git a/docs/FEATURE_COMMANDS_TARGETS_AND_ECONOMY.md b/docs/FEATURE_COMMANDS_TARGETS_AND_ECONOMY.md new file mode 100644 index 0000000..9bb7ce2 --- /dev/null +++ b/docs/FEATURE_COMMANDS_TARGETS_AND_ECONOMY.md @@ -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). diff --git a/docs/FEATURE_CONTENT_AND_AUTHORED_DATA.md b/docs/FEATURE_CONTENT_AND_AUTHORED_DATA.md new file mode 100644 index 0000000..6797d6e --- /dev/null +++ b/docs/FEATURE_CONTENT_AND_AUTHORED_DATA.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. diff --git a/docs/FEATURE_ENTITIES_COMBAT_ANIMALS.md b/docs/FEATURE_ENTITIES_COMBAT_ANIMALS.md new file mode 100644 index 0000000..d13ba99 --- /dev/null +++ b/docs/FEATURE_ENTITIES_COMBAT_ANIMALS.md @@ -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` diff --git a/docs/FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md b/docs/FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md new file mode 100644 index 0000000..018bee4 --- /dev/null +++ b/docs/FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md @@ -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) diff --git a/docs/FEATURE_PRESENTATION_PERFORMANCE.md b/docs/FEATURE_PRESENTATION_PERFORMANCE.md new file mode 100644 index 0000000..d3015f7 --- /dev/null +++ b/docs/FEATURE_PRESENTATION_PERFORMANCE.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). diff --git a/docs/FEATURE_REGIONAL_SIMULATION_AND_PERSISTENCE.md b/docs/FEATURE_REGIONAL_SIMULATION_AND_PERSISTENCE.md new file mode 100644 index 0000000..ea7f845 --- /dev/null +++ b/docs/FEATURE_REGIONAL_SIMULATION_AND_PERSISTENCE.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). diff --git a/docs/FEATURE_SAVE_SCHEMA_AND_MIGRATIONS.md b/docs/FEATURE_SAVE_SCHEMA_AND_MIGRATIONS.md new file mode 100644 index 0000000..1fddf06 --- /dev/null +++ b/docs/FEATURE_SAVE_SCHEMA_AND_MIGRATIONS.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). diff --git a/docs/FEATURE_TESTING_AND_BENCHMARKS.md b/docs/FEATURE_TESTING_AND_BENCHMARKS.md new file mode 100644 index 0000000..069d2b4 --- /dev/null +++ b/docs/FEATURE_TESTING_AND_BENCHMARKS.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. diff --git a/docs/FOOD_STORAGE_ARCHITECTURE.md b/docs/FOOD_STORAGE_ARCHITECTURE.md index dc623ff..0b12393 100644 --- a/docs/FOOD_STORAGE_ARCHITECTURE.md +++ b/docs/FOOD_STORAGE_ARCHITECTURE.md @@ -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. diff --git a/docs/LEARNING_ROADMAP.md b/docs/LEARNING_ROADMAP.md index 1042767..8866e34 100644 --- a/docs/LEARNING_ROADMAP.md +++ b/docs/LEARNING_ROADMAP.md @@ -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. diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 94e874e..d7019b7 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -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. diff --git a/docs/README.md b/docs/README.md index 851f971..6d8d593 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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. diff --git a/docs/REGIONAL_SIMULATION.md b/docs/REGIONAL_SIMULATION.md index b788166..ec4eb62 100644 --- a/docs/REGIONAL_SIMULATION.md +++ b/docs/REGIONAL_SIMULATION.md @@ -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, diff --git a/docs/SIMULATION_STATE_SCHEMA.md b/docs/SIMULATION_STATE_SCHEMA.md index f4b629a..3b10336 100644 --- a/docs/SIMULATION_STATE_SCHEMA.md +++ b/docs/SIMULATION_STATE_SCHEMA.md @@ -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 diff --git a/docs/benchmarks/README.md b/docs/benchmarks/README.md index 20f267c..1ac0268 100644 --- a/docs/benchmarks/README.md +++ b/docs/benchmarks/README.md @@ -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. diff --git a/docs/decisions/README.md b/docs/decisions/README.md index d59ba63..dac9e85 100644 --- a/docs/decisions/README.md +++ b/docs/decisions/README.md @@ -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.