169 lines
8.3 KiB
Markdown
169 lines
8.3 KiB
Markdown
# Regional simulation contract
|
|
|
|
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,
|
|
and objective world fact. A settlement or caravan scene is presentation, never
|
|
a second simulation.
|
|
|
|
This contract implements the direction accepted in
|
|
[ADR 0002](decisions/0002-emergent-world-content-and-narrative.md).
|
|
|
|
## Authoritative records
|
|
|
|
`RegionalWorldState` is a canonical, primitive-only aggregate of:
|
|
|
|
- `LocationStateRecord`: globally unique location identity and spatial context;
|
|
- `SettlementStateRecord`: location, polity, tier, founding group, stockpile,
|
|
and exact history references;
|
|
- `RouteStateRecord`: stable endpoints and simulation-time travel duration;
|
|
- `MobileGroupStateRecord`: location or route state, detailed members, cohort
|
|
members, cargo, capacity, and exact cargo/history facts;
|
|
- `PersonStateRecord`: a persistent named person at a location or in a group;
|
|
- `PopulationCohortRecord`: a conserved anonymous population count at a
|
|
location or in a group;
|
|
- `PolityStateRecord` and `DiplomaticRelationRecord`: sparse political
|
|
membership and pairwise state.
|
|
|
|
Every ID is unique across record families. Every address includes the world and
|
|
location, so equal local coordinates in different locations cannot create a
|
|
false witness, target, or relationship. Membership and route references are
|
|
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 v15 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.
|
|
|
|
## Deterministic work
|
|
|
|
`RegionalJobScheduler` orders jobs by:
|
|
|
|
```text
|
|
(due_tick, phase, entity_id, stable_sequence)
|
|
```
|
|
|
|
The queue and execution cursor are serialized together. Budgets may defer due
|
|
jobs but cannot reorder, drop, or change them. Tests require budgets of one,
|
|
eight, and unlimited jobs to produce the same ordered results and checksum,
|
|
including work scheduled by another job during execution.
|
|
|
|
`KeyedRandom` derives a decision from world seed, system ID, entity ID, and
|
|
occurrence. It does not consume a shared stream, so loading a context or
|
|
changing the job budget cannot alter another entity's result.
|
|
|
|
`AnalyticalRegionalUpdates` advances elapsed-tick linear, exponential, and
|
|
periodic processes without replaying every omitted tick. New distant systems
|
|
should schedule threshold/completion work or compute from `last_updated_tick`;
|
|
they should not add another global per-tick scan.
|
|
|
|
## First caravan proof
|
|
|
|
`RegionalCaravanService` is the first complete regional transaction. It owns a
|
|
single envelope containing regional state, the due-job queue, the indexed world
|
|
event store, and the next event ID.
|
|
|
|
Departure performs one atomic sequence:
|
|
|
|
1. validate group, route, endpoints, cargo availability, and capacity;
|
|
2. withdraw exact cargo from the origin settlement;
|
|
3. place that cargo in the mobile group;
|
|
4. put the group on the route with authoritative departure/arrival ticks;
|
|
5. record cargo-loaded and departed facts;
|
|
6. schedule one deduplicated arrival job.
|
|
|
|
Arrival atomically moves the group to the destination, transfers exact cargo
|
|
to its stockpile, records arrived and cargo-deposited facts, and cites the prior
|
|
fact in the causal chain. Any invalid reference, duplicate job, capacity
|
|
failure, event collision, or handler failure restores all affected authorities.
|
|
|
|
Presentation mode is intentionally absent from those decisions. Always-loaded,
|
|
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.
|
|
|
|
## Event retention and daily rollups
|
|
|
|
`WorldEventRetentionPlanner` is a pure, deterministic query over a complete
|
|
`WorldEventStore`. It returns a canonical `WorldEventRetentionPlan`; it never
|
|
deletes, replaces, or mutates source facts. The plan keeps the current day plus
|
|
the configured number of prior days raw. Only older event types explicitly
|
|
listed by the caller are eligible for aggregation.
|
|
|
|
An eligible transaction must have a stable world and location plus either one
|
|
positive `item_id`/`amount` pair or a positive multi-item `cargo_ledger`.
|
|
`WorldEventDailyRollupRecord` groups those contributions by day, world,
|
|
location, event type, and item. It retains the event count, total amount,
|
|
tick/event-ID bounds, and a checksum of the exact contributing event IDs.
|
|
`WorldEventDailyRollupStore` provides canonical serialization and indexed
|
|
day/location/type/item queries. Incomplete or ambiguous transaction payloads
|
|
remain raw rather than being guessed into a rollup.
|
|
|
|
Pinned fact IDs and caller-supplied causal fact IDs must exist in the source
|
|
store and always remain raw. Payload `cause_event_id` and `cause_event_ids`
|
|
references must resolve to prior facts; every referenced cause remains raw even
|
|
when its dependent transaction can be rolled up. Missing, dangling, or
|
|
non-prior causes fail the whole plan. Per-event reason traces, reciprocal causal
|
|
edges, source-ID fingerprints, and deterministic count telemetry survive the
|
|
plan's primitive-only round trip.
|
|
|
|
This is a planning foundation, not an active retention authority. A future
|
|
integration must collect external references from knowledge, relationships,
|
|
situations, commitments, journals, and regional history; verify the plan's
|
|
source checksum immediately before applying it; and publish the retained raw
|
|
store, rollup store, and chunk manifest in one atomic transaction. A rollup is
|
|
aggregate history and must never satisfy a consumer that requires an exact
|
|
ordinary world fact.
|
|
|
|
## Presentation relevance
|
|
|
|
`PresentationRelevancePolicy` is a pure query over an active context and
|
|
candidate descriptors. It selects at most 40 detailed visuals in stable order,
|
|
after rejecting foreign worlds, contexts, and locations. Explicit pins,
|
|
player-affecting threats, situation or commitment participants, leaders, and
|
|
unique owners are mandatory. If mandatory candidates exceed the limit, the
|
|
policy fails closed instead of silently erasing an important identity.
|
|
|
|
`PresentationNavRequestBudget` admits at most two new navigation requests per
|
|
frame. Both policies expose selected/rejected IDs and reason traces and do not
|
|
enter authoritative saves.
|
|
|
|
## Scale workload
|
|
|
|
The regional structural workload is fixed at five settlements, 20 caravans of
|
|
12 detailed members, 2,000 persistent named people, 50,000 aggregate
|
|
residents, and metadata for no more than 40 detailed active visuals. It proves
|
|
record validity, global-ID uniqueness, headcount/cargo conservation,
|
|
deterministic scheduler budgets, an empty final backlog, repeatable checksums,
|
|
and measured construction/execution/serialization time.
|
|
|
|
This is a headless data-and-scheduler baseline. It does not claim rendered
|
|
frame time, a complete market/economy, production-integrated chunked history
|
|
retention, or weak-PC GPU performance. Those claims require separate
|
|
active-world and hardware captures.
|
|
|
|
## Next integrations
|
|
|
|
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. migrate legacy global world-target registries to explicit active contexts;
|
|
3. make player and NPC work submit the same concrete action commands;
|
|
4. integrate the retention/rollup and chunk codecs as one atomic,
|
|
lazily loaded history transaction;
|
|
5. schedule 20 ordinary caravan trades across five settlement economies;
|
|
6. promote/demote presentation and population fidelity while pinning named and
|
|
causally referenced people;
|
|
7. add data-defined settlement projects, tier promotion, offices, diplomacy,
|
|
armies, campaigns, and aggregate conflict.
|
|
|
|
Do not add city or kingdom special cases to `SimulationManager`. A new domain
|
|
mechanic adds one reusable record/handler and ordinary world facts; new content
|
|
combines existing definitions in `.tres` packs.
|