Cenosis Docs Architecture
v4.0 · ABI major 4

Architecture

The three-tier Level-of-Detail spine is the single most important architectural pattern in Cenosis. Everything else — cognition, social systems, the director, persistence — is built to feed into or out of this spine.

The LOD Simulation Spine

With 200 NPCs in a town, only ~5 can run full LLM cognition. The rest must still progress coherently. The "always-live world" decision makes LOD a correctness requirement, not a performance optimization.

Full Sim (FS) — three nested clocks

For agents within the player's proximity. A hard cap of 8 concurrent FS agents is enforced.

LayerCadenceCostWhat runs
ReactiveEvery world tick (10 Hz)µs UtilitySelector scores affordances at current location by current needs. No LLM.
TacticalEvery ~5s game timems GoalSelector picks a short-term goal. Optionally uses a local ONNX SLM; falls back to deterministic lowest-need selection.
NarrativeEvent-drivenseconds Cloud LLM via npc-budget. Handles dialog, reflection, long-term planning, SS→FS wake summaries.

Statistical Sim (SS) — deterministic, no LLM

For off-camera agents. 200 SS agents per tick on a phone is fine. Each tick runs five steps in sequence:

  1. Schedule lookupagent.schedule.current_at(now) finds the current (activity, location).
  2. Need decay — per-need hourly rates (Hunger 0.04/h, Energy 0.06/h awake, Social 0.03/h, Fun 0.02/h), clamped to [0, 1].
  3. Schedule execution — if the scheduled location differs from current, update location and record SsEvent::StartedActivity.
  4. Opportunistic affordance use — if any need falls below 0.30, scan affordances at current location, apply the winning affordance's need + mood deltas, record SsEvent::UsedAffordance.
  5. Social encounter sampling — for every pair of co-located agents, roll 5% per tick (ChaCha8Rng seeded from config). On success, update RelationshipGraph (+0.05 Trust, Affection bidirectional) and record SsEvent::SocialEncounter.

No LLM in SS — ever

This is non-negotiable. It is what makes off-camera history deterministic across replay. The SS event log is the audit trail — concrete events recorded, never derived on read.

Macro Sim (v2.5) — city scale

For 1,000+ agent cities. Aggregates agent → household → district → settlement. Has its own deterministic aggregate progression, hysteresis with SS, NPCB v16+ scale persistence, and load shedding. Tested with 10,080-agent city_scale_budget.

Tier Transitions

Hysteresis: Enter FS at 20m, exit at 30m by default. Without this, agents at the boundary thrash and each transition costs a cloud call.

Wake (SS → FS): When the host flags proximity, the engine promotes the agent, compiles its accumulated SsEvent log into a deterministic wake summary, and optionally queues an LLM render of that summary (the LLM renders the events — it never invents new ones).

Sleep (FS → SS): On proximity exit, reset ss_since, drop the event log, demote to AgentTier::StatSim.

Write-Ahead Log & Persistence

All state changes flow through a WAL before touching any projection:

Host game  ──record_event()──▶  npc-ffi  ──crossbeam──▶  WAL writer thread
                                                                │
                                                    npc_memory.wal (group commit)
                                                                │
                                                    SQLite projection store
                                                    (HNSW + relations + beliefs)

The WAL writer uses group commit — fsync every 32 events or 50ms. Key properties this gives you:

  • Crash recovery — unprojected tails recover to tick barriers; partial ticks are detected and discarded.
  • Deterministic replay — same WAL prefix + LLM cache → identical state.
  • Repro bundles — single-file .repro captures for bug reproduction and divergence localization.

Rule

WAL writes precede projection mutations. MemoryStore::append_event is the durability boundary. Projections are always derived — never the source of truth.

Cognition Pipeline

When a Full Sim agent needs narrative output (dialog, reflection, wake summary), the pipeline runs in this order:

  1. PromptBuilder — assembles a token-budgeted prompt. Trim order: memories → dialog → world context. Sections include persona, relationships, beliefs, topic memory, location, time, nearby agents, recent events, and the task block.
  2. BudgetGovernor — checks per-agent / session / hour caps, then checks hash(prompt) → response cache. Cache hit = zero spend.
  3. CloudDispatcher — drains the priority queue (PlayerDialog > NarrativeBeat > Reflection > Background), enforces provider-health backoff and hard timeouts.
  4. ConstraintEngine — validates LLM output against persona hard_constraints (forbidden topics/actions) before acceptance.
  5. HostAction queue — completed responses flow back as HostAction variants the game engine drains via peek-then-pop.

Circuit Breaker

Repeated provider failures latch the session. All FS agents are demoted to SS and new promotions are refused. The world keeps running without cloud — just less narratively rich. The latch is surfaced through npc_engine_peek_metrics.

Social Systems

Relationships

RelationshipGraph is a directed multigraph with 6 asymmetric dimensions: Trust, Affection, Respect, Fear, Loyalty, Familiarity. Features:

  • Data-extensible RelationshipKind and RelationshipIntent (registry-driven, not enum)
  • Bounded importance-ranked history with source deduplication
  • Opt-in baseline-setpoint decay
  • Per-settlement standing aggregated from concrete evidence (no gossip-loop amplification)

Beliefs & Theory of Mind

BeliefStore holds per-agent theory-of-mind: what agent X believes about Y, and why (concrete BeliefSource events). Includes contradiction detection, provenance chains, and the PlausibleBeliefUpdate constraint — the LLM cannot reveal information the agent does not possess.

Gossip & Reputation

A first-class Tier-2 extension (npc-extend::rumor). Rumors spread between co-located SS agents via deterministic seeded sampling, with reputation effects and crowd scenes (>4 agents). NPCB v17 persists the rumor pool + reputation state.

Conversations

Stateful multi-agent scenes with intents, topics, emotional dialogue acts, commitments, and WAL-first consequences. Closed conversations atomically update relationships, beliefs, and commitments. SceneManager is the lifecycle authority.

Director & Storylets

StoryletEngine evaluates designer-authored triggers against world + social + agent context every tick. Storylets are data, not code — they define conditions and concrete effects:

  • Mood changes, relationship deltas, memory injection, dialog seeds, world events
  • Tension pacing and multi-beat storyline instances
  • Faction-biased social drama
  • Life-event pulses (birth, death, bereavement, inheritance)
  • Economic event pulses (price spikes, bankruptcy)

Packs remain data

Triggers and affordances are pack-authored JSON, never Rust code. The v0.4 security boundary does not move — packs cannot execute arbitrary code.

Determinism & Replay

Cenosis is built around a determinism-first philosophy:

  • SS agents are fully deterministic: same seed + schedule + RNG → identical event logs, needs, relationships.
  • FS agents are deterministic modulo cloud responses, which the LLM cache provides.
  • Parallel tick uses sorted-id processing order so parallel and single-threaded runs produce identical results.
  • Determinism testscriterion_7 ticks two independent towns with the same seed and bit-compares snapshots every 60 ticks. Any drift is a determinism bug.