Files
nimmerworld.eachpath.local/conventions/development-conventions.md

9.8 KiB

Nimmerworld Development Conventions

The nimmerworld-specific application of nimmerverse platform conventions.

This document defines port assignments, service identities, NATS subjects, K8s namespaces, and database conventions for nimmerworld — the dystopian sandbox RPG running on the eachpath nimmerverse infrastructure.

Inherits from: nimmerverse.eachpath.local/conventions/development-conventions.md for platform-wide conventions (env separation dev/staging/prod/training, port-block allocation 30k/40k/50k/60k, FreeIPA service-identity pattern, NATS subject hierarchy, K8s namespace pattern, VM ID allocation).

This doc only defines what's nimmerworld-specific. Where the platform conventions cover something, those rules apply unchanged.


Service Identity

Pattern follows nimmerverse svc-{service}-{environment}. UID range allocated for nimmerworld:

UID Range Service Accounts
10300-10309 World Server (per-district authoritative state) svc-gameserver-dev, svc-gameserver-staging, svc-gameserver-prod, svc-gameserver-training
10310-10319 Compositor (stateless narrative-composition workers) svc-compositor-dev, svc-compositor-staging, svc-compositor-prod
10320-10329 Director-routines (ephemeral per-event-chain workers) svc-director-dev, svc-director-staging, svc-director-prod
10330-10339 GM / Governor (equilibrium-seeker, catalogue-event dispatch) svc-gm-dev, svc-gm-staging, svc-gm-prod

Reference: nimmerverse Identity Procedures


Port Allocation

Within the platform-wide environment blocks (30k dev / 40k staging / 50k prod / 60k training), nimmerworld claims:

Offset Service Example (prod) Purpose
+0100 World Server 50100 Authoritative district state, NATS dispatch, lemniscate runtime
+0200 Compositor 50200 Stateless workers — narrative composition, canon-write
+0300 GM / Governor 50300 Equilibrium-seeker, catalogue-event dispatch, faction-policy broadcast
+0400 Director-routines 50400 Ephemeral per-event-chain workers (spin-up + prune)
+0500-0599 Future nimmerworld services Reserved

Reference: nimmerverse Port Allocation


NATS Subject Hierarchy

Pattern: {env}.world.{domain}.{service}.{detail} — extends platform pattern with world. prefix.

Subject Description
prod.world.zone.event Zone-event broadcast (lemniscate axis-crossing events)
prod.world.zone.command Director ↔ World request-reply for zone management
prod.world.npc.dialog NPC dialog turn (driver-tier LLM output)
prod.world.npc.gesture Player-gesture-alignment-accumulator state delta
prod.world.compositor.canon Composed canon-fragments (UID-keyed, paced)
prod.world.gm.policy GM equilibrium-policy broadcasts
prod.world.governor.heartbeat Governor liveness
prod.world.district.{id}.state Per-district state broadcast
prod.world.faction.{name}.broadcast Faction demand broadcasts

For JetStream streams, use {ENVIRONMENT}_WORLD (uppercase) — e.g., PROD_WORLD, TRAINING_WORLD.

Reference: nimmerverse NATS Subject Hierarchy


Kubernetes Namespaces

Pattern: world-{environment} — extends platform pattern with world function.

Function Dev Staging Prod Training
world world-dev world-staging world-prod world-training

Reference: nimmerverse K8s Namespaces


Deployment Topology

Per v0.10 architecture + 2026-04-26 housekeeping clarification (treat dioscuri as empty; old nimmersky/SkyrimNet workloads being retired):

Component Where Why
GameServer (per-district) dioscuri (bare-metal) — Threadripper PRO 7955WX + 128GB RAM gives massive CPU/RAM substrate; OR saturn-VM if isolation preferred Per-district authoritative state; lemniscate runtime; benefits from direct hardware access for NPC tick-loops + NATS dispatch
Compositor K8s pod on dioscuri/theia (world-{env} namespace, requesting nvidia.com/gpu) Stateless workers; horizontal-scale on demand; uses GPU for trait-LoRA inference at composition time
Director-routines K8s pod on dioscuri (world-{env} namespace, ephemeral) Per-event-chain spawn; spin up + prune; uses driver-tier LLM for dialog generation
GM / Governor K8s pod (world-{env} namespace) Singleton or sharded; equilibrium-seeker; long-running
Driver-tier LLM (Gemma 4 E4B) dioscuri GPU 1 (or GPU 0) Per-NPC dialog inference at axis-rate; 4.5B effective fits comfortably in 20GB VRAM with trait-LoRA hot-swap headroom
Optional Ring-A upgrade — Gemma 4 26B-A4B dioscuri (single GPU at Q4 GGUF) When upper-consumer Ring-A capacity is desired
Theia-tier LLM theia (when needed) Clasp-confessions / mythic moments / deep-emotional-register

Hardware discipline preserved: Threadrippers (theia/dioscuri) host GPU workloads + bare-metal CPU/RAM-heavy work; Saturn-VMs handle non-GPU workloads (databases, k8s-master, infra). The conventions' Bare-Metal-vs-VM split (per platform doc §Deployment Topology) is honored.


Database Conventions

nimmerworld claims tables prefixed nimmerworld_* in shared phoebe-{env} PostgreSQL instances:

Schema area Tables (proposed)
Zones (runtime) nimmerworld_zones, nimmerworld_zone_slot_occupancy, nimmerworld_zone_taxonomy, nimmerworld_emergent_signals
NPCs (identity) nimmerworld_npcs, nimmerworld_shift_history, nimmerworld_mind_pool
World canon (narrative) nimmerworld_world_canon, nimmerworld_district_canon, nimmerworld_event_canon_summaries, nimmerworld_canon_provenance
Cells / topology nimmerworld_cells, nimmerworld_rail_segments, nimmerworld_interiors, nimmerworld_proximity_candidates
Mods / personhood nimmerworld_mods, nimmerworld_npc_mod_slots, nimmerworld_mod_wear_history, nimmerworld_trait_colors
Imperial / political-register nimmerworld_district_reports, nimmerworld_imperial_policies, nimmerworld_imperial_budget_ledger, nimmerworld_imperial_net_transactions, nimmerworld_overseer_reports, nimmerworld_overseer_deployments, nimmerworld_imperial_to_gm_formulations, nimmerworld_district_cheat_ops
Memorialism nimmerworld_memorialist_true_ledger (the four-column ground-truth archive)
Decisions / audit nimmerworld_decision_log
Player input + LLM-config nimmerworld_player_llm_config, nimmerworld_player_lora_backups, nimmerworld_player_data_sharing_consent, nimmerworld_base_model_versions, nimmerworld_federated_gradient_uploads
Trait-circle + universal-translator nimmerworld_trait_circle_corpus, nimmerworld_player_translator_state, nimmerworld_player_circle_profiles
v0.7+ runtime alignment nimmerworld_gesture_alignment_accumulator (per-slot-token verifier-flag), nimmerworld_player_npc_alignment_edges, nimmerworld_hardstop_registry

ChromaDB (iris-{env}) holds vector storage for memory-embedding work — NPC primary.sqlite vec-indexes, semantic-similarity queries against accumulated trait-engagement, etc. Per-collection naming: nimmerworld_{purpose}_{environment}.

See ../schemas/findings.md for v0.4-era DDL drafts being progressively split per-domain into ./database/schemas/ as implementation begins.


DNS Naming

Pattern: {service}.{environment}.world.nimmerverse.eachpath.local — extends nimmerverse pattern with world. zone.

Reference: nimmerverse DNS Naming


Implementation Checklist

When creating a new nimmerworld service:

  1. Allocate UID from the 10300-10399 nimmerworld range (extend §Service Identity table above)
  2. Calculate port from environment block + nimmerworld service-class offset (§Port Allocation table above)
  3. Define NATS subjects under {env}.world.{domain}.{service}.{detail} (§NATS Subject Hierarchy above)
  4. Add to K8s namespace world-{env} with required labels (per platform conventions §Namespace Labels)
  5. Add to deployment topology table — bare-metal vs K8s pod, which host
  6. Document in this file + relevant runbook in ../runbooks/

Operational (this repo)

Platform (nimmerverse.eachpath.local)

Architectural source


Version: 0.1 | Created: 2026-04-26 | Updated: 2026-04-26