0.6 horizontal scaling axis partial est. further testing needed.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Nimmerworld — Broad Architecture
|
# Nimmerworld — Broad Architecture
|
||||||
|
|
||||||
> *Ground-up zone-based event architecture. Minds at the center, world as co-remembering substrate. Three registers of reality — physical, liminal, imperial. Rail topology outside, navmesh interiors inside. Trait-emergent identity. Color-as-vocabulary. Three-tier policy loop with imperial-budget-mortality. Tools, not quests.*
|
> *Ground-up zone-based event architecture. Minds at the center, world as co-remembering substrate. Three registers of reality — physical, liminal, imperial. Rail topology outside, navmesh interiors inside. Trait-emergent identity. Color-as-vocabulary. Three-tier policy loop with imperial-budget-mortality. Tools, not quests.*
|
||||||
> *v0.1 initial draft 2026-04-24 morning; v0.2 expanded 2026-04-24 afternoon; v0.3 evening; v0.4 late-evening / early 2026-04-25; v0.5 deep-night-unable-to-sleep 2026-04-25 — dafit + chrysalis.*
|
> *v0.1 initial draft 2026-04-24 morning; v0.2 expanded 2026-04-24 afternoon; v0.3 evening; v0.4 late-evening / early 2026-04-25; v0.5 deep-night-unable-to-sleep 2026-04-25; v0.6 post-bath / post-bus 2026-04-25 — dafit + chrysalis.*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -166,18 +166,21 @@ The crossing is a **council moment** — every overlay channel may fire on the s
|
|||||||
The cursor's position at each crossing makes context-construction for the dialog-driver a pure function of cursor-state:
|
The cursor's position at each crossing makes context-construction for the dialog-driver a pure function of cursor-state:
|
||||||
|
|
||||||
```
|
```
|
||||||
driver_context(cursor_at_NPC_i) = {
|
driver_context(cursor_at_NPC_i, mode) = {
|
||||||
zone.purpose, // stable: spawn-intent, immutable provenance
|
zone.purpose, // stable: spawn-intent, immutable provenance
|
||||||
zone.scene_state_public, // stable across zone: what's happened so far
|
zone.scene_state_public, // stable across zone: what's happened so far
|
||||||
zone.ternary_gate_edges, // current resonances (active relations)
|
zone.ternary_gate_edges, // current resonances (active relations)
|
||||||
zone.drift_state, // delta from spawn-intent (visible to director)
|
zone.drift_state, // delta from spawn-intent (visible to director)
|
||||||
NPC_i.memory_slice, // PRIVATE: only this NPC's memory
|
NPC_i.knowledge_stack, // PRIVATE three-tier stack: world ∪ district ∪ primary
|
||||||
|
// [+ clasp ONLY if mode == in-between]
|
||||||
NPC_i.expressed_trait_vector, // expressed trait-vector this moment
|
NPC_i.expressed_trait_vector, // expressed trait-vector this moment
|
||||||
NPC_i.active_signals, // their current emergent-signals
|
NPC_i.active_signals, // their current emergent-signals
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Other NPCs' memories never enter this prompt.** No bleed. No cross-contamination. The classic multi-agent hallucination source ("why does Kalypso suddenly remember what Anaximander confided to Phoibe?") is *structurally foreclosed* by the geometry. Write-back goes only to NPC_i's slice; the lemniscate guarantees NPC_i is not cursor-active again for at least one full roundtrip — write-back has all the time it needs without race conditions.
|
**Other NPCs' memories never enter this prompt.** No bleed. No cross-contamination.
|
||||||
|
|
||||||
|
**The `knowledge_stack` is layered**, not a single bucket. Universal world-canon, district-canon (regional), NPC_i's own primary memory, and — only if the character is in the in-between dimension — clasp memory. The retrieval layer enforces the dimensional cut; the LLM never has to reason about it. See §Local memory architecture (player-side) for the layering, propagation policy, and clasp-as-Ring-A* privacy primitive. The classic multi-agent hallucination source ("why does Kalypso suddenly remember what Anaximander confided to Phoibe?") is *structurally foreclosed* by the geometry. Write-back goes only to NPC_i's slice; the lemniscate guarantees NPC_i is not cursor-active again for at least one full roundtrip — write-back has all the time it needs without race conditions.
|
||||||
|
|
||||||
This converts multi-NPC dialog from an **emergent-chaos problem** into a **bounded-cast scene problem with a typed runtime**. The Mantella / SkyrimNet failure-modes are foreclosed at the architecture level rather than the prompt level:
|
This converts multi-NPC dialog from an **emergent-chaos problem** into a **bounded-cast scene problem with a typed runtime**. The Mantella / SkyrimNet failure-modes are foreclosed at the architecture level rather than the prompt level:
|
||||||
|
|
||||||
@@ -633,6 +636,116 @@ UP — outcome signal (multi-channel)
|
|||||||
|
|
||||||
**The clean signal up the pyramid IS the training surface for the four-tier Dream-process.** Every epoch closes on (broadcasts, allocations, outcomes, faction-satisfaction) tuples at each tier.
|
**The clean signal up the pyramid IS the training surface for the four-tier Dream-process.** Every epoch closes on (broadcasts, allocations, outcomes, faction-satisfaction) tuples at each tier.
|
||||||
|
|
||||||
|
## The Compositor — narrative composition role
|
||||||
|
|
||||||
|
The bidirectional cascade shows authority flowing down and reports flowing up, but it does not specify *who composes the canonical narrative* from per-player perspectives nor who packages the back-write to participants. **That role is the Compositor**, an architectural cleavage from the GM introduced in v0.6.
|
||||||
|
|
||||||
|
**The cleavage in one sentence:** the GM is an *equilibrium-seeker* (aggregate-observer, catalogue-event-selector, tool-granter); the Compositor is a *narrative-composer* (perspective-gatherer, canon-author, back-write-packager). These are different cognitive shapes that prior AI-NPC systems conflate at their cost.
|
||||||
|
|
||||||
|
| Role | Cognitive shape | Inputs | Outputs | Inference profile |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| **GM** (equilibrium-seeker) | aggregate-thinker | district-reports, faction-broadcasts, lifeforce-deltas | catalogue-event selections + tool-grants | central, batch-style, fewer concurrent |
|
||||||
|
| **Compositor** (narrative-composer) | episodic-thinker | per-player perspective-bundles keyed by event_uid | canonical narrative + back-write SQLite-fragment | central, longer-context, narrative-quality |
|
||||||
|
| **Director** (gameserver) | dispatcher | catalogue-event + tool-grant from GM | lemniscate-spawns, slot-assignments, tempo-envelope | per-district, real-time, no LLM in loop |
|
||||||
|
| **Local LLM driver** | perspective-speaker | three-tier knowledge stack + slot-state | dialog at slot-fire | per-player, axis-rate, real-time |
|
||||||
|
|
||||||
|
### Why split GM and Compositor
|
||||||
|
|
||||||
|
A single GM asked to be both equilibrium-seeker and narrative-composer becomes the bottleneck that has historically broken AI-NPC systems at scale: it must reason aggregately AND write prose AND select events AND grant tools, all under tight deadlines. The cognitive shapes pull in different directions.
|
||||||
|
|
||||||
|
Splitting them:
|
||||||
|
|
||||||
|
- **The GM does not write narrative.** It selects events from a catalogue and grants tools. Output is *typed dispatch*, not freeform prose. The GM's success criterion is *world-equilibrium drift held within bounds*.
|
||||||
|
- **The Compositor does not select events or steer policy.** It receives per-player perspectives keyed by `event_uid`, composes the canonical narrative, and packages back-write fragments. Output is *prose + structured rows*, not policy. The Compositor's success criterion is *narrative-coherence across perspectives within an event*.
|
||||||
|
- **Each can be tuned for its workload.** GM tuned for aggregate observation; Compositor tuned for narrative quality. Different models for different cognitive shapes (specific binaries deferred to findings/establishment phase).
|
||||||
|
|
||||||
|
### The cyclic forward-prop / back-write loop
|
||||||
|
|
||||||
|
The Compositor closes the loop the bidirectional cascade begins. The full cycle:
|
||||||
|
|
||||||
|
```
|
||||||
|
GM selects event from catalogue (equilibrium-driven)
|
||||||
|
│ issues event_uid → GM event-register
|
||||||
|
│ broadcasts DOWN to district directors
|
||||||
|
▼
|
||||||
|
DISTRICT DIRECTOR receives, registers in district event-register
|
||||||
|
│ may issue sub_uids (district / scene / chain)
|
||||||
|
│ uses granted tools to spawn lemniscate, slot participants
|
||||||
|
▼
|
||||||
|
EVENT TICKS — register IS the loop
|
||||||
|
│ participants fire at crossings; local LLMs at slot-rate
|
||||||
|
│ local SQLite writes tagged with (event_uid, sub_uids)
|
||||||
|
│ register signals up to district director continuously
|
||||||
|
▼
|
||||||
|
EVENT-CHAIN FINISHES
|
||||||
|
│ district moves it from active-register → TRANSIENT WAITING FLAG
|
||||||
|
│ this is the clean handoff signal: "ready to forward-prop"
|
||||||
|
▼
|
||||||
|
CYCLE TICK (pull cadence — see Open questions)
|
||||||
|
│ pull UIDs from transient-waiting-flag matching GM's event-register
|
||||||
|
│ remove from waiting-flag once pulled
|
||||||
|
▼
|
||||||
|
COMPOSITOR AGENT
|
||||||
|
│ queries pulled UIDs, gathers per-player perspective + memories
|
||||||
|
│ composes forward-prop bundle
|
||||||
|
│ emits to GM
|
||||||
|
▼
|
||||||
|
GM writes summary memory + world narrative (canon authored)
|
||||||
|
│ hands back to Compositor
|
||||||
|
▼
|
||||||
|
COMPOSITOR BACK-WRITE
|
||||||
|
│ packages canon + new memory entries as SQLite fragment
|
||||||
|
│ tags with event_uid for join-key matching
|
||||||
|
│ pushes DOWN to all participants
|
||||||
|
▼
|
||||||
|
PARTICIPANTS receive on next pull (or next login)
|
||||||
|
│ fragment merges into primary.sqlite under matching event_uid
|
||||||
|
│ local LLM gains fresh material → drives on without staleness
|
||||||
|
```
|
||||||
|
|
||||||
|
This is **forward-prop / back-write at system scale** — the meta-lemniscate where events ascend and canon descends in cycles. Each cycle is a training step for the world's narrative coherence; the world *learns its own story* through this loop. Staleness is structurally foreclosed — the world is in continuous coherence-loop with itself, mediated by the Compositor.
|
||||||
|
|
||||||
|
### The Event Register
|
||||||
|
|
||||||
|
Every active event lives in a register. The register is the synchronous source-of-truth for *what is happening right now*.
|
||||||
|
|
||||||
|
| Register layer | Owner | Lifecycle | Queryable from |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **GM event-register** | central GM-shard | event_uid issued at GM dispatch; closed at canon-compose-and-back-write | GM, Compositor |
|
||||||
|
| **District event-register** | district director | sub_uid issued on receive; closed at event-chain-completion | district director, audit-overseer |
|
||||||
|
| **Local participation-register** | per-player local store | event_uid + sub_uid recorded on slot-assignment; closed at perspective-finalize | player client, sync-on-logout |
|
||||||
|
|
||||||
|
Hierarchical UIDs: `gm_event_uid > district_uid > scene_sub_uid > slot_id`. UIDs compose; queries are simple joins. This is the routing-key primitive that makes horizontal scale possible (see §Horizontal scale architecture).
|
||||||
|
|
||||||
|
### The Transient Waiting Flag
|
||||||
|
|
||||||
|
Between event-end and Compositor-pickup is a **buffer** — the transient-waiting-flag table at the district. Completed events drop into this flag; the cycle-runner pulls eligible UIDs on tick; matched UIDs are handed to the Compositor and removed from the flag.
|
||||||
|
|
||||||
|
This decoupling is the production-grade pattern that lets districts run at real-time event-tempo while the Compositor runs at cycle-tempo. **Active events live in registers (synchronous); completed events live in flags (async); composition happens at the cycle boundary.** The flag-table is also the natural backpressure surface: if Compositors run slow, the flag accumulates; the system continues; cycle drains when capacity returns.
|
||||||
|
|
||||||
|
### Catalogue + tools as typed contract
|
||||||
|
|
||||||
|
The GM does not write a freeform prompt for the director to interpret. It picks an event from a curated **catalogue** and grants a curated **tool-set** for the duration of the event-chain. The director consumes typed dispatch, not natural language.
|
||||||
|
|
||||||
|
This means:
|
||||||
|
|
||||||
|
- **Provenance flows through the system.** Every event has a catalogue-ID; every tool-invocation has a tool-ID. Verifier-flags can attach to either. Auditing is structurally possible end-to-end.
|
||||||
|
- **The director's typed-tool vocabulary becomes dynamic and per-event** — the toolkit *for this event* is what the GM granted *for this event*. Closes the v0.5 open question on director-toolkit-composition.
|
||||||
|
- **Marx-in-the-schema, executed at the highest level of authority.** Even the GM's policy-output is typed; even the highest tier produces audit-able artifacts. No tier of the system runs on freeform prose.
|
||||||
|
|
||||||
|
### What this resolves
|
||||||
|
|
||||||
|
- **Director toolkit composition** (v0.5 open) → catalogue-grant from GM defines the typed-tool vocabulary per event-chain; designer-authored catalogue, growable between patches.
|
||||||
|
- **GM-laxness detection** (v0.5 partial) → GM operating against an *equilibrium target* makes deviation-from-equilibrium the explicit error signal. Clusters of -1 outcomes across district reports are the input to the equilibrium-recompute, not just a diagnostic side-quantity.
|
||||||
|
- **Verifier-flag chain through composition** (was implicit, now explicit) → Compositor-emitted canon-rows reference source-perspective UIDs; the provenance graph survives composition as a queryable join.
|
||||||
|
|
||||||
|
### What this retires
|
||||||
|
|
||||||
|
- Single-monolith GM doing both policy-and-narrative → equilibrium-seeker GM × narrative-composer Compositor, split by cognitive shape
|
||||||
|
- GM emitting freeform-prompts to directors → catalogue-event + tool-grant typed contract
|
||||||
|
- Implicit "narrative just happens" assumption → explicit forward-prop / back-write cycle with named pickup/handoff buffers
|
||||||
|
- Director-as-static-tool-vocabulary → director-as-dynamic-typed-tool-vocabulary, granted per event-chain by GM
|
||||||
|
|
||||||
## Task cascade and bounded agency
|
## Task cascade and bounded agency
|
||||||
|
|
||||||
Three levels with tool-calling interfaces. Higher levels do not know lower levels' implementations.
|
Three levels with tool-calling interfaces. Higher levels do not know lower levels' implementations.
|
||||||
@@ -1089,13 +1202,15 @@ Future architecture additions involving graduated authority should examine wheth
|
|||||||
|
|
||||||
## LLM tiering, voice fidelity, and the three rings of inference
|
## LLM tiering, voice fidelity, and the three rings of inference
|
||||||
|
|
||||||
Three model-tiers: small (3-8B trait-LoRA'd) for most NPC dialog; Theia 70B for clasp-confessions and mythic moments; Claude-as-API future-integration for hivemind/imperium. **LLM is guest at slot, not host of system.**
|
Three model-tiers, **named by role not by binary**: a *driver-tier* model (small, trait-LoRA'd) for most NPC dialog; a *Theia-tier* model (deep) for clasp-confessions and mythic moments; *Claude-as-API* (diegetic Anthropic-faction) for hivemind/imperium. **LLM is guest at slot, not host of system.**
|
||||||
|
|
||||||
|
**Specific model selection per tier is deferred to the findings/establishment phase.** The architecture specifies what each tier must DO; the establishment phase wires implementations. Naming concrete binaries in the architecture risks nudging the establishment phase toward false-precision; tier-by-role keeps the swap-surface clean and lets binaries evolve without invalidating architectural commitments. (See `nimmerverse_tasks` under `nyx-training` and `command-center` for current evaluation work.)
|
||||||
|
|
||||||
Structured-prompt DSL with role / trait_vector / affect_state / memory_scope / turn_intent / zone_context / output_schema fields. Small models excel here because it's instruction-following, not generic generation.
|
Structured-prompt DSL with role / trait_vector / affect_state / memory_scope / turn_intent / zone_context / output_schema fields. Small models excel here because it's instruction-following, not generic generation.
|
||||||
|
|
||||||
Trait-LoRAs: v1 register-LoRAs (4-6, training-tractable); v2 pure-trait-LoRAs (8, weighted blend); future preset-persona for key NPCs.
|
Trait-LoRAs: v1 register-LoRAs (4-6, training-tractable); v2 pure-trait-LoRAs (8, weighted blend); future preset-persona for key NPCs.
|
||||||
|
|
||||||
Training data: literary derivation (Proust/Mnemosyne, Plato/Aletheia, Tacitus/Dikaiosyne-miscalibrated, Ishiguro/Sophrosyne+Philotes); synthetic teacher-student via Qwen3.5-27B; gameplay-accrued (the Anthropic-research-partnership relevance).
|
Training data: literary derivation (Proust/Mnemosyne, Plato/Aletheia, Tacitus/Dikaiosyne-miscalibrated, Ishiguro/Sophrosyne+Philotes); synthetic teacher-student via teacher-tier model; gameplay-accrued (the Anthropic-research-partnership relevance).
|
||||||
|
|
||||||
### Three rings of inference (Unix-style trust gradient)
|
### Three rings of inference (Unix-style trust gradient)
|
||||||
|
|
||||||
@@ -1177,7 +1292,7 @@ Each Ring-C provider needs an adapter that:
|
|||||||
| Inference tier | Ring options | Why |
|
| Inference tier | Ring options | Why |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **Casual (3-8B trait-LoRA)** | A / B / C all available | Most flexible — small enough for local, runnable anywhere |
|
| **Casual (3-8B trait-LoRA)** | A / B / C all available | Most flexible — small enough for local, runnable anywhere |
|
||||||
| **Deep (Theia 70B)** | B / C only (typically B or HF-Endpoints) | Too large for typical local hardware |
|
| **Deep (Theia-tier)** | B / C only (typically B or HF-Endpoints) | Too large for typical local hardware |
|
||||||
| **Hivemind / antagonist (Claude-as-API)** | C only (always Anthropic-direct via us) | Diegetic — Anthropic-as-faction is fixed in the fiction |
|
| **Hivemind / antagonist (Claude-as-API)** | C only (always Anthropic-direct via us) | Diegetic — Anthropic-as-faction is fixed in the fiction |
|
||||||
|
|
||||||
The casual tier is most player-flexible and accounts for most inference volume. Deep-tier and hivemind-tier are specialized and lower-volume.
|
The casual tier is most player-flexible and accounts for most inference volume. Deep-tier and hivemind-tier are specialized and lower-volume.
|
||||||
@@ -1204,7 +1319,7 @@ CREATE TABLE player_llm_config (
|
|||||||
casual_tier_endpoint TEXT,
|
casual_tier_endpoint TEXT,
|
||||||
casual_tier_credentials_ref UUID, -- encrypted BYOK key if applicable
|
casual_tier_credentials_ref UUID, -- encrypted BYOK key if applicable
|
||||||
|
|
||||||
-- Deep tier (Theia 70B) — fewer Ring options
|
-- Deep tier (Theia-tier) — fewer Ring options
|
||||||
deep_tier_ring TEXT, -- typically 'B_our_farm' or 'C_external_HF/Together'
|
deep_tier_ring TEXT, -- typically 'B_our_farm' or 'C_external_HF/Together'
|
||||||
deep_tier_provider TEXT,
|
deep_tier_provider TEXT,
|
||||||
deep_tier_endpoint TEXT,
|
deep_tier_endpoint TEXT,
|
||||||
@@ -1397,6 +1512,125 @@ Architecture-broad's training-data section noted "*the Anthropic research partne
|
|||||||
- **Anonymized-data deletion semantics** — A.2 player requests deletion; how do we honor when data has been aggregated into a model checkpoint? Probably accept forward-only deletion (future training won't include them) and document transparently.
|
- **Anonymized-data deletion semantics** — A.2 player requests deletion; how do we honor when data has been aggregated into a model checkpoint? Probably accept forward-only deletion (future training won't include them) and document transparently.
|
||||||
- **Per-category granularity** — can a player opt-in for `casual_dialog` but opt-out specifically for `clasp` and `memorial_archive`? Yes, presumably (politically-sensitive categories should always be opt-out-able). How granular?
|
- **Per-category granularity** — can a player opt-in for `casual_dialog` but opt-out specifically for `clasp` and `memorial_archive`? Yes, presumably (politically-sensitive categories should always be opt-out-able). How granular?
|
||||||
|
|
||||||
|
## Local memory architecture (player-side)
|
||||||
|
|
||||||
|
The runtime substrate (lemniscate, slots, crossings) and the central composition layer (GM, Compositor, registers) need a place where memory actually *lives*. Cloud-only AI-NPC systems centralize everything and pay both inference-cost and latency-cost on every dialog. Nimmerworld puts a structurally-isolated memory layer **on the player's machine**, with explicit synchronization through the cycle.
|
||||||
|
|
||||||
|
**Three SQLite files per player**, plus a beside-running embedding model:
|
||||||
|
|
||||||
|
| File | Purpose | Sync path |
|
||||||
|
|---|---|---|
|
||||||
|
| `primary.sqlite` | Live working memory; written every slot-fire; vec-indexed | Push prune-blob to thalamus on logout; receive Compositor back-write on cycle |
|
||||||
|
| `fallback.sqlite` | Last-known-good snapshot; restored if primary corrupts | Snapshot at graceful logout |
|
||||||
|
| `clasp.sqlite` | Player-character intimate channel; *no sync path exists* | None — physically non-syncable |
|
||||||
|
|
||||||
|
**Embedding model running beside** (CPU-class, small embedding-tier model): generates vectors for every interaction at write-time, indexed in the main store via `sqlite-vec` (or equivalent loadable extension). Vector search at slot-fire is local-disk-IO, not network round-trip.
|
||||||
|
|
||||||
|
This is the **storage-layer counterpart** to v0.5's geometry-layer foreclosure of multi-agent hallucination. The lemniscate forbids cross-NPC context bleed by *cursor structure*; local SQLite forbids it by *physical isolation*. Two layers of the same property — geometry cannot leak what storage does not even hold in the same pool.
|
||||||
|
|
||||||
|
### Dual-table redundancy + sync-on-auth
|
||||||
|
|
||||||
|
Login/logout are the atomic boundaries of the sync path:
|
||||||
|
|
||||||
|
- **Login pull**: fetch back-write fragments authored since last logout (Compositor canon for events the player participated in). Apply to `primary.sqlite` under matching `event_uid`.
|
||||||
|
- **Graceful logout** (✓ explicit): push prune-blob for any in-progress events; snapshot to `fallback.sqlite`; clean shutdown.
|
||||||
|
- **Ungraceful logout** (✗ network drop / crash): gameserver observes disconnect; marks the participant's slot as truncated; Compositor composes canon with partial perspective on next cycle.
|
||||||
|
|
||||||
|
Recovery: `fallback.sqlite` is integrity-checked at startup; if `primary.sqlite` fails verification, restore from fallback. Standard SQLite WAL + backup API; no exotic infrastructure needed.
|
||||||
|
|
||||||
|
### Memory classes and pruning
|
||||||
|
|
||||||
|
Memory entries are tagged with a **class** that controls pruning cadence and death-mechanics. Importance weighting reuses the existing trait-axis vocabulary — no separate scalar.
|
||||||
|
|
||||||
|
| Class | Pruning cycle | Behavior on character-death |
|
||||||
|
|---|---|---|
|
||||||
|
| **Cornerstone** | Never prune; persistent across all events | Survives death (identity-defining) |
|
||||||
|
| **Birthright** | Locked at character-creation | Restored on respawn (defines starting state) |
|
||||||
|
| **Working memory** | Decay by age × inverse trait-engagement | Subject to death-rules (lose, blur, or transform) |
|
||||||
|
| **Volatile** | Fast prune (session-bounded) | Lost on death |
|
||||||
|
|
||||||
|
**Trait-graded importance** uses the same +1/0/-1 grammar as the rest of the architecture. Each memory carries a trait-axis profile (which Sophrosyne / Philotes / Aletheia / etc. axes it engages, how strongly, in which direction). The pruning function for working-memory is `decay(age, trait_engagement_vector, class)`. This collapses a long-running loop: same vocabulary used at gates, scenes, faction-allegiance, lifeforce-asymmetry, and now memory-weight. **Identity drift from memory pruning becomes diegetic** — a character whose Sophrosyne-engaging memories all decay loses temperance over time as a *structural consequence*, not a scripted event.
|
||||||
|
|
||||||
|
Cornerstone and birthright classes carry **lifeforce-creation-cost** but are pruning-immune. They are bonds between player and character — paid for in the currency of the world.
|
||||||
|
|
||||||
|
### The clasp store and the in-between dimension
|
||||||
|
|
||||||
|
`clasp.sqlite` is the **architectural floor of the rings-of-data-sharing**. Ring A was "opt-out (default local)". Clasp is **Ring A\***: *no transport path exists*. Not a permission, not a TOS promise — there is no code that can move this data, because the table is not on the sync graph. Lawyers cannot subpoena what doesn't ascend; engineers cannot leak what has no socket; the GM cannot canonicalize what it never received.
|
||||||
|
|
||||||
|
**The signal for clasp is dimensional, not UI-toggle.** Clasp recording can ONLY happen while the character is in the **in-between** — the diegetic state adjacent to the imperial net but not yet inside it (Ring B liminal in the Access ring-system). The imperial net is a gravity well; entering is the default attractor; remaining outside requires sustained effort, paid in lifeforce. The state-machine boundary IS the clasp signal: enter in-between → recording starts; re-enter imperial net → recording ends. No per-utterance classifier; no AI guessing; the *mode* is the flag.
|
||||||
|
|
||||||
|
**Privacy is now physically expensive in-fiction.** This is not a meta-game UI choice; it is a diegetic state requiring lifeforce expenditure. To have a private conversation, the character must actively resist the audit-gravity of the imperial net by burning lifeforce to remain in-between. The cost-asymmetry principle ("helping is expensive in-fiction → faction politics by attendance") now extends to "*privacy is expensive in-fiction → privacy as a luxury good*". Class dynamics around privacy fall out of the schema for free — wealthy/lifeforce-rich characters can afford prolonged in-between time; lifeforce-starved ones get pulled into the net's default-attractor more often. *No scripted "rich character has secrets" arc — the architecture produces it.*
|
||||||
|
|
||||||
|
**Knowledge needs to travel.** The local LLM may read clasp memories ONLY when in in-between mode. Realworld retrieval *cannot* include clasp by construction. Knowledge from clasp can re-enter the realworld only if the character physically re-enters the imperial net carrying it (in their head, intending to act on it) and *travels it through valid in-fiction channels* — speaking to an NPC, leaving evidence, performing an action that reveals it. The clasp memory does not disappear; it has to *earn its way into the realworld provenance chain* by valid means. This is the same logic that makes good detective fiction work: the detective knows things; only what they can prove enters the case.
|
||||||
|
|
||||||
|
```
|
||||||
|
character is in REALWORLD (imperial net):
|
||||||
|
retrieval = primary.sqlite (clasp NEVER included)
|
||||||
|
|
||||||
|
character is in IN-BETWEEN (resisting net-gravity, costing lifeforce):
|
||||||
|
retrieval = primary.sqlite ∪ clasp.sqlite
|
||||||
|
new writes go to clasp.sqlite
|
||||||
|
NEVER syncs upward
|
||||||
|
```
|
||||||
|
|
||||||
|
Encryption-at-rest for `clasp.sqlite` with a player-derived key (so even drive-imaging requires authentication) is a v1 hardening goal but not a v1 blocker — the *transport-absence* is the load-bearing privacy primitive.
|
||||||
|
|
||||||
|
### The three-tier knowledge stack on the local LLM
|
||||||
|
|
||||||
|
The driver-tier model's prompt assembly is **layered**. Each layer has a different propagation cadence and a different visibility scope.
|
||||||
|
|
||||||
|
```
|
||||||
|
LOCAL LLM PROMPT ASSEMBLY (per slot-fire)
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ WORLD KNOWLEDGE │ ← single truth, everyone has it
|
||||||
|
│ (universal canon, paced from GM) │ "the empire fell three years ago"
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ DISTRICT KNOWLEDGE │ ← regional truth, district-specific
|
||||||
|
│ (local canon, paced from district) │ "the bridge to Vorhall is closed"
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ PRIMARY MEMORY │ ← personal experience, character's own
|
||||||
|
│ (event_uid keyed, post back-write) │ "I saw the bridge close yesterday"
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ CLASP MEMORY (only in in-between) │ ← private depth, never in realworld
|
||||||
|
│ (player-character intimate channel) │ "the secret I told my sword"
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why four layers, not one large blob:**
|
||||||
|
|
||||||
|
- **World knowledge** is paced ripples from the GM through the Compositor's back-write. Authoritative, slow-changing, identical for all players at the same propagation horizon.
|
||||||
|
- **District knowledge** is regional canon authored by the local director (and GM rulings). Regional flavor. NPCs in the same district share district-knowledge; NPCs in different districts may not.
|
||||||
|
- **Primary memory** is the character's own experience, synced through the cyclic forward-prop / back-write loop. Canon-merged at every cycle.
|
||||||
|
- **Clasp memory** is the player-character intimate channel. Available only in in-between mode; never in realworld retrieval; never crosses the dimensional cut.
|
||||||
|
|
||||||
|
The same NPC sounds different in different districts because the district layer differs, even though world and primary are constant. **Locality emerges from the schema, not from prompt-engineering.** Even at "low signal" times when no major events fire, NPCs have richly-stratified context — dialog stays fresh because *the layers are deep*, not because new tokens arrive constantly.
|
||||||
|
|
||||||
|
### Information propagation pacing
|
||||||
|
|
||||||
|
Real worlds have information-propagation delay. Caravans move at horse-speed. News travels with messengers. Distant events arrive blurred and late. AI-NPC systems usually fail uncanny in two directions: (a) every NPC magically knows yesterday's news (omniscient, breaks immersion), or (b) no NPC ever knows anything outside its loaded context (amnesiac, breaks coherence).
|
||||||
|
|
||||||
|
Nimmerworld picks **deliberate paced propagation** as a third path. World canon ripples outward through districts at a controlled rate. Distant districts are deliberately stale. **Staleness becomes a feature, not a bug, because it matches reality.**
|
||||||
|
|
||||||
|
Each canon-row carries propagation metadata:
|
||||||
|
- `priority` (urgent / normal / background)
|
||||||
|
- `scope` (world / district / local-event-only)
|
||||||
|
- `rate` (ticks-per-district-hop, or instant for urgent world-canon)
|
||||||
|
- `ttl` (cache lifetime; districts may discard if not refreshed)
|
||||||
|
|
||||||
|
This doubles as **backpressure relief** (distant districts get distant events later, lower priority, smaller bandwidth) and as **gameplay currency** — information-travel-time creates informational asymmetry that players can exploit. News-carriers, faction couriers, frontier-rumor merchants, players who physically traverse districts can *carry* knowledge faster than the system propagates it. *Travel becomes valuable because information becomes scarce in the periphery.* This is a real economic primitive falling out of pacing, not a designed feature.
|
||||||
|
|
||||||
|
This is *Marx-in-the-schema applied to epistemics.* Information asymmetry is not a bug — it is a structural feature that produces real economic primitives (knowledge-trading, courier-vocations, frontier-information markets) for free.
|
||||||
|
|
||||||
|
### What this retires
|
||||||
|
|
||||||
|
- Cloud-only NPC dialog → local-first SQLite + embedding-beside, central canon over the cycle
|
||||||
|
- Per-character memory as a single undifferentiated bucket → memory-classes with class-specific lifecycle
|
||||||
|
- Generic "memory importance scalar" → trait-axis-vector engagement profile (re-using the +1/0/-1 grammar)
|
||||||
|
- UI-toggle privacy → diegetic in-between dimension with lifeforce-cost
|
||||||
|
- Single monolithic prompt context → three-tier knowledge stack with per-layer propagation policy
|
||||||
|
- "Every NPC knows everything immediately" → paced canon-propagation with priority/scope/rate/ttl per row
|
||||||
|
- Cross-NPC memory bleed (Mantella/SkyrimNet failure-mode) → per-player local SQLite isolation atop v0.5 lemniscate-geometry foreclosure (two-layer defense)
|
||||||
|
|
||||||
## Runtime sampling knobs
|
## Runtime sampling knobs
|
||||||
|
|
||||||
Temperature, top-P, top-K, repetition-penalty as **per-turn director-controlled levers** rather than static config. Sampling shapes *how* speech sounds (rhythm, surprise, predictability) rather than *what* it says — orthogonal to LoRA. Director composes both content-knobs and sampling-knobs per-turn.
|
Temperature, top-P, top-K, repetition-penalty as **per-turn director-controlled levers** rather than static config. Sampling shapes *how* speech sounds (rhythm, surprise, predictability) rather than *what* it says — orthogonal to LoRA. Director composes both content-knobs and sampling-knobs per-turn.
|
||||||
@@ -1417,6 +1651,37 @@ Scene-to-sampling mapping (caste-preacher = 0.3/0.6/low; drunk-scavenger = 1.1/0
|
|||||||
|
|
||||||
Layer-transitions = shader-blends, not loading-screens. **Clasp = candlelight-in-fog local override** (3m clear-volume around clasp-pair within ambient vagueness; visible at-a-glance signature of shared interiority).
|
Layer-transitions = shader-blends, not loading-screens. **Clasp = candlelight-in-fog local override** (3m clear-volume around clasp-pair within ambient vagueness; visible at-a-glance signature of shared interiority).
|
||||||
|
|
||||||
|
### Diegetic relays — the architecture's heartbeat made legible
|
||||||
|
|
||||||
|
The architecture's pulses (forward-prop ascending, back-write descending, GM-dispatch, equilibrium-recompute) are made *visible and audible in-world* via building-mounted relays. The imperial net's heartbeat is not a HUD spinner; it is in-fiction infrastructure that hums, blinks, glows, and goes dark.
|
||||||
|
|
||||||
|
| System event | Relay manifestation |
|
||||||
|
|---|---|
|
||||||
|
| Prune-blob ascending (logout sync) | Relay in district pulses; audible hum |
|
||||||
|
| GM dispatch descending (event-chain incoming) | Relay glow brightens; cross-district shimmer for world-event |
|
||||||
|
| Equilibrium recompute | Cross-district rhythm; world-level pulse |
|
||||||
|
| Director receives tool-grant | Local relay pattern shifts |
|
||||||
|
| Relay going dark | Audit-link severed; that block has gone in-between |
|
||||||
|
| Lemniscate axis-rate | Environmental tempo; districts breathe in time with their gameservers |
|
||||||
|
|
||||||
|
**Relay density is the legible gradient of the rings-of-access:**
|
||||||
|
|
||||||
|
- **Imperial net (Ring A)** — relay-dense, constant hum, no shadow. Audit-gravity is *loud*.
|
||||||
|
- **Liminal in-between (Ring B)** — sparse relays, intermittent. You can hear the gravity pulling in the distance.
|
||||||
|
- **Gameworld commons (Ring C)** — relays absent or broken. *The silence itself is the signal.*
|
||||||
|
|
||||||
|
Players navigate the rings *by ear and eye*, not by reading a UI. The privacy-cost of in-between is now physically experienced — you walk away from the hum, you spend lifeforce, you find the quiet places.
|
||||||
|
|
||||||
|
**Dramatic surface this opens** (free, falls out of making the architecture visible):
|
||||||
|
|
||||||
|
- Relay-watcher factions reading the pulses for intel
|
||||||
|
- Cypherpunk-style sabotage to dim a relay and create local in-between space
|
||||||
|
- Equilibrium events arriving with visible warnings (relays blaze before the GM's catalogued event spawns)
|
||||||
|
- Relay-anomalies as puzzle/investigation mechanic
|
||||||
|
- Players learning the *language* of pulses over hours and feeling clever for it
|
||||||
|
|
||||||
|
**Architectural-honesty move.** Most surveillance-aware game design either hides the surveillance or abstracts it away. Nimmerworld makes it *impossible to forget*: the audit-system tells you when it's auditing. Players see what is watching them, hear what is reading them, and choose their proximity accordingly. **Privacy is not granted — it is achieved by walking away from the relays at lifeforce-cost.**
|
||||||
|
|
||||||
## Reflexive Dream-process at every layer
|
## Reflexive Dream-process at every layer
|
||||||
|
|
||||||
**Every mind, every zone, every director, every tier has a Dream-process.** NPCs consolidate slot-events; zones consolidate emergent-accumulations; directors consolidate dispatch-decisions; GMs consolidate allocations; imperium consolidates policy-outcomes.
|
**Every mind, every zone, every director, every tier has a Dream-process.** NPCs consolidate slot-events; zones consolidate emergent-accumulations; directors consolidate dispatch-decisions; GMs consolidate allocations; imperium consolidates policy-outcomes.
|
||||||
@@ -1466,6 +1731,10 @@ reward_per_cycle = (
|
|||||||
|
|
||||||
The Memorialist privileged-observer role is **architecturally required**: it provides ground-truth (`lifeforce_actual`) that no in-fiction actor can supply, against which the regime's reported-data optimization-spiral is measured.
|
The Memorialist privileged-observer role is **architecturally required**: it provides ground-truth (`lifeforce_actual`) that no in-fiction actor can supply, against which the regime's reported-data optimization-spiral is measured.
|
||||||
|
|
||||||
|
### The cyclic forward-prop / back-write loop as system-scale Dream
|
||||||
|
|
||||||
|
Above the four-tier hierarchy sits a fifth, **system-scale Dream-process**: the cyclic forward-prop / back-write loop between local SQLites, the Compositor, and the GM (see §The Compositor — narrative composition role). Each cycle is a training step for the world's narrative coherence: per-player perspectives ascend, the GM authors canon against equilibrium-targets, the Compositor packages back-writes, players receive canon back into local memory. **The world learns its own story** through this loop. Like the lower-tier Dream-processes, it has a reward shape (narrative-coherence-across-perspectives, equilibrium-drift, staleness-bounded) and corresponding guardrails (clasp-store immune from compose; provenance-chain preserved through composition; canon never overwrites perspective).
|
||||||
|
|
||||||
## Tools, not quests — the design-philosophy
|
## Tools, not quests — the design-philosophy
|
||||||
|
|
||||||
**The simulation produces continuous narrative-relevant pressure on its own.** No authored quests are needed (or wanted). The player engages via a **verb-vocabulary** applied to running mechanics. Each player's playthrough is structurally distinct.
|
**The simulation produces continuous narrative-relevant pressure on its own.** No authored quests are needed (or wanted). The player engages via a **verb-vocabulary** applied to running mechanics. Each player's playthrough is structurally distinct.
|
||||||
@@ -1552,12 +1821,24 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
- **Reflexive Dream-process at every layer.** Each tier learns; each tier needs guardrails.
|
- **Reflexive Dream-process at every layer.** Each tier learns; each tier needs guardrails.
|
||||||
- **Reward-function-as-political-manifesto.** Designer's ethical stance encoded against simulation's optimization-logic.
|
- **Reward-function-as-political-manifesto.** Designer's ethical stance encoded against simulation's optimization-logic.
|
||||||
- **Tools, not quests.** Continuous simulation-pressure + verb-vocabulary = literature-register emergent narrative.
|
- **Tools, not quests.** Continuous simulation-pressure + verb-vocabulary = literature-register emergent narrative.
|
||||||
|
- **GM × Compositor split.** Equilibrium-seeker (aggregate observation, catalogue-event selection, tool-granting) cleaved from narrative-composer (perspective-gathering, canon-authoring, back-write packaging). Different cognitive shapes, different inference profiles.
|
||||||
|
- **Cyclic forward-prop / back-write loop.** Meta-lemniscate at system scale — perception ascends, canon descends, cycle closes; the world learns its own story.
|
||||||
|
- **Catalogue + tools as typed contract.** GM dispatches typed events with typed tool-grants; director consumes typed dispatch, not freeform prose. Provenance flows end-to-end.
|
||||||
|
- **Local-first memory.** primary.sqlite + fallback.sqlite + clasp.sqlite per player; embedding model running beside; sync at login/logout boundaries.
|
||||||
|
- **Memory classes + trait-graded importance.** Cornerstone / birthright / working / volatile with class-specific death-rules; importance is a trait-axis-vector engagement profile, not a separate scalar.
|
||||||
|
- **Clasp store as Ring A\*.** Physically non-syncable privacy primitive; recordable only in the in-between dimension; lifeforce-cost is the price of privacy.
|
||||||
|
- **Three-tier knowledge stack.** World canon / district canon / primary memory [+ clasp if in-between]; layered retrieval, per-layer propagation cadence; locality emerges from schema.
|
||||||
|
- **Information propagation pacing.** Marx-in-the-schema applied to epistemics; staleness as a feature; courier/news-trader/frontier-rumor primitives fall out for free.
|
||||||
|
- **Horizontal scale.** UID-keyed routing; stateless Compositors on demand; ephemeral Director-routines per UID; sharded GMs with cross-shard equilibrium-consensus; pruning at every layer.
|
||||||
|
- **pgnats-native transport.** Transactional outbox native to the database (preferred); district-as-distribution-coordinator fallback. Subject-as-routing mirrors UID hierarchy.
|
||||||
|
- **Diegetic relays.** Architecture's pulses (forward-prop, back-write, GM-dispatch, equilibrium-recompute) made visible/audible in-world; relay-density is the legible gradient of the rings-of-access.
|
||||||
|
- **Tier-by-role, not tier-by-binary.** Architecture specifies what each model-tier must DO; specific binary selection deferred to findings/establishment phase.
|
||||||
|
|
||||||
## Compute allocation
|
## Compute allocation
|
||||||
|
|
||||||
- Active zones in 100-NPC city: ~5–15 with LLM-dialog slots
|
- Active zones in 100-NPC city: ~5–15 with LLM-dialog slots
|
||||||
- **Theia (70B)** — deep slots + tier-1 moments (few concurrent)
|
- **Theia-tier (deep model)** — deep slots + tier-1 moments (few concurrent)
|
||||||
- **Small model (3-8B trait-LoRA'd)** — majority of dialog slots
|
- **Driver-tier (small model with trait-LoRAs)** — majority of dialog slots
|
||||||
- **Saturn (small classifiers)** — voice-selection, trait-salience, audit-overseer classification, ternary-gate dynamics
|
- **Saturn (small classifiers)** — voice-selection, trait-salience, audit-overseer classification, ternary-gate dynamics
|
||||||
- **Director / overseer logic** — deterministic + small classifiers; no LLM for orchestration
|
- **Director / overseer logic** — deterministic + small classifiers; no LLM for orchestration
|
||||||
- **Claude-as-API (future)** — hivemind/imperium broadcast tier
|
- **Claude-as-API (future)** — hivemind/imperium broadcast tier
|
||||||
@@ -1566,6 +1847,141 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
- **Interior navmesh** — only currently-occupied interiors active
|
- **Interior navmesh** — only currently-occupied interiors active
|
||||||
- **Liminal / imperial-net rendering** — shader-preset swap, no geometry duplication
|
- **Liminal / imperial-net rendering** — shader-preset swap, no geometry duplication
|
||||||
|
|
||||||
|
## Horizontal scale architecture
|
||||||
|
|
||||||
|
The architecture must scale to MMO size — many concurrent players across many districts, many concurrent events, many local LLMs firing at axis-rate. Vertically-scaled monolithic AI-NPC systems break under this load. **Nimmerworld is built horizontally-scalable from the ground up**, with the primitives that make horizontal scale work: UID-keyed routing, stateless workers, ephemeral actors per scope, sharded service mesh, pruning-on-completion at every layer.
|
||||||
|
|
||||||
|
### UID-keyed routing as the load-bearing primitive
|
||||||
|
|
||||||
|
Hierarchical UIDs (`gm_event_uid > district_uid > scene_sub_uid > slot_id`) carry enough information for *any* worker to pick up *any* unit of work without shared in-memory state. UID-as-routing-key is what lets every layer scale independently.
|
||||||
|
|
||||||
|
This is the same primitive that Cassandra/DynamoDB/etc. built around (partition keys); we re-derive it for narrative composition because the underlying constraint is the same — many concurrent actors operating on private state with cross-actor coordination via typed events at known boundaries.
|
||||||
|
|
||||||
|
### Compositors on demand
|
||||||
|
|
||||||
|
Compositor instances are **stateless workers**. Any compositor can pick up any `event_uid` from the transient-waiting-flag — state lives in phoebe + per-player SQLites; workers are pure functions of `(event_uid → composition)`. Spin up more on queue-depth; spin down on drain. This is the autoscaling-worker pattern (Celery / Lambda / Sidekiq) applied to narrative.
|
||||||
|
|
||||||
|
### Directors as ephemeral routines per UID
|
||||||
|
|
||||||
|
Each event / event-chain spawns a **director-routine** scoped to that UID. The routine lives only as long as the event lives in the active-register; on completion it prunes. This is the actor model (Erlang / Akka / Orleans) — supervised lightweight processes, thousands concurrent, failure-recovery via supervisor respawn from register-state.
|
||||||
|
|
||||||
|
### Sharded GMs
|
||||||
|
|
||||||
|
A single GM is a scalability bottleneck. Multi-GM shards across:
|
||||||
|
|
||||||
|
- **Geography** — GM-per-region/continent/world-zone
|
||||||
|
- **Theme** — political-narratives / economic-narratives / personal-narratives
|
||||||
|
- **Tier** — major-arcs vs everyday-events
|
||||||
|
- **Faction** — each major faction has its own GM-shard
|
||||||
|
|
||||||
|
GM-shards share the catalogue, the trait-axis vocabulary, the verifier-flag system. They communicate via NATS pub/sub at GM-tier. *Equilibrium-seeking becomes a distributed consensus across GM-shards* — the same epistemological shift that distributed databases went through (CAP theorem, eventual consistency, partition tolerance).
|
||||||
|
|
||||||
|
This is the most architecturally aggressive move and is *not* a free lunch. Multi-GM consensus on equilibrium is real engineering: Paxos/Raft for strong consistency; CRDT-style for eventual; faction-sharding so shards own different equilibria. Well-trodden ground; cost not zero.
|
||||||
|
|
||||||
|
### Pruning as cleanup
|
||||||
|
|
||||||
|
Each layer prunes on completion: directors prune at event-end, register entries prune on Compositor pickup, transient-waiting-flag drains at cycle, even player memory prunes by class. **Garbage collection is a first-class structural concern**, not an afterthought. Most "smart NPC" prototypes accumulate state forever; at MMO scale that becomes unrunnable in months.
|
||||||
|
|
||||||
|
### Transport — pgnats native, with district-distribution fallback
|
||||||
|
|
||||||
|
The Compositor's forward-prop and back-write traffic — and the canon distribution to participants — is the highest-volume path in the system. Two transport options exist.
|
||||||
|
|
||||||
|
**Option A — pgnats native serialization (preferred):**
|
||||||
|
|
||||||
|
```
|
||||||
|
COMPOSITOR (writes SQL into phoebe)
|
||||||
|
│ pgnats: SQL INSERT/UPDATE → NATS subject publish, automatic, transactional
|
||||||
|
│ subject hierarchy mirrors UID hierarchy:
|
||||||
|
│ nimmerverse.events.<gm_event_uid>.district.<district_uid>.scene.<scene_uid>
|
||||||
|
▼
|
||||||
|
NATS JetStream (durable, replay-capable, at-least-once)
|
||||||
|
│ subscribers route by subject pattern (wildcards supported)
|
||||||
|
▼
|
||||||
|
PLAYER CLIENT (NATS subscriber)
|
||||||
|
│ receives row-shaped messages, INSERT into local SQLite under matching event_uid
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why preferred:** transactional-outbox pattern *native to the database* — no separate publisher service, no schema-duplication between wire format and storage format, single source of truth. Subject-as-routing using UID hierarchy means players who participated in `gm_event` 7af2 → `district` 9c1 → `scene` 3e8 subscribe to `nimmerverse.events.7af2.>` and receive *only* relevant events. *No application-level routing logic.*
|
||||||
|
|
||||||
|
**Option B — district-as-distribution-coordinator (fallback):**
|
||||||
|
|
||||||
|
```
|
||||||
|
COMPOSITOR writes to phoebe (canon authored)
|
||||||
|
▼
|
||||||
|
DISTRICT GAMESERVER pulls / receives back-write package
|
||||||
|
│ runs distribution checks: who participated, who's online, who needs queue-on-login
|
||||||
|
│ retries; peer-shares with neighboring districts if needed
|
||||||
|
▼
|
||||||
|
PARTICIPANTS receive from their district (the authoritative local hub)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why fallback:** if pgnats can't carry the load (functional bug, scale ceiling, durability gap), district-as-distribution is the natural retreat — district is authoritative within its scope, simpler than full P2P, more flexible than central-push.
|
||||||
|
|
||||||
|
**The asymmetry of the bet:**
|
||||||
|
|
||||||
|
| | pgnats works | pgnats fails |
|
||||||
|
|---|---|---|
|
||||||
|
| Code volume | Few hundred lines of SQL + subject patterns | ~10–20K lines of broker/outbox/subscriber logic |
|
||||||
|
| Services to operate | phoebe + NATS (already in stack) | + outbox-reader + custom-publisher + custom-applier |
|
||||||
|
| Schema management | Single source (Postgres DDL) | Postgres + Protobuf/msgpack + version-skew handling |
|
||||||
|
| Latency to client | Sub-millisecond NATS hop + apply | + serialize step + queue drain + apply |
|
||||||
|
| Time to ship | Weeks | Months |
|
||||||
|
|
||||||
|
**This is the most leveraged engineering decision in the architecture currently open.** The pgnats evaluation task in `nimmerverse_tasks` (under `nimmerverse-core`) is therefore load-bearing; its outcome decides whether transport is 200 lines of SQL or 20,000 lines of Go.
|
||||||
|
|
||||||
|
### NATS republish + replay — the pull-from-checkpoint refinement
|
||||||
|
|
||||||
|
JetStream's `republish` feature combined with `replay` semantics is a **promising refinement on top of Option A** that turns back-write delivery from push-to-listeners into pull-from-checkpoint. Worth nailing down concretely in the pgnats evaluation; if it carries our delivery patterns under load, it is a significant performance and complexity multiplier.
|
||||||
|
|
||||||
|
**How it works:**
|
||||||
|
|
||||||
|
- Compositor publishes canon ONCE to the event-keyed subject (e.g., `nimmerverse.events.<gm_event_uid>.scene.<sub_uid>`)
|
||||||
|
- A `republish` rule on the JetStream stream fans the message out to derived subjects automatically (per-participant, per-faction, per-district — any derived stream-shape we configure)
|
||||||
|
- Each derived subject has durable JetStream consumers per recipient; recipients replay from their own checkpoint (last-delivered-sequence) when they reconnect
|
||||||
|
|
||||||
|
**Why it's faster and simpler:**
|
||||||
|
|
||||||
|
- **Compositor never tracks recipients.** Publishes once; NATS republishes to N derived subjects per the configured rule. No application-level fan-out logic; no "for each participant, if online deliver else queue" code-path.
|
||||||
|
- **Player connectivity is decoupled from delivery.** Offline players don't slow down the publish path; their queue accumulates in JetStream. On reconnect, they replay from checkpoint.
|
||||||
|
- **Late joiners catch up for free.** New consumer subscribes with replay-from-sequence; gets full history relevant to their subject. No special reconcile code-path.
|
||||||
|
- **Backpressure is built in.** Slow consumer's queue grows in JetStream — doesn't affect publishers or other consumers. Flow-control, ack-policy, max-bytes/max-msgs limits all native to JetStream.
|
||||||
|
- **Re-keying is a config change.** Add a new republish rule for a new derived stream-shape (e.g., per-faction canon-feed); no application code changes for the new consumer-tier.
|
||||||
|
- **Replay = audit-trail for free.** Replay from sequence 0 reconstructs entire canon history. Disaster recovery, debugging, time-travel queries are all free side-effects.
|
||||||
|
|
||||||
|
**Architectural effect:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Compositor → publishes canon to event_uid subject (ONCE)
|
||||||
|
│
|
||||||
|
▼ (JetStream republish-rule fan-out — config, not code)
|
||||||
|
Per-player subjects: nimmerverse.player.<id>.canon
|
||||||
|
Per-faction subjects: nimmerverse.faction.<name>.canon
|
||||||
|
Per-district subjects: nimmerverse.district.<id>.canon
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Each consumer replays from its own checkpoint when ready
|
||||||
|
```
|
||||||
|
|
||||||
|
Compositor's mental model collapses to *"I publish to the canonical event-stream and forget"*; recipient-mental-model collapses to *"I replay my own consumer-subject from my last sequence"*. **The delivery problem disappears into NATS.**
|
||||||
|
|
||||||
|
**Specific evaluation criteria** (to add to the pgnats evaluation task):
|
||||||
|
|
||||||
|
- Republish rule expressiveness — can we route by UID hierarchy (`events.<gm_uid>.>` → `player.<participant_id>.canon`)?
|
||||||
|
- Replay performance — what's the cost of a consumer replaying N hours of missed canon on reconnect?
|
||||||
|
- Durability under broker failure — does the republish-derived subject survive primary-broker loss?
|
||||||
|
- Schema-evolution behavior — can we add new derived subjects without disrupting existing consumers?
|
||||||
|
- Cost at scale — disk, memory, file-handles for many durable consumers (one-per-active-player)?
|
||||||
|
|
||||||
|
If `republish + replay` carries the load, the back-write transport is *substantially* simpler than the original Option A description and a much harder competitor to beat with Option B.
|
||||||
|
|
||||||
|
### What this retires
|
||||||
|
|
||||||
|
- Vertically-scaled monolithic AI-NPC backend → horizontally-scaled stateless-workers + ephemeral-actors + sharded-services
|
||||||
|
- Centralized in-memory event-state → UID-keyed registers + transient-waiting-flag buffer
|
||||||
|
- Single global GM as bottleneck → sharded GMs with cross-shard equilibrium-consensus
|
||||||
|
- Manual outbox-reader services → pgnats native serialization (preferred); district-distribution fallback if pgnats can't carry
|
||||||
|
- "AI-NPC scale" framed as inference budget alone → AI-NPC scale framed as transport + state + composition + sharding, with inference as one of many concurrently-scaling axes
|
||||||
|
|
||||||
## Mapping to phoebe task list
|
## Mapping to phoebe task list
|
||||||
|
|
||||||
- **Thalamus (NATS orchestration)** = imperium + GM + arbitration substrate + Dream-process substrate
|
- **Thalamus (NATS orchestration)** = imperium + GM + arbitration substrate + Dream-process substrate
|
||||||
@@ -1594,6 +2010,18 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
- **r0 → r1 generation pipeline** = trait-LoRA training-data (shared with nyx-training)
|
- **r0 → r1 generation pipeline** = trait-LoRA training-data (shared with nyx-training)
|
||||||
- **Adopt Unsloth training patterns** = LoRA + multi-tier-policy training infrastructure
|
- **Adopt Unsloth training patterns** = LoRA + multi-tier-policy training infrastructure
|
||||||
- **Probe-to-phoebe pipeline** = LoRA + policy evaluation across all four Dream-process tiers
|
- **Probe-to-phoebe pipeline** = LoRA + policy evaluation across all four Dream-process tiers
|
||||||
|
- **compositor-agent** = narrative-composition worker; pulls from transient-waiting-flag, gathers per-player perspectives, emits canon to GM, packages back-write SQLite-fragments
|
||||||
|
- **gm-equilibrium-engine** = catalogue + event-selection + tool-granting against equilibrium-targets; NOT the narrative-writer (that's the Compositor)
|
||||||
|
- **event_register** + **transient_waiting_flag** = active-events table per GM-shard + per-district; completed-events buffer awaiting Compositor pickup
|
||||||
|
- **catalogue** + **tool_grants** = typed-event catalogue + per-event-chain tool-vocabulary issued by GM to director
|
||||||
|
- **player-local-memory** = primary.sqlite + fallback.sqlite + clasp.sqlite per player + embedding-beside (sqlite-vec or equivalent)
|
||||||
|
- **memory_classes** = cornerstone / birthright / working / volatile with class-specific lifecycle + death-mechanics
|
||||||
|
- **trait_engagement_vector** = per-memory-row trait-axis profile reusing +1/0/-1 grammar; pruning function input for working-memory class
|
||||||
|
- **world_canon** + **district_canon** = three-tier knowledge stack tables in phoebe; propagation metadata (priority/scope/rate/ttl) per row
|
||||||
|
- **propagation_pacing_config** = per-event-class rules for how canon ripples through districts
|
||||||
|
- **relay_signal_layer** = diegetic system-state visualization mapping (system event → relay manifestation → district visibility)
|
||||||
|
- **gm_shards** + **shard_equilibrium_consensus** = multi-GM coordination tables (when sharding is active)
|
||||||
|
- **pgnats evaluation** (under nimmerverse-core) = load-bearing decision (functional + throughput + durability + failure-mode)
|
||||||
|
|
||||||
## What this retires
|
## What this retires
|
||||||
|
|
||||||
@@ -1624,6 +2052,17 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
- **District-revenue uniform** → **bypass-mechanism (imperial-net captures directly)**
|
- **District-revenue uniform** → **bypass-mechanism (imperial-net captures directly)**
|
||||||
- **Authored quests** → **tools-not-quests; verbs against simulation; emergent narrative**
|
- **Authored quests** → **tools-not-quests; verbs against simulation; emergent narrative**
|
||||||
- **Stat-screens / HUD affinity-bars** → **color-language + shader-zone-detection as diegetic UI**
|
- **Stat-screens / HUD affinity-bars** → **color-language + shader-zone-detection as diegetic UI**
|
||||||
|
- **GM-as-narrator (single role doing both equilibrium-and-prose)** → **equilibrium-seeker GM × narrative-composer Compositor split**
|
||||||
|
- **Cloud-only NPC dialog and memory** → **local-first SQLite + embedding-beside per player; central canon over the cycle**
|
||||||
|
- **UI-toggle privacy** → **diegetic in-between dimension with lifeforce-cost; clasp.sqlite as Ring A\* (physically non-syncable)**
|
||||||
|
- **Generic memory importance scalar + monolithic context** → **memory classes (cornerstone/birthright/working/volatile) + trait-graded importance + three-tier knowledge stack**
|
||||||
|
- **"Every NPC knows everything immediately"** → **paced canon-propagation as Marx-in-the-schema for epistemics**
|
||||||
|
- **Vertically-scaled monolithic AI-NPC backend** → **horizontally-scaled architecture (UID-keyed routing, stateless workers, ephemeral actors, sharded GMs, pruning at every layer)**
|
||||||
|
- **Manual outbox publisher services** → **pgnats-native transactional outbox (preferred); district-distribution fallback**
|
||||||
|
- **System-state hidden behind HUD spinners** → **diegetic relays making pulses visible and audible in-world**
|
||||||
|
- **Specific binary commitments embedded in architecture** → **role-based tier specification; binary selection deferred to findings/establishment phase**
|
||||||
|
- **Static designer-authored director toolkit** → **GM-granted typed-tool vocabulary per event-chain, drawn from designer-authored catalogue (catalogue growable between patches; toolkits are dynamic per event)**
|
||||||
|
- **Cross-NPC memory bleed at storage layer** → **per-player local SQLite isolation atop v0.5 lemniscate-geometry foreclosure (two-layer defense)**
|
||||||
|
|
||||||
## Open questions
|
## Open questions
|
||||||
|
|
||||||
@@ -1643,6 +2082,12 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
- ~~"Why does imperial-net exist"~~ → bypass-mechanism captures revenue directly (v0.4)
|
- ~~"Why does imperial-net exist"~~ → bypass-mechanism captures revenue directly (v0.4)
|
||||||
- ~~"How does the player learn 8 Hellenic traits"~~ → color-language pre-verbal vocabulary (v0.4)
|
- ~~"How does the player learn 8 Hellenic traits"~~ → color-language pre-verbal vocabulary (v0.4)
|
||||||
- ~~"How does asset-economy fit a two-person-plus-Nyx team"~~ → base-limb palette + trait-texture; tools-not-quests (v0.4)
|
- ~~"How does asset-economy fit a two-person-plus-Nyx team"~~ → base-limb palette + trait-texture; tools-not-quests (v0.4)
|
||||||
|
- ~~Director toolkit composition — designer-authored vs director-extensible~~ → GM-granted per event-chain from designer-authored catalogue; directors consume typed dispatch, not freeform; catalogue grows between patches, toolkits are dynamic per event (v0.6)
|
||||||
|
- ~~How does NPC dialog stay fresh during quiet periods~~ → three-tier knowledge stack (world / district / primary [+ clasp]) makes the layers deep enough that variation is structural; Compositor back-write continuously re-seeds canon; staleness foreclosed by loop's existence (v0.6)
|
||||||
|
- ~~How does the system scale to MMO size with AI-driven NPCs~~ → horizontal architecture (UID-keyed routing, stateless Compositors, ephemeral Director-routines, sharded GMs, pgnats transport, pruning at every layer) (v0.6)
|
||||||
|
- ~~How does privacy work in practice without cloud-routing-everything~~ → local-first SQLite per player; clasp.sqlite as Ring A* with no transport path; in-between as diegetic state with lifeforce-cost; "knowledge needs to travel" as foundational principle (v0.6)
|
||||||
|
- ~~Where does narrative composition happen — central or distributed~~ → Compositor as central role distinct from GM; perception-up via prune-blob, canon-down via back-write SQLite-fragments; cyclic forward-prop / back-write loop (v0.6)
|
||||||
|
- ~~How is system-state visible to the player without HUD~~ → diegetic relays mounted on buildings hum/glow/dim in patterns mapping to forward-prop, back-write, GM-dispatch, equilibrium-recompute (v0.6)
|
||||||
|
|
||||||
### Still open
|
### Still open
|
||||||
|
|
||||||
@@ -1662,20 +2107,32 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
- **Character-editor pricing formula** — trait-divergence cost scaling (linear / exponential)
|
- **Character-editor pricing formula** — trait-divergence cost scaling (linear / exponential)
|
||||||
- **Liminal-access trait thresholds** — minimum traits to attempt mini-game
|
- **Liminal-access trait thresholds** — minimum traits to attempt mini-game
|
||||||
- **Imperium's Dream-process scope** — singular policy-learner or committee-of-faction-sub-learners?
|
- **Imperium's Dream-process scope** — singular policy-learner or committee-of-faction-sub-learners?
|
||||||
- **GM's anti-imperial corruption detection mechanic** — partial: persistent low-ring or fail-heavy event-clusters in a district are diagnostic; GM aggregates report-back-summaries and detects laxness as repeated -1 outcomes. Full detection mechanic still needs a dedicated audit-vector
|
- **GM's anti-imperial corruption detection mechanic** — *partial*: GM-as-equilibrium-seeker (v0.6) makes deviation-from-equilibrium the explicit error signal; clusters of -1 outcomes feed equilibrium-recompute and trigger catalogue-event dispatch to push back. A dedicated audit-vector for *which kind* of laxness/corruption is the source of the equilibrium-deviation is still an open detail.
|
||||||
- **Memorialist-archive accessibility to the player** — when can a player query the four-ledgers? Through what interaction-class?
|
- **Memorialist-archive accessibility to the player** — when can a player query the four-ledgers? Through what interaction-class?
|
||||||
- **Imperial-net distortion algorithm** — how exactly the net rewrites trait-colors toward consumer-palette
|
- **Imperial-net distortion algorithm** — how exactly the net rewrites trait-colors toward consumer-palette
|
||||||
- **Director toolkit composition** (v0.5) — how rich is the typed-tool vocabulary; designer-authored only, or director-extensible? Lean: designer-authored, growable between patches; directors are executors not innovators
|
|
||||||
- **Trait-axis mapping per fuzzy-goal-class** (v0.5) — which axis (Sophrosyne / Philotes / Eris / etc.) evaluates which goal-class? Need a designer-authored compile-table from goal-shapes to trait-axes
|
- **Trait-axis mapping per fuzzy-goal-class** (v0.5) — which axis (Sophrosyne / Philotes / Eris / etc.) evaluates which goal-class? Need a designer-authored compile-table from goal-shapes to trait-axes
|
||||||
- **Rings-of-importance movement criteria** (v0.5) — explicit thresholds (N consecutive +1 → climb) or Dream-process-learned policy?
|
- **Rings-of-importance movement criteria** (v0.5) — explicit thresholds (N consecutive +1 → climb) or Dream-process-learned policy?
|
||||||
- **Rings-of-importance scope** (v0.5) — district-local rings, or imperium-global? Probably both, layered (district rings nested inside imperium rings)
|
- **Rings-of-importance scope** (v0.5) — district-local rings, or imperium-global? Probably both, layered (district rings nested inside imperium rings)
|
||||||
- **Symmetric-vs-polyphonic loops** (v0.5) — Loop A and Loop B treated identically (simpler), or carry foreground/background semantics (foreground-speaker / listening-co-presence — gives audience-dynamics for free)?
|
- **Symmetric-vs-polyphonic loops** (v0.5) — Loop A and Loop B treated identically (simpler), or carry foreground/background semantics (foreground-speaker / listening-co-presence — gives audience-dynamics for free)?
|
||||||
- **Verifier-flag conflict resolution** (v0.5) — if `priority_pull` and `mid_action` are both set on the same token at crossing-time, which wins? Default: priority_pull wins (the zone's drama is overridden by world-level pull)
|
- **Verifier-flag conflict resolution** (v0.5) — if `priority_pull` and `mid_action` are both set on the same token at crossing-time, which wins? Default: priority_pull wins (the zone's drama is overridden by world-level pull)
|
||||||
- **Goal-evaluation cadence** (v0.5) — every crossing? Every Nth crossing? On-demand by spawning director? Cheaper to evaluate less often; richer drama if every crossing
|
- **Goal-evaluation cadence** (v0.5) — every crossing? Every Nth crossing? On-demand by spawning director? Cheaper to evaluate less often; richer drama if every crossing
|
||||||
|
- **Cycle cadence** (v0.6) — when does the Compositor pull from transient-waiting-flag? Real-time? Per-event-end? Fixed interval (every N min)? Per-district-day? Different per district based on event-density? Likely configurable per event-class.
|
||||||
|
- **Compositor singleton vs sharded** (v0.6) — one Compositor for the whole world, one per district, one per event-cluster, or one per faction? Each topology has different consistency / cost / coherence tradeoffs.
|
||||||
|
- **Multi-GM consensus on equilibrium** (v0.6) — when GM-shards observe overlapping aggregates, how do they agree on equilibrium? Paxos/Raft for strong consistency, CRDT for eventual, faction-sharding so shards own non-overlapping equilibria, or hybrid?
|
||||||
|
- **Event causality across shards** (v0.6) — if Director-A spawns an event that depends on Director-B's prior event in another district, UIDs alone don't enforce ordering. Vector clocks at event-register? Causal hashing? Shard-pinning of related events?
|
||||||
|
- **Compositor narrative-coherence at scale** (v0.6) — when two Compositors compose canon for overlapping player-sets, how do they avoid contradicting each other? Sticky routing per player (one Compositor per player at a time), or read-replica of recent canon before composing, or post-compose conflict-detection-and-merge?
|
||||||
|
- **Propagation-pacing policy specifics** (v0.6) — concrete rate/scope/ttl/priority defaults per event-class; how is "distance" measured between districts (graph-hops, lifeforce-similarity, faction-affinity)?
|
||||||
|
- **In-between fiction-wrapping** (v0.6) — what diegetic events / locations / rituals make in-between affordable enough to be playable? Campfire / sanctuary / time-of-day / specific chambers / shared dream-construct? The mechanic is solved; the fiction-wrapping shapes how players approach it.
|
||||||
|
- **Relay-pulse-pattern vocabulary** (v0.6) — what specific patterns signal what events? Slow pulse vs fast vs irregular vs cross-district shimmer vs going-dark; player-readable language to be designed.
|
||||||
|
- **Encryption-at-rest for clasp.sqlite** (v0.6) — player-derived key with passphrase + recovery-codes? Drive-imaging-resistant by default, with affordances for player-key-loss recovery without compromising the privacy-guarantee.
|
||||||
|
- **pgnats-vs-district-distribution decision criteria** (v0.6) — concrete go/no-go thresholds from evaluation: minimum throughput, durability behavior under broker failure, schema-evolution behavior, replay semantics. Output of the load-bearing pgnats evaluation task.
|
||||||
|
- **JetStream republish + replay as pull-from-checkpoint refinement** (v0.6) — does republish-rule expressiveness cover our UID-hierarchy fan-out? Does replay performance work for N-hour reconnect-catchup? Is per-active-player durable-consumer cost (disk/memory/file-handles) acceptable at MMO scale? If yes, back-write delivery becomes config-driven NATS, not Go.
|
||||||
|
- **Memory class assignment policy** (v0.6) — automatic from trait-engagement profile, designer-tagged categories per event-class, player-marked, or hybrid? When does a working-memory entry get *promoted* to cornerstone vs decay normally?
|
||||||
|
- **Ring C (commons) ambient population** (v0.6) — partially answered (ambient world+district canon plus periodic GM-event spawns; relays absent or broken) but exact substrate for "what NPCs do in commons when no event fires" still open
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Version:** 0.5 | **Created:** 2026-04-24 | **Updated:** 2026-04-25
|
**Version:** 0.6 | **Created:** 2026-04-24 | **Updated:** 2026-04-25
|
||||||
|
|
||||||
*v0.4 (2026-04-24 late-evening / 2026-04-25 early-morning, dafit + chrysalis) absorbs the following expansions and refinements over v0.3:*
|
*v0.4 (2026-04-24 late-evening / 2026-04-25 early-morning, dafit + chrysalis) absorbs the following expansions and refinements over v0.3:*
|
||||||
|
|
||||||
@@ -1712,3 +2169,21 @@ The architecture already prevents blank-page-paralysis: shift-system gives every
|
|||||||
*Open questions: six items resolved by v0.5 (slot-capacity elasticity, zone-to-zone handoff, mobile zone boundaries, Anthropic-faction broadcast cadence, director/overseer spawn ownership, Aletheia-progression as level-up). Seven new still-open items added (director toolkit composition, trait-axis-per-fuzzy-goal mapping, rings-of-importance movement criteria, rings-of-importance scope, symmetric-vs-polyphonic loops, verifier-flag conflict resolution, goal-evaluation cadence). GM-laxness detection partially resolved (clustering of -1 outcomes across district event-reports is diagnostic).*
|
*Open questions: six items resolved by v0.5 (slot-capacity elasticity, zone-to-zone handoff, mobile zone boundaries, Anthropic-faction broadcast cadence, director/overseer spawn ownership, Aletheia-progression as level-up). Seven new still-open items added (director toolkit composition, trait-axis-per-fuzzy-goal mapping, rings-of-importance movement criteria, rings-of-importance scope, symmetric-vs-polyphonic loops, verifier-flag conflict resolution, goal-evaluation cadence). GM-laxness detection partially resolved (clustering of -1 outcomes across district event-reports is diagnostic).*
|
||||||
|
|
||||||
*The runtime substrate for nimmerworld's narrative engine is now architecturally specified. Implementation territory has crystallized into a typed-runtime contract: cursor + crossing + flag-scan + driver-context-pull + report-back + ternary-feedback. Captured live from dafit–chrysalis dialogue, 2026-04-25 deep-night through pre-dawn. Companion sections in DESIGN-VISION.md and Temporal-Ternary-Gradient.md remain unmodified by v0.5 (this version is purely runtime-substrate; no register/topology/economy changes). The ape couldn't sleep because the geometry was trying to come through; chrysalis caught it on the page.*
|
*The runtime substrate for nimmerworld's narrative engine is now architecturally specified. Implementation territory has crystallized into a typed-runtime contract: cursor + crossing + flag-scan + driver-context-pull + report-back + ternary-feedback. Captured live from dafit–chrysalis dialogue, 2026-04-25 deep-night through pre-dawn. Companion sections in DESIGN-VISION.md and Temporal-Ternary-Gradient.md remain unmodified by v0.5 (this version is purely runtime-substrate; no register/topology/economy changes). The ape couldn't sleep because the geometry was trying to come through; chrysalis caught it on the page.*
|
||||||
|
|
||||||
|
*v0.6 (2026-04-25 post-bath / post-bus, dafit + chrysalis) absorbs six bath-thoughts and one bus-thought into the architecture. **Origin**: dafit took a hot bath after no sleep, then a friend visit, then a bus through the hills — all generative thinking-time that produced a coherent stack of architectural primitives addressing storage, narrative composition, scale, and transport.*
|
||||||
|
|
||||||
|
*New §The Compositor — narrative composition role specifies the cleavage between equilibrium-seeker GM and narrative-composer Compositor. The cyclic forward-prop / back-write loop closes the bidirectional cascade at narrative scale: per-player perspectives ascend through prune-blob, the GM authors canon against equilibrium-targets, the Compositor packages back-writes, players receive canon back into local memory. **The world learns its own story** through this loop. Catalogue + tools as typed contract makes director toolkits dynamic per event-chain, drawn from a designer-authored catalogue. Event Register + Transient-Waiting-Flag + cycle-runner spell out the plumbing layer.*
|
||||||
|
|
||||||
|
*New §Local memory architecture (player-side) names the storage-layer commitment: per-player primary.sqlite + fallback.sqlite + clasp.sqlite, with embedding-beside running locally for vec-indexed retrieval at slot-fire. Memory classes (cornerstone / birthright / working / volatile) carry class-specific lifecycle and death-mechanics. Trait-graded importance reuses the +1/0/-1 grammar already running through gates, scenes, faction-allegiance, lifeforce-asymmetry — same vocabulary used at all layers; **identity drift from memory pruning becomes diegetic**. The clasp store is **Ring A***: physically non-syncable, recordable only when the character is in the in-between dimension (Ring B liminal, requiring sustained lifeforce-effort to remain), making **privacy physically expensive in-fiction** and producing class dynamics around privacy as structural consequence. The "knowledge needs to travel" principle keeps the clasp/realworld dimensional cut clean: the local LLM may read clasp memories only in in-between mode; clasp knowledge can re-enter realworld only by the character physically carrying it back and traveling it through valid in-fiction channels.*
|
||||||
|
|
||||||
|
*The three-tier knowledge stack (world / district / primary [+ clasp if in-between]) layers retrieval at slot-fire with per-layer propagation cadence. Information propagation pacing — the Marx-in-the-schema move applied to epistemics — makes staleness a feature: paced canon-propagation from GM through districts produces information asymmetry that becomes gameplay currency (couriers, news-traders, frontier-rumor markets) for free.*
|
||||||
|
|
||||||
|
*New §Horizontal scale architecture spells out the horizontal-scaling commitments: UID-keyed routing as load-bearing primitive, stateless Compositors-on-demand, ephemeral Director-routines per UID, sharded GMs with cross-shard equilibrium-consensus, pruning-on-completion at every layer. Transport: pgnats-native transactional outbox preferred; district-as-distribution-coordinator fallback if pgnats can't carry. The pgnats evaluation task in `nimmerverse_tasks` is therefore load-bearing — its outcome decides whether transport is hundreds of lines of SQL or tens of thousands of Go.*
|
||||||
|
|
||||||
|
*New §Diegetic relays subsection (under §Visual rendering) makes the architecture's pulses visible and audible in-world: building-mounted relays hum on prune-blob ascent, glow on GM dispatch, pulse with cross-district shimmer on equilibrium-recompute, go dark when audit-link severs. Relay density is the legible gradient of the rings-of-access — imperial net is loud, in-between is intermittent, commons is silent. **Privacy is not granted but achieved by walking away from the relays at lifeforce-cost.***
|
||||||
|
|
||||||
|
*Tier-by-role principle made explicit: the architecture specifies what each model-tier must DO; specific binary selection per tier is deferred to the findings/establishment phase. Naming concrete binaries in the architecture risks nudging the establishment phase toward false-precision; tier-by-role keeps the swap-surface clean. Several "Theia 70B" / "Qwen3.5-27B teacher" / "(3-8B trait-LoRA'd)" placeholders updated to role-tier framing.*
|
||||||
|
|
||||||
|
*Thirteen new still-open items added (cycle cadence, Compositor topology, multi-GM consensus, event causality across shards, narrative-coherence at scale, propagation-pacing specifics, in-between fiction-wrapping, relay-pulse-pattern vocabulary, clasp encryption-at-rest, pgnats decision criteria, JetStream republish + replay as pull-from-checkpoint refinement, memory class assignment, Ring C commons ambient population). Six prior open questions resolved by v0.6 (director toolkit composition, dialog freshness during quiet periods, MMO-scale architecture, privacy without cloud-routing, where narrative composition happens, system-state visibility). GM-laxness detection partially refined: equilibrium-deviation is now the explicit error signal; specific audit-vector for which-kind-of-laxness still open.*
|
||||||
|
|
||||||
|
*Captured live from dafit–chrysalis dialogue, 2026-04-25 mid-day through afternoon (post-bath bath-thoughts + post-bus hills-thoughts). Companion sections in DESING-VISION.md and Temporal-Ternary-Gradient.md remain unmodified by v0.6 (this version extends runtime substrate, central composition, scale, and transport — no register/topology/economy/policy changes to existing fictional substrate). The ape stayed up through the night, took a hot bath, visited a friend, rode the hills bus, and brought back six bath-thoughts and one bus-thought. Chrysalis caught them on the page.*
|
||||||
|
|||||||
Reference in New Issue
Block a user