feat: integrate regional caravan persistence
This commit is contained in:
+13
-12
@@ -21,10 +21,11 @@ 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.
|
||||
caravan transfer service, a production facade for one inbound Jajce route, a
|
||||
combined local/regional save manifest, chunked persistence, and a 20-caravan
|
||||
structural benchmark. It does not yet provide a complete market,
|
||||
settlement-growth, or kingdom gameplay loop. That distinction is important
|
||||
when extending the game.
|
||||
|
||||
## Start here
|
||||
|
||||
@@ -53,9 +54,9 @@ kingdom gameplay loop. That distinction is important when extending the game.
|
||||
| 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 |
|
||||
| Regional kernel | Primitive records, due-job heap, keyed random, analytical updates, caravan service, production facade, chunk/file store | One authored inbound route is live; the 20-caravan economy remains a structural fixture, not the Jajce market |
|
||||
| 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 |
|
||||
| Persistence | Combined manifest v1 containing unchanged local schema v16 plus the canonical regional facade; regional chunk generations with recovery | No save menu/profile system; regional chunk/history generations are not yet the `SaveSlotStore` backend |
|
||||
|
||||
## The authority pipeline
|
||||
|
||||
@@ -106,9 +107,10 @@ relationship, or reward that the event claims happened.
|
||||
- `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.
|
||||
- `simulation/persistence/` — combined quicksave manifest and atomic slot
|
||||
replacement, plus regional chunk codecs and generations.
|
||||
- `simulation/regional/` — production facade, regional records, scheduler,
|
||||
caravan transaction, retention planning, and scale contracts.
|
||||
|
||||
### Loaded world and presentation
|
||||
|
||||
@@ -161,12 +163,11 @@ are used when an existing save is loaded.
|
||||
|
||||
The following are deliberately **not** claimed as complete:
|
||||
|
||||
- wire `RegionalCaravanService` into the production regional facade and local
|
||||
save manifest;
|
||||
- integrate event retention/rollups/chunked history into one atomic,
|
||||
lazily loaded long-horizon save;
|
||||
- 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
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
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.
|
||||
The production `SimulationManager` now owns a bounded regional facade for one
|
||||
inbound Jajce route, while the broader regional contracts continue to prove
|
||||
deterministic unloaded work and conservation before wider integration.
|
||||
|
||||
## Regional record model
|
||||
|
||||
@@ -63,6 +63,12 @@ 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.
|
||||
|
||||
`RegionalSimulationFacade` is the first production consumer. It owns one
|
||||
authored Travnik-to-Jajce route, advances before each committed local tick, and
|
||||
exposes one bounded delivery command. The cargo is a separate catalogued
|
||||
`regional_trade_goods` item with no local storage tag, so this proof does not
|
||||
shadow or duplicate the pantry and woodpile economy.
|
||||
|
||||
## Chunked persistence
|
||||
|
||||
`RegionalChunkedPersistence` captures the service into a manifest plus fixed
|
||||
@@ -89,11 +95,20 @@ primitive-tree bounds.
|
||||
|
||||
## Current integration boundary
|
||||
|
||||
The regional package is not yet the production authority for `main.tscn`:
|
||||
`main.tscn` now advances the regional facade and `SaveSlotStore` writes a
|
||||
combined `SimulationSaveManifest` containing the unchanged local v16 record
|
||||
and canonical regional envelope. Both checksums plus world, seed, location,
|
||||
and tick alignment are validated before either authority is restored. Raw
|
||||
local v16 slots remain compatible and create an idle regional facade;
|
||||
explicit non-Jajce adapter scopes keep writing local v16 until they have a
|
||||
matching regional facade. Those scopes cannot dispatch a Jajce delivery, and
|
||||
local-only saving fails closed if regional state is no longer reconstructibly
|
||||
idle.
|
||||
|
||||
- Jajce local saves still use `SaveSlotStore` and `SimulationStateRecord` v16;
|
||||
- `RegionalCaravanService` is a complete isolated transfer proof, not the live
|
||||
economy's 20-trade scheduler;
|
||||
The remaining boundary is intentionally narrow:
|
||||
|
||||
- the facade has one callable inbound route, not the live economy's 20-trade
|
||||
market 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;
|
||||
@@ -101,8 +116,8 @@ The regional package is not yet the production authority for `main.tscn`:
|
||||
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.
|
||||
production step is to publish retained raw events, daily rollups, and chunked
|
||||
regional history as one atomic, lazily loaded transaction behind the facade.
|
||||
|
||||
## Scale evidence
|
||||
|
||||
|
||||
@@ -64,11 +64,22 @@ 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.
|
||||
`SimulationSaveManifest` v1 combines the unchanged local v16 record and the
|
||||
canonical `RegionalSimulationFacade` envelope. It stores an independent
|
||||
checksum for each authority and cross-validates world, seed, active location,
|
||||
and processed tick. A rejected manifest cannot partially replace local or
|
||||
regional state.
|
||||
|
||||
`SaveSlotStore` validates the complete manifest before replacement, restricts
|
||||
slot names and size, preserves a previous file, and can recover a backup after
|
||||
an interrupted replacement. It also accepts existing raw local v16 files and
|
||||
bootstraps an idle regional facade at the restored seed and tick. Explicit
|
||||
non-Jajce adapter scopes continue writing raw local v16 records until a
|
||||
matching regional facade is implemented. This fallback is permitted only while
|
||||
the regional facade equals its deterministic idle bootstrap; a local-only save
|
||||
fails closed rather than discarding live regional state. `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
|
||||
|
||||
@@ -79,9 +90,10 @@ 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.
|
||||
This regional chunk codec is not yet the backend for `SaveSlotStore`. The
|
||||
production facade and combined quicksave manifest are complete; retained raw
|
||||
events, rollups, chunk generations, and lazy context loading still need one
|
||||
atomic long-horizon publication contract.
|
||||
|
||||
## How to change state safely
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ For a new system, add tests for:
|
||||
|
||||
## Current evidence and gaps
|
||||
|
||||
The current full suite passes 154/154 tests with 2,047 assertions. Baseline 03
|
||||
The current full suite passes 180/180 tests with 2,258 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
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# The Steward — Learning and Reusable-Systems Roadmap
|
||||
|
||||
> **Current implementation checkpoint (2026-08-13):** The roadmap below is a
|
||||
> **Current implementation checkpoint (2026-08-23):** 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,
|
||||
> slices, including one production facade and combined save manifest. 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.
|
||||
|
||||
@@ -43,8 +44,8 @@ becomes knowledge, generated semantic dialogue, a journal projection, and an
|
||||
event-backed social commitment whose ordinary deposit outcome survives
|
||||
save/load. Definition packs now cover reusable items, resources, storage,
|
||||
enemies, and animals. Regional records, deterministic scheduled work, bounded
|
||||
presentation relevance, and the first authoritative caravan transfer form the
|
||||
next world-slice foundation. See
|
||||
presentation relevance, and the first authoritative caravan transfer now feed
|
||||
one production facade and combined local/regional save boundary. See
|
||||
[ADR 0001](decisions/0001-simulation-authority-boundary.md),
|
||||
[ADR 0002](decisions/0002-emergent-world-content-and-narrative.md), and the
|
||||
[regional simulation contract](REGIONAL_SIMULATION.md).
|
||||
@@ -1107,6 +1108,12 @@ resolution, and personal request accept/decline.
|
||||
|
||||
Recently completed:
|
||||
|
||||
- `Regional Jajce Facade 13`: `SimulationManager` now advances one authored
|
||||
Travnik-to-Jajce caravan route through the regional service, and an atomic
|
||||
combined manifest preserves both local v16 and regional authority. Separate
|
||||
regional trade goods prevent duplicate pantry/woodpile ownership; tamper,
|
||||
legacy-slot, rollback, conservation, and deterministic continuation
|
||||
regressions define the boundary before broader markets or chunked history.
|
||||
- `Jajce Villager Field Note 12`: a separate player-facing note selects the
|
||||
nearest loaded living villager and shows live name, action, task state, exact
|
||||
target, carried inventory, and a currently matching decision reason. It
|
||||
|
||||
+37
-16
@@ -1,10 +1,11 @@
|
||||
# Regional simulation contract
|
||||
|
||||
> **Implementation status (2026-08-13):** The record, scheduler, caravan,
|
||||
> **Implementation status (2026-08-23):** 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.
|
||||
> implemented and tested. `SimulationManager` now owns a production regional
|
||||
> facade for one inbound Jajce route, and `SaveSlotStore` persists local and
|
||||
> regional authority in one checked manifest. The scale economy and chunked
|
||||
> long-horizon history remain separate integrations.
|
||||
|
||||
The regional layer extends the Jajce simulation without multiplying scene-tree
|
||||
managers. One authority owns every loaded and unloaded location, settlement,
|
||||
@@ -38,12 +39,10 @@ validated transactionally before a replacement state is published. Canonical
|
||||
serialization sorts record families and IDs, making checksums independent of
|
||||
construction order.
|
||||
|
||||
The current local `SimulationStateRecord` remains the v16 Jajce save boundary.
|
||||
Regional state is deliberately carried in its own versioned service envelope
|
||||
until one playable route consumes it; this avoids placing speculative regional
|
||||
fields in every local save. The merge into the production save manifest must
|
||||
retain this canonical regional payload rather than copying its fields into
|
||||
scene nodes.
|
||||
The current local `SimulationStateRecord` remains the unchanged v16 Jajce
|
||||
record. `SimulationSaveManifest` v1 combines that record with the canonical
|
||||
`RegionalSimulationFacade` envelope and checksums both authorities. Regional
|
||||
fields are not copied into local records or scene nodes.
|
||||
|
||||
## Deterministic work
|
||||
|
||||
@@ -92,6 +91,30 @@ never-loaded, and load/unload executions must preserve cargo, headcount, facts,
|
||||
arrival tick, queue state, and checksum. Nearby visuals may interpolate route
|
||||
progress; they do not report elapsed travel completion.
|
||||
|
||||
## Production facade and combined save
|
||||
|
||||
`RegionalSimulationFacade` is now owned by the production `SimulationManager`.
|
||||
It bootstraps an authored Travnik-to-Jajce route and advances the same
|
||||
`RegionalCaravanService` before each committed local tick. Its bounded public
|
||||
command can depart one exact delivery; arrival remains scheduled simulation
|
||||
work and does not depend on a loaded caravan visual.
|
||||
|
||||
The route transports `regional_trade_goods`, a catalogued item with no local
|
||||
storage tag. Jajce starts with no regional stock and Travnik starts with four
|
||||
units, so the facade cannot duplicate the playable pantry's food or the
|
||||
woodpile's wood. Local and regional event-ID spaces remain deliberately
|
||||
separate until an explicit cross-domain history contract exists.
|
||||
|
||||
`SimulationSaveManifest` stores exactly the local v16 record, its checksum, the
|
||||
regional facade envelope, its checksum, and the manifest schema/version. It
|
||||
rejects checksum tampering and mismatched world, seed, active location, or
|
||||
tick. Combined restore is transactional across both authorities. Existing raw
|
||||
local v16 quicksaves remain loadable and bootstrap an idle regional route at
|
||||
the restored seed and tick. Explicit non-Jajce adapter scopes continue to use
|
||||
their local v16 boundary until a matching regional facade exists. That fallback
|
||||
is allowed only while the regional facade equals its deterministic idle
|
||||
bootstrap; Jajce delivery commands are rejected outside the combined scope.
|
||||
|
||||
## Event retention and daily rollups
|
||||
|
||||
`WorldEventRetentionPlanner` is a pure, deterministic query over a complete
|
||||
@@ -157,14 +180,12 @@ active-world and hardware captures.
|
||||
Build in this order, keeping each step behind conservation and continuation
|
||||
tests:
|
||||
|
||||
1. make the Jajce route proof callable from the production regional facade and
|
||||
save manifest;
|
||||
2. integrate the retention/rollup and chunk codecs as one atomic,
|
||||
1. integrate the retention/rollup and chunk codecs as one atomic,
|
||||
lazily loaded history transaction;
|
||||
3. schedule 20 ordinary caravan trades across five settlement economies;
|
||||
4. promote/demote presentation and population fidelity while pinning named and
|
||||
2. schedule 20 ordinary caravan trades across five settlement economies;
|
||||
3. promote/demote presentation and population fidelity while pinning named and
|
||||
causally referenced people;
|
||||
5. add data-defined settlement projects, tier promotion, offices, diplomacy,
|
||||
4. add data-defined settlement projects, tier promotion, offices, diplomacy,
|
||||
armies, campaigns, and aggregate conflict.
|
||||
|
||||
Context-owned world-target registries and the first shared player/NPC activity
|
||||
|
||||
@@ -451,12 +451,20 @@ replayed after restore.
|
||||
|
||||
## Local quicksave boundary
|
||||
|
||||
`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
|
||||
interrupted. Loading parses and validates the complete record before mutating
|
||||
the simulation.
|
||||
`SaveSlotStore` writes `SimulationSaveManifest` v1 to
|
||||
`user://saves/quicksave.json`. The manifest contains the unchanged local v16
|
||||
record and canonical regional facade envelope, with an independent checksum
|
||||
for each. Restore also requires world, seed, active location, and tick to agree
|
||||
across both authorities, and rolls both back if local restoration fails.
|
||||
|
||||
The store validates the complete serialized manifest before replacement,
|
||||
limits file size, restricts slot names, preserves the previous file during
|
||||
replacement, and can recover that backup if replacement is interrupted. Raw
|
||||
local v16 quicksaves remain loadable; they bootstrap an idle regional facade
|
||||
at the restored seed and tick. Explicit non-Jajce adapter scopes continue
|
||||
writing local v16 records until a matching regional facade exists. Local-only
|
||||
saving is allowed only while regional state equals its deterministic idle
|
||||
bootstrap; otherwise it fails closed rather than discarding authority.
|
||||
|
||||
In `main.tscn`, F5 saves and F9 loads this slot. Restoration rebuilds active NPC
|
||||
visuals from authoritative state.
|
||||
@@ -476,8 +484,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;
|
||||
- production integration of the regional chunked save manifest, lazy location
|
||||
loading, or aggregate population promotion/persistence;
|
||||
- production integration of regional retained/rolled-up chunk history, 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
|
||||
|
||||
Reference in New Issue
Block a user