diff --git a/.claude/rules/diagrams.md b/.claude/rules/diagrams.md new file mode 100644 index 000000000..7832992aa --- /dev/null +++ b/.claude/rules/diagrams.md @@ -0,0 +1,49 @@ +# Diagrams + +Use the user-scope `Skill(d2-diagram)` for d2 syntax, category templates, the +render scripts, and the rendering traps (the `|md` → `foreignObject` trap in +particular will cost you a render that looks authored and shows blank). This +file is only what is **specific to this repo**. + +`.d2` source + `.svg` render in `docs/diagrams/{category}/` — categories in +use: `architecture`, `data-flow`, `design`, `entity`, `state`, `ui`. + +```bash +make diagrams # render every .d2 -> .svg +make check-diagrams # fail if any .d2 lacks a .svg +clide draw --file docs/diagrams/data-flow/wiki-generator-flow.d2 # show the user +``` + +`make diagrams` is the repo's entry point rather than the skill's batch script, +so the convention holds for anyone without that skill installed. + +Scratch renders go in `.cache/` — never in `docs/diagrams/`, never in `/tmp`. + +**One PNG survives deliberately:** `design/star-map-concentric.png` has no +`.d2` source. Everything else under `docs/diagrams/` is `.d2` + `.svg` +(SVG-only since 2026-08-20; the flip cut the tree from 17 MB to 3.3 MB). + +## Some `.d2` files are generator output — do not hand-edit + +`docs/diagrams/design/star-map-*.d2` (×7: `overview`, `core`, +`north`/`south`/`east`/`west-reach`, `deep-frontier`) are written by +`tooling/generate-star-map.py` alongside `docs/design/star-map.json`. The +`concentric`/`realcoords`/`topology` SVGs come from a second script, +`tooling/generate-star-map-svg.py`, and never pass through d2 at all. + +Edit the generator and re-run it; a hand-edit is lost on the next run. Same +source-canonical rule as `.claude/rules/asset-pipeline.md`. + +## A diagram that names files goes stale silently + +Nothing fails when a path in a diagram moves. So when writing one here: + +- **State what was verified** in a header comment — whether edges were read in + the source or inferred. `wiki-generator-flow.d2` says every path was read in + the tool's own source; that claim is the diagram's value. +- **Say what it answers**, in one line, at the top. A diagram without a stated + question accumulates nodes. +- **Cross-reference the D-record** it illustrates, and reference the diagram + back from that record, or it is unreachable from the governance tree. + +Create or update a diagram when a D-record is added or amended. diff --git a/CLAUDE.md b/CLAUDE.md index d35c69791..aa61d6e5e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -179,7 +179,7 @@ The implant UI system — all diegetic neural overlay panels — lives at `clien - Decisions: records in `governance/{decisions,questions,rejected}/.md` (see `governance/README.md`; query via `pql decisions`) - Decision IDs: `D-NNN` (confirmed), `Q-NNN` (open questions), `R-NNN` (rejected) - **Claim IDs before writing:** `pql decisions claim D "title"` — prevents ID collisions across parallel branches -- Diagrams: `.d2` source + `.png` renders in `docs/diagrams/{category}/`. Create or update diagrams via `/d2-diagram` when D-records are added or modified. +- Diagrams: `.d2` source + `.svg` renders in `docs/diagrams/{category}/` — `make diagrams` renders, `make check-diagrams` gates, `clide draw --file ` shows one (it takes `.d2` source directly). Create or update diagrams when D-records are added or modified, via `Skill(d2-diagram)` plus `.claude/rules/diagrams.md`. - Discussion rounds: numbered sequentially, archived to `docs/discussions/` when complete - Briefings: one per agent, updated after decision-producing rounds - Tickets: managed via `pql ticket`/`pql plan` CLI or `/ticket` skill (`T-NNN` ids) diff --git a/Makefile b/Makefile index 3a4249d97..cba180f4f 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ GODOT := $(shell command -v godot4 2>/dev/null || command -v godot 2>/dev/null) perf-baseline debug-schedule \ test-ipc-fixtures test-ipc-protocol test-ipc-integration test-ipc-benchmark \ screenshot visual-movie test-visual visual-update \ - manifest + manifest diagrams check-diagrams # --- Configuration --- @@ -537,6 +537,30 @@ manifest: @tooling/generate-character-manifest @echo "Manifest regenerated — commit client/assets/characters/manifest.json if changed." +# --- Diagrams --- +# +# SVG, not PNG: d2 emits SVG natively, while its PNG path wants a ~150 MB +# headless-Chromium download and prompts interactively. SVG also renders in +# Gitea and in clide (`clide draw --file `), diffs as text, and +# cut docs/diagrams/ from 17 MB to 2.8 MB. +# +# Do NOT use d2 `|md` blocks in a diagram: they emit an SVG , +# which ImageMagick and flutter_svg both silently drop — the text is then in +# the file and invisible in every viewer except a browser. Use plain labels. + +diagrams: + @for d in $$(find docs/diagrams -name '*.d2'); do \ + d2 "$$d" "$${d%.d2}.svg" >/dev/null || exit 1; \ + done + @echo "Diagrams rendered — commit any changed docs/diagrams/**/*.svg." + +check-diagrams: + @fail=0; for d in $$(find docs/diagrams -name '*.d2'); do \ + test -f "$${d%.d2}.svg" || { echo "unrendered: $$d"; fail=1; }; \ + done; \ + test $$fail -eq 0 || { echo "Run 'make diagrams'."; exit 1; }; \ + echo "All diagrams rendered." + # --- Clean --- clean: diff --git a/docs/briefings/qatux.md b/docs/briefings/qatux.md index bfad9c214..ca7292d7c 100644 --- a/docs/briefings/qatux.md +++ b/docs/briefings/qatux.md @@ -58,7 +58,7 @@ None assigned directly. Track all Q-NNN and Q-WTF-* records. - `decisions/` — domain-split decision files (see `decisions/README.md` for index) - `docs/discussions/` — archived rounds (including active rounds per D-022) - `docs/briefings/` — agent briefing files (you maintain these) -- `docs/diagrams/` — decision diagrams (architecture, data-flow, entity, state, ui) — `.d2` source + `.png` renders +- `docs/diagrams/` — decision diagrams (architecture, data-flow, entity, state, ui) — `.d2` source + `.svg` renders (`make diagrams`) - `docs/workshops/` — workshop briefs, outputs, and summaries - `TEAM.md` — team roster diff --git a/docs/design/star-map-plan.md b/docs/design/star-map-plan.md index 0ffb875ec..08b515cb3 100644 --- a/docs/design/star-map-plan.md +++ b/docs/design/star-map-plan.md @@ -401,7 +401,7 @@ Consistent with existing project d2 conventions (dark background, `#1a1e24` base | `tooling/star-map-seed.json` | JSON config | Miri | Before map generation | | `docs/design/star-map.json` | JSON graph | Generated | Output of script | | `docs/diagrams/design/star-map-*.d2` (×7) | d2 source | Generated | Output of script | -| `docs/diagrams/design/star-map-*.png` (×7) | PNG renders | Generated via d2 | After d2 source | +| `docs/diagrams/design/star-map-*.svg` (×7) | SVG renders | Generated via d2 (`make diagrams`) | After d2 source — done 2026-08-20 | | Gateway system profile | Hand-authored | Miri | After name decided | | Framework amendment: add `astronomical_id` | Edit to `systems-framework.md` | Miri | After lead sign-off | | Naming catalog: real-star pool + fabrication rules | Embedded in this doc | Miri | Done (see naming section above) | diff --git a/docs/diagrams/architecture/audio-bus.png b/docs/diagrams/architecture/audio-bus.png deleted file mode 100644 index e69c00baa..000000000 Binary files a/docs/diagrams/architecture/audio-bus.png and /dev/null differ diff --git a/docs/diagrams/architecture/audio-bus.svg b/docs/diagrams/architecture/audio-bus.svg new file mode 100644 index 000000000..f27ab6731 --- /dev/null +++ b/docs/diagrams/architecture/audio-bus.svg @@ -0,0 +1,118 @@ +Rust Server(ObserverSnapshot)AudioManager(GDScript autoload singleton)5-Bus MixerPlayer Volume Sliders(1 per bus · in Settings)Audio Dip Profiles (D-069)zone_id per tilesound eventsDirectory-scan registry(res://audio/ on startup)Zone crossfade1.5-2s tween on zone_id changeBus 1 — Music(reserved · empty v0.1)Bus 2 — Ambient(station hum + zone overlays)Bus 3 — World SFX(NPC footsteps · doors · env events)Bus 4 — Player Actions(footsteps · future: combat · items)Bus 5 — UI Sounds(cursor hover · implant open · chimes)DialogueAmbient -6 to -8dB · 300ms inConfrontationAmbient -10 to -12dB + LPF · 500ms inListeningFocusWorld SFX +2 to +3dB(stationary 30+ ticks) zone change typed eventsfilename → AudioStreamloopeventeventeventproportional volumeproportional dipproportional dip + + + + + + + + + + + + diff --git a/docs/diagrams/architecture/d239-tile-derivation-contract.png b/docs/diagrams/architecture/d239-tile-derivation-contract.png deleted file mode 100644 index c85749a6a..000000000 Binary files a/docs/diagrams/architecture/d239-tile-derivation-contract.png and /dev/null differ diff --git a/docs/diagrams/architecture/d239-tile-derivation-contract.svg b/docs/diagrams/architecture/d239-tile-derivation-contract.svg new file mode 100644 index 000000000..0850f05a6 --- /dev/null +++ b/docs/diagrams/architecture/d239-tile-derivation-contract.svg @@ -0,0 +1,113 @@ +Inputs (authored upstream only)Climate primitives (per 2x2 km district)Three-carrier refinement chain (pure, deterministic D-010)8 morphology families(gated decision tree)Domain warp (anti-squaring)stateless hash(seed, body, pos)f64 sub-metre -> truncate to voxel addrBodyWorldState cache (D-203)RegionProfile labels for the Atlas(populated in D-206 background pass)seedatlas (L0-L4)body-params(stellar / orbit / hydrosphere / lithology)temperature C (nullable)sun + planet + atmosphereseason + day/night swingmoisture(separate primitive)derived: precipitation / GlaciationGrade /vegetation+treeline / seasonal-clock (Q-105)+ scattered transient freeze+snowRegionProfile (~1 km)morphology family + tectonic_class+ derived RIVER_THRESHOLDChunkContext (64 m)basin-dir + meander-curve params(no per-tile flow grid)VoxelColumn (1 m)on-demand, cached, never persistedLava / Fjord / CliffCoast / BraidedDelta /DuneStrand / IncisedGorge / Meander / AlluvialPlainhard gates: fjord>=Glaciation2 |Lava=Volcanic | lithology bounds slopefrozen 17-zone MorphologyZone vocab(enum = freeze point; change needs D-amendment) (seed, atlas, body-params, position)gates morphology + freezeselect family organic, seam-freestore labels + + + + + + + diff --git a/docs/diagrams/architecture/ipc-bridge.png b/docs/diagrams/architecture/ipc-bridge.png deleted file mode 100644 index a8887b1f0..000000000 Binary files a/docs/diagrams/architecture/ipc-bridge.png and /dev/null differ diff --git a/docs/diagrams/architecture/ipc-bridge.svg b/docs/diagrams/architecture/ipc-bridge.svg new file mode 100644 index 000000000..4efe72077 --- /dev/null +++ b/docs/diagrams/architecture/ipc-bridge.svg @@ -0,0 +1,113 @@ +Godot ClientTransport LayerRust Simulation ServerPlayerInput (MessagePack)ObserverSnapshot (MessagePack)RendererUI + HUDAudioManagerInput CaptureSimBridge (LocalBridge / NetworkBridge)Single-playerUnix socket / localhost TCPMultiplayerRemote TCPSimBridge (recv end)bevy_ecs WorldPerception SystemAI + StorytellerKnowledge Graph semantic actions(MoveNorth, Interact, UsePerceptionMode) single-playermultiplayer dispatch inputObserverSnapshot(entities, fog, sound events,monologue triggers, HUD widgets) + + + + + + + diff --git a/docs/diagrams/architecture/specialization-layer.png b/docs/diagrams/architecture/specialization-layer.png deleted file mode 100644 index cd31d1cec..000000000 Binary files a/docs/diagrams/architecture/specialization-layer.png and /dev/null differ diff --git a/docs/diagrams/architecture/specialization-layer.svg b/docs/diagrams/architecture/specialization-layer.svg new file mode 100644 index 000000000..dd4473787 --- /dev/null +++ b/docs/diagrams/architecture/specialization-layer.svg @@ -0,0 +1,114 @@ +wiki/economics/system_specialization.tomlwiki/economics/specialisation_vocabulary.tomlsystems.dbDeterministic-variedheuristic fallback(seed-hashed weighted drawW_ROLE=8000, W_CORP=5000,W_NOISE=400)D-233Economic block-fill(BulkClass × ProductionUbiquity→ coverage, vocabulary,operations surface)D-232Architecture-flavor(template pool selectionfor corridor vsheritage-divergent systems)D-214PoliticalArchetype(settlement spatial layout:commission radial /corporate campus /cooperative distributed)D-174Shadow economyintensityD-172Currency zonevalidationGroombridgelandmark mechanism:financial_hub (Specialist)+ GSH hero-elementvia D-222 + D-232 pinsystem_economy.economic_specializationsystem_economy.cultural_specializationsystem_factions.dominant_factionspecialization_vocabulary(compiled reference table) import_economics.pyimport_system_specialization()compiled reference primary source(authored wins)NULL → heuristicD-232 templatepool overrideSpecialist districtcharacter + + + + + + + + diff --git a/docs/diagrams/architecture/system-tiers.png b/docs/diagrams/architecture/system-tiers.png deleted file mode 100644 index 74cfbf9fd..000000000 Binary files a/docs/diagrams/architecture/system-tiers.png and /dev/null differ diff --git a/docs/diagrams/architecture/system-tiers.svg b/docs/diagrams/architecture/system-tiers.svg new file mode 100644 index 000000000..16dfcf39d --- /dev/null +++ b/docs/diagrams/architecture/system-tiers.svg @@ -0,0 +1,113 @@ +Architectural Principles (D-010)Simulation Tiers (D-026)30-80 NPCsFull sim · 10-20 ticks/secScope tags keep NPCs here500-2,000 NPCsState machine · 1 tick/game-minute(schedule · mood · relationships · job)10,000+ NPCsFrozen serialized structs ~1-2KBReactivate on player return ~2-5msLRU Eviction(interaction-timestamp priority queue)Client-Server Separationeven in single-playerInformation Boundariesas first-class systemNo Baked Player Identity"characters, some player-controlled"Deterministic Simulationtimestamped input eventsTier 1 — ActiveTier 2 — BackgroundTier 3 — State-SavedTier 4 — Ungenerated evict (LRU)player proximityor scope tagevict (LRU)player returnplayer approach(generated ahead of arrival) + + + + + + + diff --git a/docs/diagrams/architecture/testability.png b/docs/diagrams/architecture/testability.png deleted file mode 100644 index 055686c12..000000000 Binary files a/docs/diagrams/architecture/testability.png and /dev/null differ diff --git a/docs/diagrams/architecture/testability.svg b/docs/diagrams/architecture/testability.svg new file mode 100644 index 000000000..fc9582ce1 --- /dev/null +++ b/docs/diagrams/architecture/testability.svg @@ -0,0 +1,114 @@ +Test RunnersTest OutputIPC Test LayersTest PhasesProduction Code Constraintscargo nextest(Rust)gdUnit4(Godot)bash wrapper scripts(tests/ directory)Layer 1 — Fixture SerializationRoundtrip (fast · every edit)Layer 2 — Mock Subprocess ProtocolState machine (medium · every PR)Layer 3 — Real Subprocess Integration(slow · daily / pre-merge)Phase 1 (Sprint 1-2)Infra + collision / pathfinding / timePhase 2 (Sprint 3-4)Monologue pipeline + info boundary negativesPhase 3 (Sprint 5+)CauseChain + divergent snapshotsNo cfg(test) in production codeECS World setup replaces mock injectionCauseChain = production component(monologue provenance + debugging)Deterministic replay (D-010 P4)SimulationTime · SimRng · InputQueue injectable JSON summary+ JUnit XML (CI)JSON summary+ JUnit XML (CI) gatesgatesunblocksunblocks + + + + + + + + diff --git a/docs/diagrams/data-flow/dialogue-pipeline.png b/docs/diagrams/data-flow/dialogue-pipeline.png deleted file mode 100644 index e287b9279..000000000 Binary files a/docs/diagrams/data-flow/dialogue-pipeline.png and /dev/null differ diff --git a/docs/diagrams/data-flow/dialogue-pipeline.svg b/docs/diagrams/data-flow/dialogue-pipeline.svg new file mode 100644 index 000000000..b61c4cd17 --- /dev/null +++ b/docs/diagrams/data-flow/dialogue-pipeline.svg @@ -0,0 +1,112 @@ +Player Initiates InteractionPhase 1 — Simulation(no KnowledgeGraph read)Phase 2 — Observer(reads KnowledgeGraph)Four Relational Layers (D-028)Invisible Locked Options (D-062)Confrontation Weight (D-063)Walk-away (D-064)WASD during conversationWalk-away ConsequencesObjectType component→ max possible verb setFilter by KG confidence(Confront requires KnowsDetails+)POI priority flip+ contradiction markersArchetype filter rules(same crate: smuggler→Stash · detective→Flag)Layer 1 — Access Tier(RelationshipState only)Layer 2 — Relationship History(interaction log: greeting + topic)Layer 3 — Trust-gated Gossip(RelationshipState AND KnowledgeConfidence — D-075)Layer 4 — Unprompted Disclosure(weighted by trust + mood)Locked options = completely invisibleNo grayed-out · no lock icons · no hintsNew options appearing on repeat visits= the reward (dopamine)Written in character's internal voice(italicized first-person)Pre-delivery monologue beat1-2s: "No taking it back."World reacts(NPC Tier 2 anim · D-033 fade · monologue spikes)1 — Dialogue fades 300ms(no close button)2 — NPC reacts(animation · may call after player)3 — KG records incompleteness(per-seed tolerance: no universal safe-to-leave rules) max verb setfiltered verb setvisible options only(max 3 shown) if Confront option present + + + + + + diff --git a/docs/diagrams/data-flow/eavesdrop-pipeline.png b/docs/diagrams/data-flow/eavesdrop-pipeline.png deleted file mode 100644 index cf622f00d..000000000 Binary files a/docs/diagrams/data-flow/eavesdrop-pipeline.png and /dev/null differ diff --git a/docs/diagrams/data-flow/eavesdrop-pipeline.svg b/docs/diagrams/data-flow/eavesdrop-pipeline.svg new file mode 100644 index 000000000..7101d006a --- /dev/null +++ b/docs/diagrams/data-flow/eavesdrop-pipeline.svg @@ -0,0 +1,118 @@ +NPC-to-NPC Conversation(authored at full fidelity by copy team)Universal Murmur Asset (D-072)single asset plays everywhereZone Ambient LevelConversation ConspicuousnessServer-side Occlusion Filter (D-078)per-word probability rollListeningFocus Boost (D-071)World SFX +2 to +3dBstationary 30+ ticksNo Ambient Dip for Eavesdrop(opposite of direct conversation dip)Pre-occluded text(words → "..." per roll)Passive Dialogue Panel (D-078)(D-061 box, read-only)Monologue Channel(D-016 — separate pipeline)KnowledgeGraph entry(KnowsOf confidence unlessListeningFocus + proximity → KnowsDetails)Bar (high ambient)hidden in murmur, needs proximityWorkplace (moderate)semi-conspicuous, distance-dependentCorridor (low ambient)conspicuous, audible from distanceFactors: distance · ambient noise· ListeningFocus stanceStochastic per word(same scene can yield different fragments)Seedable RNG per tick→ deterministic replay (D-010)Speaker format (e.g. Kael to Mira)Reduced opacity (0.9)vs active dialogueNo response optionswitness_interaction trigger→ character's reactionCharacter reaction(thought · never quoted speech) audio text goes throughconspicuousness shaped by noise penaltyprobability curve shiftinstead of dippre-occluded text sent to clientclient renders exactly what it receivestriggers witness_interactionoverheard info enters KG + + + + + + + + + + + + diff --git a/docs/diagrams/data-flow/perception-pipeline.png b/docs/diagrams/data-flow/perception-pipeline.png deleted file mode 100644 index 3b8df192f..000000000 Binary files a/docs/diagrams/data-flow/perception-pipeline.png and /dev/null differ diff --git a/docs/diagrams/data-flow/perception-pipeline.svg b/docs/diagrams/data-flow/perception-pipeline.svg new file mode 100644 index 000000000..7af937010 --- /dev/null +++ b/docs/diagrams/data-flow/perception-pipeline.svg @@ -0,0 +1,117 @@ +ECS World StateLOS System(Albert Ford symmetric shadowcasting — D-035)Perception Modes (D-017)Sound System (D-018)Three-Range ModelObserverSnapshotKnowledgeGraph read(per-character — what THIS observer knows)Fog Rendering (D-059)5-layer shader systemFog Entity Recognitioncompute_fov(is_opaque, origin, range, z)→ VisibilityMapSymmetry guarantee:if A sees B → B sees ANatural Vision(walls block, cone model)Thermal(heat through walls, no identity)Camera Feeds(remote, spoofable)Unisphere Tracking(known inserts, maskable)Audio Analysis(signatures, no visual)Close (in/near LOS)High accuracy · stereo audioMedium (outside LOS)Visual indicators at fog edge + monologueLong (across map)Insert notifications · spoofableClear (vision cone)soft gradient 6-8 sim tilesLight Fog (peripheral)desaturated 40-50%, Perlin noiseDeep Fog (explored)near-monochrome + zone tintUnexplored (has maps)geometric wireframe outlinesUnexplored (no maps)solid near-blackRecognition chime fires (D-067)at ONSET of cognitive delayCognitive delay (D-060)0.6s base · 0.3s for anomalyMonologue fires DURING delay"Those footsteps... that's Kael's walk"Grey blob → D-033 color+ silhouette over 0.3s entity positions + opaque tiles sound eventsVisibilityMapobserver query result(what this sensor reveals)sound eventsper-entity recognition datavisible entities + fog stateheard/sensed entity not in LOSconcurrent + + + + + + + + + + + diff --git a/docs/diagrams/data-flow/wiki-generator-flow.d2 b/docs/diagrams/data-flow/wiki-generator-flow.d2 new file mode 100644 index 000000000..d5b7b16bf --- /dev/null +++ b/docs/diagrams/data-flow/wiki-generator-flow.d2 @@ -0,0 +1,110 @@ +# Wiki <-> generator data flow — the canonical map (D-262) +# +# WHAT THIS ANSWERS: for any file under wiki/, which way do the arrows point? +# The answer differs per file, and two paths run in BOTH directions — which is +# what everyone (agents included) keeps getting wrong. +# +# COLOUR is the grouping (green authored / blue tool / amber store / grey +# generated / purple runtime). There are deliberately no container boxes: the +# tools sit at four different depths in the flow, so boxing them together +# forced long tangled edge routes and made the graph unreadable at pane width. +# +# EDGES: solid = build-time · green = runtime · dashed = one-time/bootstrap +# red = the trap (output that is read back as input) +# +# Every path here was read in the tool's own source, not inferred. +# tooling/check-dataflow-graph asserts the paths still exist; it CANNOT verify +# that an edge's MEANING is still true — see D-262. +# +# View it: clide draw --file docs/diagrams/data-flow/wiki-generator-flow.d2 +# Render: make diagrams + +direction: down + +vars: { + d2-config: { + layout-engine: elk + pad: 30 + } +} + +classes: { + authored: {style: {fill: "#1f6f43"; stroke: "#8fd9ae"; font-color: "#ffffff"; bold: true; border-radius: 4}} + tool: {shape: hexagon; style: {fill: "#2b4c7e"; stroke: "#9dc0f0"; font-color: "#ffffff"}} + store: {shape: cylinder; style: {fill: "#7a4b12"; stroke: "#e0b070"; font-color: "#ffffff"; bold: true}} + generated: {style: {fill: "#3a3a42"; stroke: "#9a9aa4"; font-color: "#ffffff"; border-radius: 4}} + runtime: {style: {fill: "#5c2d6e"; stroke: "#d3a8e6"; font-color: "#ffffff"; border-radius: 4}} + run: {style: {stroke: "#1f8f4a"; stroke-width: 3}} + once: {style: {stroke: "#9a9aa4"; stroke-dash: 4}} + trap: {style: {stroke: "#c0392b"; stroke-width: 3; font-color: "#c0392b"; bold: true}} +} + +# ---- authored (green): a human writes these ---- +econ: "wiki/economics/\nTOMLs + 37 commodity pages" {class: authored} +corp: "wiki/corporations/*.md\n156 pages" {class: authored} +gttr: "gttr*.md\nDrifter's Guide prose" {class: authored} +prose: "system-page prose sections" {class: authored} +cli: "tooling/atlas add-body\nTHE bodies catalog origin" {class: authored} + +# ---- generators (blue hexagons) ---- +econimp: "import_economics\n+ generate_brands" {class: tool} +sync: "wiki_sync.py" {class: tool} +scaf: "scaffold_bodies.py\n+ body_definition_parser" {class: tool} +hook: "populate_gttr_hook" {class: tool} +tref: "populate_terrain_reference" {class: tool} +hmap: "import_heightmaps\n+ planet_simulation" {class: tool} + +# ---- stores (amber cylinders) ---- +db: "systems.db" {class: store} +smap: "star-map.json" {class: store} + +# ---- generated into wiki/ (grey): do not hand-edit ---- +sys: "GJ-*/index.md\nREAD-ONLY blocks" {class: generated} +body: "bodies/{id}/index.md\nfrontmatter = body definition" {class: generated} +assets: "heightmap · reliefmap · globe\nterrain.npz · markers.json" {class: generated} +brands: "generated_brands.toml" {class: generated} + +# ---- runtime (purple) ---- +cascade: "server cascade" {class: runtime} +client: "Godot client" {class: runtime} + +# wiki -> DB +econ -> econimp +corp -> econimp +gttr -> hook +cli -> db: "catalog" +econimp -> db +econimp -> brands +hook -> db: "gttr_hook" + +# DB -> wiki — the direction people miss +db -> sync +smap -> sync +sync -> sys: "renders" +prose -> sys: "preserved" +sys -> scaf: "bodies table" +scaf -> body: "writes ONCE" +sys -> sync: "parses (bootstrap)" {class: once} + +# the trap +body -> econimp: "read as INPUT" {class: trap} + +# assets +db -> hmap {class: once} +hmap -> assets {class: once} +assets -> tref +tref -> db: "terrain_reference" + +# runtime +db -> cascade {class: run} +assets -> cascade: "read at runtime" {class: run} +db -> client: "shipped" {class: run} + +# NOTE: deliberately a plain text node, NOT a `|md` block. d2 renders markdown +# blocks as an SVG (embedded HTML), which ImageMagick and +# flutter_svg both silently DROP — the legend then exists in the file and is +# invisible in every viewer except a browser. Plain labels render as real +# and survive everywhere. +legend: "READING THIS\n\nCOLOUR = kind. green authored · blue generator · amber store\n grey generated-into-wiki/ · purple runtime\nLINE = when. solid build-time · green runtime\n dashed one-time/bootstrap · RED the trap\n\n\nTWO PATHS RUN BOTH WAYS\nwiki_sync.py renders DB→wiki (generate_wiki(), routine) AND\nparses wiki→DB (import_from_wiki(), bootstrap only).\nNot a drawing error.\n\nTHE RED EDGE IS THE EXPENSIVE ONE\nscaffold_bodies.py writes a body page once and NEVER\noverwrites it; the generator then reads that frontmatter\ndirectly. A hand-edit there is not reverted — it is OBEYED,\nand silently changes world generation. Hence the\nGOVERNANCE.md prohibition.\n\nTWO ROUTES INTO THE GAME\nsystems.db ships with the build; the per-body PNGs are read\nat RUNTIME via bodies.terrain_reference, never baked in.\n\nFIELD RESOLUTION IN A BODY PAGE (body_definition_parser)\noverride > direct read > derived > inferred > seeded random.\nContinuous fields vary because they fall to the last tier;\ncategorical ones are concentrated because they come from\nthe bodies table." { + style: {font-size: 24; font-color: "#dcdce4"; fill: "#161619"; stroke: "#9a9aa4"; border-radius: 4} +} diff --git a/docs/diagrams/data-flow/wiki-generator-flow.svg b/docs/diagrams/data-flow/wiki-generator-flow.svg new file mode 100644 index 000000000..221c942b0 --- /dev/null +++ b/docs/diagrams/data-flow/wiki-generator-flow.svg @@ -0,0 +1,112 @@ +wiki/economics/TOMLs + 37 commodity pageswiki/corporations/*.md156 pagesgttr*.mdDrifter's Guide prosesystem-page prose sectionstooling/atlas add-bodyTHE bodies catalog originimport_economics+ generate_brandswiki_sync.pyscaffold_bodies.py+ body_definition_parserpopulate_gttr_hookpopulate_terrain_referenceimport_heightmaps+ planet_simulationsystems.dbstar-map.jsonGJ-*/index.mdREAD-ONLY blocksbodies/{id}/index.mdfrontmatter = body definitionheightmap · reliefmap · globeterrain.npz · markers.jsongenerated_brands.tomlserver cascadeGodot clientREADING THIS COLOUR = kind. green authored · blue generator · amber store grey generated-into-wiki/ · purple runtimeLINE = when. solid build-time · green runtime dashed one-time/bootstrap · RED the trap TWO PATHS RUN BOTH WAYSwiki_sync.py renders DB→wiki (generate_wiki(), routine) ANDparses wiki→DB (import_from_wiki(), bootstrap only).Not a drawing error. THE RED EDGE IS THE EXPENSIVE ONEscaffold_bodies.py writes a body page once and NEVERoverwrites it; the generator then reads that frontmatterdirectly. A hand-edit there is not reverted — it is OBEYED,and silently changes world generation. Hence theGOVERNANCE.md prohibition. TWO ROUTES INTO THE GAMEsystems.db ships with the build; the per-body PNGs are readat RUNTIME via bodies.terrain_reference, never baked in. FIELD RESOLUTION IN A BODY PAGE (body_definition_parser)override > direct read > derived > inferred > seeded random.Continuous fields vary because they fall to the last tier;categorical ones are concentrated because they come fromthe bodies table. cataloggttr_hookrenderspreservedbodies tablewrites ONCE parses (bootstrap) read as INPUTterrain_reference read at runtimeshipped + + + + + + + + + + + + + diff --git a/docs/diagrams/design/district-topology.png b/docs/diagrams/design/district-topology.png deleted file mode 100644 index d0644d5f6..000000000 Binary files a/docs/diagrams/design/district-topology.png and /dev/null differ diff --git a/docs/diagrams/design/district-topology.svg b/docs/diagrams/design/district-topology.svg new file mode 100644 index 000000000..18ca2e5b2 --- /dev/null +++ b/docs/diagrams/design/district-topology.svg @@ -0,0 +1,125 @@ +LegendThe Ring(span gate aperture)Gate Cluster · 40×32 vtTerminal · 44×28 vtTransition Corridor~40×6 vtThe Last Shift · 28×22 vtMaintenance Corridor(z=0 · Era 1 · 2vt wide)zero public trafficJUNC-1The Loop(station tram · 6 districts)Transit Platform~12×8 vt · bar-side(encounter node)Sector 3 Residential~15×12 vt · Drin/NaiaPublicSemi-pubSemi-privPrivateCommissionAperture8×4Freight Staging24×8Passenger Arrival12×8Customs Lanes(freight 5×4vt + ped 3×2vt)Concourse40×8 · PUBLICGallery · z=232×10 · COMMISSIONForecourt44×4Cargo Floor + Main CorridorRestricted Storage(single coded door)M-HATCH-TBar Approach28×3Main Floor(corner booth · card table)Bathroom Corridor(east ext.)Back Room(Lera)M-HATCH-B freight passenger staircase (Commission)LOS z=2 downdual-use transit(90s flicker)coded doordistrict spine (south)public routeeast doorstaff onlybar-side decompressionz=1 down z=0z=0 up z=1 workers arrive here (G-11)adjacentnear Terminaladjacent to spine + + + + + + + + + + + + + + + + + + + diff --git a/docs/diagrams/design/star-map-core.svg b/docs/diagrams/design/star-map-core.svg new file mode 100644 index 000000000..38bc1b110 --- /dev/null +++ b/docs/diagrams/design/star-map-core.svg @@ -0,0 +1,102 @@ +LegendS-001[GATEWAY]hubS-010wave 2hubS-014wave 1hubS-027wave 2hubS-037wave 1junctionS-047wave 4hubS-067wave 1hubS-074wave 1junctionS-091wave 5hubS-093wave 1hubS-111wave 1junctionS-114wave 5loop_memberS-118wave 1hubS-119wave 2hubS-120wave 1hubS-139wave 1hubS-168wave 2hubS-181wave 1junctionS-213wave 2junctionS-235wave 2junctionS-253wave 1junctionS-263wave 1junctionS-265wave 2hubS-279wave 2loop_memberS-297wave 1loop_memberS-008[South Reach]S-015[North Reach]S-044[West Reach]S-054[East Reach]S-077[East Reach]S-090[South Reach]S-110[South Reach]S-161[West Reach]S-164[North Reach]S-186[West Reach]S-248[East Reach]S-266[North Reach]Wave 1Wave 2Wave 3Wave 4Wave 5Unsettled + + + diff --git a/docs/diagrams/design/star-map-deep-frontier.svg b/docs/diagrams/design/star-map-deep-frontier.svg new file mode 100644 index 000000000..5cc6dd645 --- /dev/null +++ b/docs/diagrams/design/star-map-deep-frontier.svg @@ -0,0 +1,102 @@ +LegendS-011unsettledloop_memberS-012wave 5spur_endS-016unsettledloop_memberS-042unsettledloop_memberS-043wave 5loop_memberS-049wave 4through_routeS-063unsettledloop_memberS-069wave 4loop_memberS-073wave 3junctionS-078wave 4through_routeS-079wave 4loop_memberS-084wave 4through_routeS-089wave 3through_routeS-096wave 4loop_memberS-101wave 5loop_memberS-105wave 3loop_memberS-107wave 2loop_memberS-115unsettledthrough_routeS-117unsettledthrough_routeS-122wave 3through_routeS-124wave 4loop_memberS-126wave 5loop_memberS-129wave 5loop_memberS-130unsettledthrough_routeS-134wave 4loop_memberS-137wave 3spur_endS-138unsettledloop_memberS-141wave 5loop_memberS-143wave 4loop_memberS-145unsettledloop_memberS-146wave 3loop_memberS-147wave 4loop_memberS-150wave 5through_routeS-154wave 3loop_memberS-158wave 3through_routeS-159wave 2through_routeS-163wave 2loop_memberS-173wave 5loop_memberS-177wave 4loop_memberS-180wave 3loop_memberS-184wave 4loop_memberS-190wave 4through_routeS-194wave 4loop_memberS-197unsettledthrough_routeS-205wave 3dead_endS-206wave 5dead_endS-208wave 3loop_memberS-210wave 5loop_memberS-214wave 3loop_memberS-215wave 4through_routeS-218wave 3through_routeS-220wave 4loop_memberS-221wave 4loop_memberS-223wave 5loop_memberS-224wave 5loop_memberS-226wave 4loop_memberS-230unsettledthrough_routeS-233wave 2loop_memberS-242wave 4loop_memberS-246wave 2through_routeS-252wave 4dead_endS-255wave 4loop_memberS-256wave 4loop_memberS-258wave 3loop_memberS-262wave 5through_routeS-271wave 4loop_memberS-272unsettledloop_memberS-280wave 3loop_memberS-283wave 5loop_memberS-284wave 4spur_endS-285wave 2loop_memberS-290wave 4loop_memberS-292wave 4through_routeS-296wave 3loop_memberS-299wave 4through_routeS-004[South Reach]S-039[East Reach]S-051[East Reach]S-052[West Reach]S-080[North Reach]S-135[South Reach]S-164[North Reach]S-225[West Reach]Wave 1Wave 2Wave 3Wave 4Wave 5Unsettled + + + diff --git a/docs/diagrams/design/star-map-east-reach.svg b/docs/diagrams/design/star-map-east-reach.svg new file mode 100644 index 000000000..2a1d1db62 --- /dev/null +++ b/docs/diagrams/design/star-map-east-reach.svg @@ -0,0 +1,102 @@ +LegendS-005wave 2loop_memberS-021wave 2loop_memberS-026wave 2loop_memberS-039wave 3loop_memberS-048wave 2loop_memberS-051wave 4loop_memberS-054wave 4hubS-056wave 3loop_memberS-059wave 2loop_memberS-060wave 2loop_memberS-062wave 3loop_memberS-064wave 3loop_memberS-066wave 5loop_memberS-068wave 2loop_memberS-071wave 2loop_memberS-076unsettledloop_memberS-077wave 5loop_memberS-085wave 2loop_memberS-092wave 3loop_memberS-095wave 3dead_endS-098wave 5dead_endS-108unsettledloop_memberS-109wave 4loop_memberS-121wave 3loop_memberS-125unsettledloop_memberS-131wave 3loop_memberS-149wave 5loop_memberS-160wave 3loop_memberS-166wave 2loop_memberS-175wave 3loop_memberS-185wave 3hubS-193wave 3loop_memberS-199wave 2loop_memberS-207wave 3loop_memberS-211wave 5loop_memberS-216wave 4loop_memberS-228wave 5loop_memberS-229wave 4loop_memberS-234wave 2loop_memberS-236wave 3hubS-237wave 3loop_memberS-244wave 3loop_memberS-248wave 4loop_memberS-250wave 3loop_memberS-275wave 2loop_memberS-281wave 3loop_memberS-289wave 3loop_memberS-294wave 3loop_memberS-298wave 2loop_memberS-300wave 1loop_memberS-047[Core]S-058[North Reach]S-073[Deep Frontier]S-093[Core]S-145[Deep Frontier]S-202[South Reach]S-265[Core]Wave 1Wave 2Wave 3Wave 4Wave 5Unsettled + + + diff --git a/docs/diagrams/design/star-map-north-reach.svg b/docs/diagrams/design/star-map-north-reach.svg new file mode 100644 index 000000000..a14ca7b29 --- /dev/null +++ b/docs/diagrams/design/star-map-north-reach.svg @@ -0,0 +1,102 @@ +LegendS-006wave 2loop_memberS-009wave 5hubS-015wave 3junctionS-017wave 4loop_memberS-022wave 4loop_memberS-023wave 4through_routeS-024wave 2loop_memberS-028wave 3loop_memberS-032wave 2through_routeS-033wave 3spur_endS-040wave 2loop_memberS-046wave 3loop_memberS-050wave 2loop_memberS-058wave 3loop_memberS-065wave 2loop_memberS-070wave 3dead_endS-075wave 5loop_memberS-080wave 4loop_memberS-081wave 2loop_memberS-097wave 5loop_memberS-099wave 2through_routeS-104wave 3dead_endS-106wave 4loop_memberS-112wave 2loop_memberS-127wave 3loop_memberS-132wave 4loop_memberS-152wave 3loop_memberS-164unsettledhubS-171wave 2loop_memberS-176wave 3dead_endS-183wave 3junctionS-188wave 2loop_memberS-191wave 4loop_memberS-196wave 2loop_memberS-198wave 3loop_memberS-201wave 3loop_memberS-203wave 1loop_memberS-204wave 2spur_endS-231wave 3through_routeS-239wave 4junctionS-240wave 3dead_endS-241wave 5spur_endS-243wave 2loop_memberS-251wave 2loop_memberS-266wave 3loop_memberS-268wave 2loop_memberS-273wave 2loop_memberS-276wave 3spur_endS-287wave 3dead_endS-291wave 4through_routeS-010[Core]S-011[Deep Frontier]S-119[Core]S-129[Deep Frontier]S-161[West Reach]S-236[East Reach]S-265[Core]Wave 1Wave 2Wave 3Wave 4Wave 5Unsettled + + + diff --git a/docs/diagrams/design/star-map-overview.svg b/docs/diagrams/design/star-map-overview.svg new file mode 100644 index 000000000..dac481387 --- /dev/null +++ b/docs/diagrams/design/star-map-overview.svg @@ -0,0 +1,114 @@ +Core25 systems · 14 hubsNorth Reach50 systems · 2 hubsWest Reach50 systems · 2 hubsSouth Reach50 systems · 2 hubsEast Reach50 systems · 3 hubsDeep Frontier75 systems · 0 hubsGATEWAY (S-001)Diplomatic Periphery · CoreSol aperture: dormant located in3 connections3 connections3 connections3 connections2 connections2 connections2 connections2 connections1 connections1 connections1 connections1 connections + + + + + + + + + + + + + + + diff --git a/docs/diagrams/design/star-map-south-reach.svg b/docs/diagrams/design/star-map-south-reach.svg new file mode 100644 index 000000000..cf9a47ae3 --- /dev/null +++ b/docs/diagrams/design/star-map-south-reach.svg @@ -0,0 +1,102 @@ +LegendS-002wave 3dead_endS-004wave 2loop_memberS-008wave 2junctionS-013wave 5loop_memberS-025wave 3loop_memberS-029wave 3loop_memberS-031wave 3spur_endS-041wave 3loop_memberS-045wave 4dead_endS-055wave 3loop_memberS-057wave 3through_routeS-061wave 3junctionS-072wave 3spur_endS-082wave 2loop_memberS-087wave 4loop_memberS-090wave 1loop_memberS-094wave 3spur_endS-100wave 3dead_endS-102wave 4junctionS-103unsettledloop_memberS-110wave 4hubS-113unsettledjunctionS-123unsettleddead_endS-133unsettledthrough_routeS-135wave 3junctionS-136wave 3dead_endS-142wave 3dead_endS-148wave 3dead_endS-153wave 2spur_endS-156wave 4loop_memberS-162wave 3through_routeS-165wave 3loop_memberS-169wave 3spur_endS-174wave 4loop_memberS-178wave 3loop_memberS-187wave 2loop_memberS-192wave 2through_routeS-200wave 3loop_memberS-202wave 3loop_memberS-209wave 3loop_memberS-212wave 2hubS-219wave 5loop_memberS-238unsettledthrough_routeS-247wave 2loop_memberS-249wave 3loop_memberS-259unsettledloop_memberS-270wave 5dead_endS-277wave 4loop_memberS-282unsettledjunctionS-288wave 3junctionS-027[Core]S-092[East Reach]S-119[Core]S-120[Core]S-180[Deep Frontier]S-254[West Reach]S-285[Deep Frontier]Wave 1Wave 2Wave 3Wave 4Wave 5Unsettled + + + diff --git a/docs/diagrams/design/star-map-west-reach.svg b/docs/diagrams/design/star-map-west-reach.svg new file mode 100644 index 000000000..a1380bcb0 --- /dev/null +++ b/docs/diagrams/design/star-map-west-reach.svg @@ -0,0 +1,102 @@ +LegendS-003wave 2loop_memberS-007wave 2loop_memberS-018wave 2loop_memberS-019wave 5through_routeS-020wave 1loop_memberS-030wave 3loop_memberS-034wave 3loop_memberS-035wave 1through_routeS-036wave 4loop_memberS-038wave 3dead_endS-044wave 4loop_memberS-052wave 4junctionS-053wave 4loop_memberS-083unsettledthrough_routeS-086wave 2loop_memberS-088wave 2through_routeS-116wave 3through_routeS-128wave 3loop_memberS-140wave 3loop_memberS-144wave 4loop_memberS-151wave 4through_routeS-155wave 2through_routeS-157wave 3loop_memberS-161wave 5junctionS-167wave 3through_routeS-170wave 4loop_memberS-172wave 2spur_endS-179wave 5loop_memberS-182wave 1loop_memberS-186wave 3junctionS-189wave 2loop_memberS-195unsettledhubS-217wave 3loop_memberS-222wave 2loop_memberS-225wave 2hubS-227wave 3loop_memberS-232wave 4junctionS-245wave 4loop_memberS-254wave 3junctionS-257wave 3loop_memberS-260wave 3dead_endS-261wave 5loop_memberS-264wave 2dead_endS-267wave 5loop_memberS-269wave 4loop_memberS-274wave 3spur_endS-278wave 3loop_memberS-286wave 2through_routeS-293wave 5through_routeS-295wave 2through_routeS-120[Core]S-220[Deep Frontier]S-223[Deep Frontier]S-239[North Reach]S-263[Core]S-265[Core]S-288[South Reach]Wave 1Wave 2Wave 3Wave 4Wave 5Unsettled + + + diff --git a/docs/diagrams/entity/dialogue-tags.png b/docs/diagrams/entity/dialogue-tags.png deleted file mode 100644 index 0ecde5204..000000000 Binary files a/docs/diagrams/entity/dialogue-tags.png and /dev/null differ diff --git a/docs/diagrams/entity/dialogue-tags.svg b/docs/diagrams/entity/dialogue-tags.svg new file mode 100644 index 000000000..51bb54046 --- /dev/null +++ b/docs/diagrams/entity/dialogue-tags.svg @@ -0,0 +1,107 @@ +Dialogue Lineid{npc-slug}_{d|m}_{###}PKtextStringroleenum (template-defined role)accesslist<enum> (public · insider · authority · peer · hostile)trustenum (surface · real · secret)situationlist<enum> (14 situations)topiclist<enum> (9 topics — optional)moodlist<enum> (8 moods — optional)tagslist<string> (freeform — optional)Monologue Lineid{npc-slug}_m_{s|d}_{###}PKcharacterenum (smuggler · detective)not_nulltriggerenum (9 triggers)not_nullprerequisitemap or nulldual_lensmap (authoring-only)notesString (authoring-only)AccessTier valuespublicPublic — default, anyoneinsiderInsider — social network memberauthorityAuthority — institutional rolepeerPeer — known colleaguehostileHostile — adversarial contextTrustTier valuessurfaceSurface — any relationship + any confidencerealReal — (Friendly|Known) + KnowsOf+secretSecret — Friendly + KnowsDetails+Situation (14)s1first_meetings2regular_contacts3after_conflicts4work_contexts5social_contexts6private_contexts7witnessed_somethings8under_suspicions9post_confrontations10trust_brokens11urgents12relaxeds13farewells14greetingMood (8)m1anxiousm2frustratedm3contentm4suspiciousm5warmm6hostilem7relievedm8focusedMonologue Triggers (9)t1enter_locationt2observe_npct3hear_soundt4observe_anomalyt5post_conversationt6discover_evidencet7witness_interactiont8time_idlet9return_visit access fieldtrust field situation fieldmood fieldextendstrigger field + + + + + + + + diff --git a/docs/diagrams/entity/knowledge-graph.png b/docs/diagrams/entity/knowledge-graph.png deleted file mode 100644 index 2ed4c0789..000000000 Binary files a/docs/diagrams/entity/knowledge-graph.png and /dev/null differ diff --git a/docs/diagrams/entity/knowledge-graph.svg b/docs/diagrams/entity/knowledge-graph.svg new file mode 100644 index 000000000..ecfc50619 --- /dev/null +++ b/docs/diagrams/entity/knowledge-graph.svg @@ -0,0 +1,118 @@ +KnowledgeGraphentity_knowledgeBTreeMap<StableId, EntityKnowledge>fact_knowledgeBTreeMap<FactId, FactKnowledge>EntityKnowledgestable_idStableId(u64)FKconfidenceKnowledgeConfidencestateKnowledgeStatesourceKnowledgeSourcelast_observed_ticku64FactKnowledgefact_idFactIdPKconfidenceKnowledgeConfidencestateKnowledgeStatesourceKnowledgeSourcelast_observed_ticku64KnowledgeConfidencedirectDirect — currently in LOSknows_detailsKnowsDetails — actionable (secret tier)knows_ofKnowsOf — involved in Y (real tier)suspectsSuspects — something off (surface tier)KnowledgeStateactiveActive — believed truecontradictedContradicted — conflict detected (Sprint 3+)staleStale — aged beyond threshold (Sprint 3+)KnowledgeSourcedirect_observationDirectObservationheardHeardtold_byToldBy (Sprint 3+)inferredInferred (Sprint 3+)backgroundBackgroundEntityRegistrystable_to_entityBTreeMap<StableId, Entity>entity_to_stableBTreeMap<Entity, StableId>KnowledgeEventQueue(bevy_ecs Resource) contains manycontains manyusesusesusesusesusesuses StableId lookupdrained each tick→ writes components + + + + + + + + + + + + diff --git a/docs/diagrams/entity/npc-generation.png b/docs/diagrams/entity/npc-generation.png deleted file mode 100644 index 27a7f786c..000000000 Binary files a/docs/diagrams/entity/npc-generation.png and /dev/null differ diff --git a/docs/diagrams/entity/npc-generation.svg b/docs/diagrams/entity/npc-generation.svg new file mode 100644 index 000000000..f91785396 --- /dev/null +++ b/docs/diagrams/entity/npc-generation.svg @@ -0,0 +1,113 @@ +NPC (generated)7 Essential Axes3 Supporting AxesCombatCapability(optional ECS component)Key Contradiction InteractionsSocial Site(atomic Tier 2 template unit)WantSecret / VulnerabilityRelationships (1-3)Tolerance ThresholdDaily RoutineInformation InventoryContentmentPersonality Traits (2-3)Tell SystemSkill SetWant × SecretRoutine × SecretTolerance × RelationshipsWant × RelationshipsPersonality × ToleranceSocial Group (4-8 NPCs)2+ triangles + 1 cross-template triangleFunctional Cluster15-40 tiles, internal sightlinesNPC Ownershipowned by 1 template, referenced by others generated with generated withcombat tag → componentproducesplaced in + + + + + + + diff --git a/docs/diagrams/state/knowledge-confidence.png b/docs/diagrams/state/knowledge-confidence.png deleted file mode 100644 index 2a39389f5..000000000 Binary files a/docs/diagrams/state/knowledge-confidence.png and /dev/null differ diff --git a/docs/diagrams/state/knowledge-confidence.svg b/docs/diagrams/state/knowledge-confidence.svg new file mode 100644 index 000000000..b5007cc7c --- /dev/null +++ b/docs/diagrams/state/knowledge-confidence.svg @@ -0,0 +1,117 @@ +No Knowledge(entity unknown)Suspects"something off"KnowsOf"X is involved in Y"KnowsDetails"actionable detail"Direct"currently in LOS"Dialogue Trust Gate (D-075)Fog Recognition (D-059)KnowledgeStateSurface tier(any confidence)Real tier(KnowsOf+ AND Friendly/Known)Secret tier(KnowsDetails+ AND Friendly)Recognized entity(D-033 color + silhouette)Grey blob(no identity)Active (Sprint 2)Contradicted (Sprint 3+)ToldBy conflicts DirectObservationStale (Sprint 3+)aged past DecayThreshold observe anomalyor receive tipfurther observationor testimony direct evidenceor confrontationenter LOSexit LOSdecay(last_observed_tick age)decay ToldBy vs DirectObservation(Sprint 3+)decay (Sprint 3+) + + + + + + + + + + + diff --git a/docs/diagrams/state/movement-stances.png b/docs/diagrams/state/movement-stances.png deleted file mode 100644 index 1c1280900..000000000 Binary files a/docs/diagrams/state/movement-stances.png and /dev/null differ diff --git a/docs/diagrams/state/movement-stances.svg b/docs/diagrams/state/movement-stances.svg new file mode 100644 index 000000000..6ca2c499c --- /dev/null +++ b/docs/diagrams/state/movement-stances.svg @@ -0,0 +1,118 @@ +Sprint1 tile/tick · loud footstepsMonologue 40% (urgent only)Interaction buffer CLEARED (D-055)Sprint double-take: anomaly monologue fires retroactivelyWalk(default stance)1 tile/2 ticks · normal footstepsMonologue 100%Default — MovementProfile componentCareful1 tile/3 ticks · quiet footstepsMonologue 150% + tell notice bonusListeningFocus accumulates (stationary_ticks)Eavesdrop bonus: ListeningFocus +2-3dB (D-071)Crouch1 tile/4 ticks · very quietUses Prone/Seated occupancy layer (D-054)Prone(future)TilePresence (D-054)Same-tile occupancy layersStandingProne / SeatedFixture toggletoggle toggletoggletoggletoggletoggle (future)toggle-out onlyoccupiesoccupies + + + + + + + + + + + + diff --git a/docs/diagrams/state/npc-simulation-tiers.png b/docs/diagrams/state/npc-simulation-tiers.png deleted file mode 100644 index 403e849b0..000000000 Binary files a/docs/diagrams/state/npc-simulation-tiers.png and /dev/null differ diff --git a/docs/diagrams/state/npc-simulation-tiers.svg b/docs/diagrams/state/npc-simulation-tiers.svg new file mode 100644 index 000000000..ba7f6f37f --- /dev/null +++ b/docs/diagrams/state/npc-simulation-tiers.svg @@ -0,0 +1,116 @@ +Tier 4UngeneratedTier 3State-Saved~1-2KB frozen structTier 2Background500-2,000 NPCsTier 1Active30-80 NPCs · full simScope Tags (prevent eviction)LRU Priority Queue(interaction-timestamp)neighborhoodactive-questcolleagueknown-contact player approach(generated ahead)player return(~2-5ms reactivation)LRU eviction player proximityor scope tag matchLRU eviction(no scope tag)prevents evictionmanagesmanages + + + + + + + + + + diff --git a/docs/diagrams/ui/fog-layers.png b/docs/diagrams/ui/fog-layers.png deleted file mode 100644 index f1e2a3aa3..000000000 Binary files a/docs/diagrams/ui/fog-layers.png and /dev/null differ diff --git a/docs/diagrams/ui/fog-layers.svg b/docs/diagrams/ui/fog-layers.svg new file mode 100644 index 000000000..e420a2b90 --- /dev/null +++ b/docs/diagrams/ui/fog-layers.svg @@ -0,0 +1,113 @@ +KnowledgeGraph(per character — D-041)Five Fog LayersEntities in FogSame fog, different information per characterSmuggler: recognizes dock workers = green iconsDetective: same entities = grey blobs Fog is not darkness —it is the absence of your attention.Performance Budget<1ms/frame totalVision cone = PointLight2DFog = CanvasGroup noise shader (Layer 5)Sound pings = 0-5 spritesEntity ghosts = 0-10 sprites typicalLayer 1 — Clear (vision cone)Soft gradient edge 6-8 sim tiles(= 3-4 visual tiles per D-066)No hard line · Darkwood approachLayer 2 — Light Fog (peripheral)Desaturated 40-50% · brightness -30%Animated Perlin noise (8-10s cycle)D-033 entity colors visible but reducedLayer 3 — Deep Fog (explored)Near-monochrome + ~10% zone tint(bar=warm dark · hub=cool dark)More pronounced noise (15-20s cycle)zone_id from ObserverSnapshot (D-077)Layer 4 — Unexplored (has maps)Geometric wireframe outlinesInsert data aestheticLayer 5 — Unexplored (no maps)Solid near-blackInformation zeroSound Ping2-3 concentric expanding rings(sonar-style · insert white-blue)Loud=3 rings bright · quiet=1 ring faintFade over 1.5sRecognized EntityD-033 color glow + silhouette feature(e.g. identifying clothing detail)0.8s breathing pulse+/-0.5 tile position driftUnrecognized Entityneutral grey blobno silhouette · no identity determines entity recognition(which observer sees which entities)KnowsOf+ → recognized Suspects / none → blobentities rendered within fog statesame shader, per-character KG + + + + + + + diff --git a/docs/diagrams/ui/hud-layout.png b/docs/diagrams/ui/hud-layout.png deleted file mode 100644 index e247a9221..000000000 Binary files a/docs/diagrams/ui/hud-layout.png and /dev/null differ diff --git a/docs/diagrams/ui/hud-layout.svg b/docs/diagrams/ui/hud-layout.svg new file mode 100644 index 000000000..5597b8242 --- /dev/null +++ b/docs/diagrams/ui/hud-layout.svg @@ -0,0 +1,112 @@ +Rendering Z-Stack (D-049)8 layers — bottom to topInsert Overlay Design (D-048)Dialogue Box (D-061, D-076)Monologue floats ABOVE dialogue box(z-layer 7 — spatial separationcharacter thinks while NPC speaks)Layer 0 — Floor Tiles(zone identity · movement surface)Layer 1 — Floor Objects(cosmetic · walked over)Layer 2 — Furniture / Placed Objects(y-sorted with entities)Layer 3 — Entity Sprites(y-sorted · D-033 relationship color24x32px footprint in 64x64 tile)Layer 4 — Overhead / Wall Tops(pipes · ducts · fixtures · signagesemi-transparent partial occlusion)Layer 5 — Fog of Perception(vision cone mask · fog shaderaffects layers 0-4)Layer 6 — Insert Overlay(lattice HUD · bloom-renderedNOT affected by fogInteraction labels render here)Layer 7 — Monologue / UI(always visible · top of stackDialogue box and response options)Soft bloom shader~2-3px gaussian · ~40% blendSmugglerthinner · sparser (baseline lattice)Detectivedenser · crisper (augmented lattice)Insert OFF behavior (OQ-07)Cursor shape changesInteraction labels hiddenBottom of screenmax 20% heightMax-width 1200px(centered · ~62% of 1920px)Unified conversation log(active + overheard — chronological)Speaker to Target formatper-character name coloursResponse options below logmax 3 visibleNo portraits(NPC is on screen)Entry timeout15s + 3s fade (configurable) does NOT affectrendered atrendered atmonologue above + + + + + + diff --git a/docs/diagrams/ui/interaction-flow.png b/docs/diagrams/ui/interaction-flow.png deleted file mode 100644 index 13e13a622..000000000 Binary files a/docs/diagrams/ui/interaction-flow.png and /dev/null differ diff --git a/docs/diagrams/ui/interaction-flow.svg b/docs/diagrams/ui/interaction-flow.svg new file mode 100644 index 000000000..6e4caa699 --- /dev/null +++ b/docs/diagrams/ui/interaction-flow.svg @@ -0,0 +1,115 @@ +Cursor States (D-056)(insert's own interface element · z-layer 7)Cursor RulesEntity Interaction List (D-057)(left-click on entity)World Radial Menu (D-058)(right-click)Default4 thin inward ticks + bloomWhite-blue · barely visibleEntity HoverTicks expand outward (150ms)Corner brackets · D-033 relationship colorVerb tooltip in insert stylingObject HoverTicks rotate 45° → X-shapeMuted grey (amber if flagged)Weapon AimTicks extend · center gap widensLines 1 to 2px · warm whiteNO bloom · D-033 tint on targetChanges on LOS · not just proximityInteraction range ~2 sim tiles (= 1m)Weapon mode suppresses interaction prompts(unless Shift held)Insert OFF: cursor shape still changes(body reacts) · verb labels hidden(insert doesn't process targets)Compact vertical listanchored to entity position2-4 options maxNew options: gradient glow background(knowledge change signal)Labels on z-layer 6(insert data — hidden if insert off)Phase 1 (simulation): max verb setfrom ObjectType componentPhase 2 (observer): filter by KGarchetype variation · POI flipv0.1: 2 spokesObserve (eye) · Insert (phone)Future: up to 6 spokes+ Comms (signal) · Wait (clock)Drag-release (power users)Click-click (newcomers)Fixed categories → spatial memory(unlike entity verbs which vary by knowledge) entity in LOS+ proximity object in LOS+ proximityweapon selectedweapon deselectedleft-click→ shows interaction listright-click→ opens radial filtered + + + + + + + + +