docs(decisions): restructure into pql governance DQR tree
Phase 1 of the pql migration. Moves the flat decisions/*.md layout into
governance/{decisions,questions,rejected}/<domain>.md — the tree pql's
`decisions sync` parses natively (record type from subdir, domain from
filename stem). Proven against pql 1.6.2: sync reports 357 records
(237 D / 108 Q / 12 R), 1057 refs, broken: 0; validate ok.
- 6 D-domain files -> governance/decisions/ (git renames)
- 5 questions-<domain>.md -> governance/questions/<domain>.md (prefix dropped)
- rejected.md split by domain -> governance/rejected/{architecture(R-001..010),
economics(R-011),perception(R-012)}.md
- decisions/README.md + questions.md index folded into governance/README.md;
pql's `decisions sync` now auto-maintains the record index appended below
the hand-written domain guidance (no more manual ID-list table upkeep).
- .pql/config.yaml: canonical vault config (tracked, not ignored).
Link rewrites are token-preserving: only the relative `foo.md` path portion
changes (e.g. `rejected.md#r-011` -> `../rejected/economics.md#r-011`); every
`[D-NNN]` bracket text and `#anchor` stays byte-identical, so pql's reference
extraction is unaffected. The one-shot transform is committed at
tooling/pql-migrate/restructure_decisions.py for provenance.
Codebase path references to decisions/ (CLAUDE.md, rules, skills, docs) are
updated in a follow-up commit.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,435 @@
|
||||
# Governance — Decisions, Questions, Rejected
|
||||
|
||||
Structured planning records for The Settled Reach. `pql decisions sync` parses
|
||||
these into `.pql/pql.db`; query them with `pql decisions …`.
|
||||
|
||||
## Layout
|
||||
|
||||
Records live in three per-type subdirectories, split by domain:
|
||||
|
||||
```
|
||||
governance/
|
||||
decisions/<domain>.md # D-NNN — confirmed design decisions
|
||||
questions/<domain>.md # Q-NNN — open questions (may resolve into a D or R)
|
||||
rejected/<domain>.md # R-NNN — rejected alternatives (kept for the audit trail)
|
||||
```
|
||||
|
||||
The parser infers **record type from the parent subdirectory** and **domain from
|
||||
the filename stem**. A `### D-NNN: Title` (or `Q-`/`R-`) heading begins each record;
|
||||
`- **Field:** value` lines and inline `[D-NNN](…#anchor)` links carry the metadata
|
||||
and cross-references pql indexes.
|
||||
|
||||
Current domains: `architecture`, `content`, `economics`, `perception`, `process`,
|
||||
`scope`. Create a new `<domain>.md` in the relevant subdir when records land in a
|
||||
new domain.
|
||||
|
||||
## Domain guide
|
||||
|
||||
When in doubt where a record belongs:
|
||||
|
||||
- **architecture** — constrains *how we build* (engine, protocols, data structures, performance).
|
||||
- **scope** — defines *what we build* (game concept, feature scope, prototype shape).
|
||||
- **perception** — defines *what the player observes or knows* (camera, fog, LOS, audio).
|
||||
- **content** — defines *narrative, NPCs, dialogue, setting, templates*.
|
||||
- **economics** — the economics layer (currencies, commodities, corporations, simulation).
|
||||
- **process** — defines *how the team works* (workflow, commits, branches, reviews).
|
||||
|
||||
Cross-domain records live in one file with `[D-NNN](../<subdir>/<domain>.md#…)` links
|
||||
to the related domain.
|
||||
|
||||
## Querying
|
||||
|
||||
```bash
|
||||
pql decisions list # every record
|
||||
pql decisions list --type confirmed --domain architecture
|
||||
pql decisions show D-010 --with-tickets # a record + its implementing tickets
|
||||
pql decisions read D-238 # full markdown body
|
||||
pql decisions refs D-010 # cross-references in/out
|
||||
pql decisions coverage # decisions ↔ ticket coverage
|
||||
```
|
||||
|
||||
## Adding a record
|
||||
|
||||
1. **Claim an ID** (no side effects): `pql decisions claim D <domain> "title"`
|
||||
(use `Q` for a question, `R` for a rejected alternative).
|
||||
2. Edit the appropriate file (`decisions/<domain>.md`, `questions/<domain>.md`,
|
||||
or `rejected/<domain>.md`). Follow the existing `### D-NNN: Title` format.
|
||||
3. Commit. The pre-commit hook runs `pql decisions validate` (malformed-record gate)
|
||||
and stages the planning changelog.
|
||||
4. Update relevant agent briefings if needed.
|
||||
|
||||
When a question resolves, set its `- **Status:** Resolved → [D-NNN](../decisions/<domain>.md#…)`
|
||||
line in place — keep the Q-record for the audit trail rather than deleting it.
|
||||
|
||||
*Maintained by Qatux.*
|
||||
|
||||
<!-- pql:records (auto-generated; do not edit manually) -->
|
||||
|
||||
## Decisions
|
||||
|
||||
- [D-001: Build a custom game, not a mod](decisions/scope.md#d-001-build-a-custom-game-not-a-mod) — _scope_
|
||||
- [D-002: Dynasty grand strategy concept [SUPERSEDED]](decisions/scope.md#d-002-dynasty-grand-strategy-concept-superseded) — _scope_
|
||||
- [D-003: The Settled Reach is the first campaign, not the only possible one](decisions/scope.md#d-003-the-settled-reach-is-the-first-campaign-not-the-only-possible-one) — _scope_
|
||||
- [D-004: Team composition confirmed](decisions/process.md#d-004-team-composition-confirmed) — _process_
|
||||
- [D-005: Core concept - single character, first-person, story-generator](decisions/scope.md#d-005-core-concept---single-character-first-person-story-generator) — _scope_
|
||||
- [D-006: Prototype scenario — Institute/Armstrong/Guardians [SUPERSEDED]](decisions/scope.md#d-006-prototype-scenario--institutearmstrongguardians-superseded) — _scope_
|
||||
- [D-007: Five pillars of game design](decisions/scope.md#d-007-five-pillars-of-game-design) — _scope_
|
||||
- [D-008: Action pillar design principles](decisions/architecture.md#d-008-action-pillar-design-principles) — _architecture_
|
||||
- [D-009: Multiplayer - design for it, build single-player first](decisions/architecture.md#d-009-multiplayer---design-for-it-build-single-player-first) — _architecture_
|
||||
- [D-010: Multiplayer-ready architectural baseline](decisions/architecture.md#d-010-multiplayer-ready-architectural-baseline) — _architecture_
|
||||
- [D-011: Fog of perception is non-negotiable (Pillar 1 infrastructure)](decisions/perception.md#d-011-fog-of-perception-is-non-negotiable-pillar-1-infrastructure) — _perception_
|
||||
- [D-012: Chunk-based map architecture for future borderless generation](decisions/architecture.md#d-012-chunk-based-map-architecture-for-future-borderless-generation) — _architecture_
|
||||
- [D-013: Diegetic insert/POI navigation system](decisions/scope.md#d-013-diegetic-insertpoi-navigation-system) — _scope_
|
||||
- [D-014: v0.1 map specification [SUPERSEDED]](decisions/scope.md#d-014-v01-map-specification-superseded) — _scope_
|
||||
- [D-015: Camera locked to character, rotation as future option](decisions/perception.md#d-015-camera-locked-to-character-rotation-as-future-option) — _perception_
|
||||
- [D-016: Internal monologue as core perception/atmosphere system](decisions/perception.md#d-016-internal-monologue-as-core-perceptionatmosphere-system) — _perception_
|
||||
- [D-017: Perception modes as character-build system](decisions/perception.md#d-017-perception-modes-as-character-build-system) — _perception_
|
||||
- [D-018: Three-range sound model](decisions/perception.md#d-018-three-range-sound-model) — _perception_
|
||||
- [D-019: Top-down confirmed as primary camera, 3D cutscenes for key moments [SUPERSEDED by D-148]](decisions/perception.md#d-019-top-down-confirmed-as-primary-camera-3d-cutscenes-for-key-moments-superseded-by-d-148) — _perception_
|
||||
- [D-020: Engine and architecture selection — Godot client + Rust simulation via subprocess/IPC](decisions/architecture.md#d-020-engine-and-architecture-selection--godot-client--rust-simulation-via-subprocessipc) — _architecture_
|
||||
- [D-021: Official project title — "The Settled Reach"](decisions/process.md#d-021-official-project-title--the-settled-reach) — _process_
|
||||
- [D-022: Process — Round-based collaboration workflow](decisions/process.md#d-022-process--round-based-collaboration-workflow) — _process_
|
||||
- [D-023: Three-tier content model with life-sim substrate](decisions/content.md#d-023-three-tier-content-model-with-life-sim-substrate) — _content_
|
||||
- [D-024: NPC generation model — 10 axes + combat component](decisions/content.md#d-024-npc-generation-model--10-axes--combat-component) — _content_
|
||||
- [D-025: Social site / functional cluster as atomic template unit](decisions/content.md#d-025-social-site--functional-cluster-as-atomic-template-unit) — _content_
|
||||
- [D-026: Simulation tiers with timestamp-based eviction](decisions/architecture.md#d-026-simulation-tiers-with-timestamp-based-eviction) — _architecture_
|
||||
- [D-027: Vertical slice — smuggler + detective, two-character proof [SUPERSEDED]](decisions/scope.md#d-027-vertical-slice--smuggler--detective-two-character-proof-superseded) — _scope_
|
||||
- [D-028: Dialogue architecture — tagged line pools with four relational layers](decisions/content.md#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers) — _content_
|
||||
- [D-029: Population entanglement ratio — 30/50/20](decisions/content.md#d-029-population-entanglement-ratio--305020) — _content_
|
||||
- [D-030: Testability architecture — 8 decisions for ticket #214](decisions/architecture.md#d-030-testability-architecture--8-decisions-for-ticket-214) — _architecture_
|
||||
- [D-031: Time system — game clock and day phases](decisions/architecture.md#d-031-time-system--game-clock-and-day-phases) — _architecture_
|
||||
- [D-032: Separate monologue pools per character [SUPERSEDED — deferred to Phase 6]](decisions/content.md#d-032-separate-monologue-pools-per-character-superseded--deferred-to-phase-6) — _content_
|
||||
- [D-033: Entity color = relationship to player](decisions/perception.md#d-033-entity-color--relationship-to-player) — _perception_
|
||||
- [D-034: THE FRIEND — production-level NPC pattern](decisions/content.md#d-034-the-friend--production-level-npc-pattern) — _content_
|
||||
- [D-035: Converged tag taxonomy for dialogue and monologue line pools](decisions/content.md#d-035-converged-tag-taxonomy-for-dialogue-and-monologue-line-pools) — _content_
|
||||
- [D-036: Sova Transit District / Van Maanen's Star as v0.1 setting](decisions/content.md#d-036-sova-transit-district--van-maanens-star-as-v01-setting) — _content_
|
||||
- [D-037: Contraband specification — unlicensed lattice components](decisions/content.md#d-037-contraband-specification--unlicensed-lattice-components) — _content_
|
||||
- [D-038: Audio in v0.1 scope — 8 files via Stable Audio Open](decisions/scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open) — _scope_
|
||||
- [D-039: v0.1 wow moment scope — all 6 moments [SUPERSEDED]](decisions/scope.md#d-039-v01-wow-moment-scope--all-6-moments-superseded) — _scope_
|
||||
- [D-040: Wiki taxonomy structure — hierarchical with YAML frontmatter](decisions/process.md#d-040-wiki-taxonomy-structure--hierarchical-with-yaml-frontmatter) — _process_
|
||||
- [D-041: Knowledge Graph Data Model](decisions/architecture.md#d-041-knowledge-graph-data-model) — _architecture_
|
||||
- [D-042: UI microcopy format — YAML via GDScript autoload](decisions/architecture.md#d-042-ui-microcopy-format--yaml-via-gdscript-autoload) — _architecture_
|
||||
- [D-043: Art direction — visual style ("functional warmth")](decisions/perception.md#d-043-art-direction--visual-style-functional-warmth) — _perception_
|
||||
- [D-044: Art direction — visual hierarchy (entity > object > structure)](decisions/perception.md#d-044-art-direction--visual-hierarchy-entity--object--structure) — _perception_
|
||||
- [D-045: Art direction — environmental neutrality (strict zero shift)](decisions/perception.md#d-045-art-direction--environmental-neutrality-strict-zero-shift) — _perception_
|
||||
- [D-046: Art direction — lighting system (three-reference model)](decisions/perception.md#d-046-art-direction--lighting-system-three-reference-model) — _perception_
|
||||
- [D-047: Art direction — two-tier animation system](decisions/perception.md#d-047-art-direction--two-tier-animation-system) — _perception_
|
||||
- [D-048: Neural insert overlay — visual design](decisions/perception.md#d-048-neural-insert-overlay--visual-design) — _perception_
|
||||
- [D-049: Z-level rendering stack (8 layers)](decisions/perception.md#d-049-z-level-rendering-stack-8-layers) — _perception_
|
||||
- [D-050: Velen — Van Maanen's Star primary world](decisions/content.md#d-050-velen--van-maanens-star-primary-world) — _content_
|
||||
- [D-051: "Settling is placement" — design principle](decisions/scope.md#d-051-settling-is-placement--design-principle) — _scope_
|
||||
- [D-052: Character favorite colors — object-layer identification](decisions/perception.md#d-052-character-favorite-colors--object-layer-identification) — _perception_
|
||||
- [D-053: Movement as stance toggle system](decisions/scope.md#d-053-movement-as-stance-toggle-system) — _scope_
|
||||
- [D-054: Tile-based movement with same-tile occupancy](decisions/architecture.md#d-054-tile-based-movement-with-same-tile-occupancy) — _architecture_
|
||||
- [D-055: Sprint explicitly suppresses interaction buffer](decisions/architecture.md#d-055-sprint-explicitly-suppresses-interaction-buffer) — _architecture_
|
||||
- [D-056: Cursor states — insert-styled geometric](decisions/perception.md#d-056-cursor-states--insert-styled-geometric) — _perception_
|
||||
- [D-057: Entity interaction — vertical list, insert-styled [PARTIALLY SUPERSEDED — archetype portion deferred to Phase 6]](decisions/perception.md#d-057-entity-interaction--vertical-list-insert-styled-partially-superseded--archetype-portion-deferred-to-phase-6) — _perception_
|
||||
- [D-058: World menu — radial, 4 spokes](decisions/perception.md#d-058-world-menu--radial-4-spokes) — _perception_
|
||||
- [D-059: Fog — shader-based, five layers, knowledge-graph-driven](decisions/perception.md#d-059-fog--shader-based-five-layers-knowledge-graph-driven) — _perception_
|
||||
- [D-060: Cognitive delay for fog recognition](decisions/perception.md#d-060-cognitive-delay-for-fog-recognition) — _perception_
|
||||
- [D-061: Dialogue box — unified conversation log, bottom screen, max 20% height, no portraits](decisions/perception.md#d-061-dialogue-box--unified-conversation-log-bottom-screen-max-20-height-no-portraits) — _perception_
|
||||
- [D-062: Invisible locked dialogue options](decisions/content.md#d-062-invisible-locked-dialogue-options) — _content_
|
||||
- [D-063: Confrontation — same box, different weight](decisions/content.md#d-063-confrontation--same-box-different-weight) — _content_
|
||||
- [D-064: Walk-away — three-phase consequences](decisions/content.md#d-064-walk-away--three-phase-consequences) — _content_
|
||||
- [D-065: Smuggler inventory — knowledge-primary with physical evidence [SUPERSEDED]](decisions/scope.md#d-065-smuggler-inventory--knowledge-primary-with-physical-evidence-superseded) — _scope_
|
||||
- [D-066: Dual-scale grid — 0.5m simulation, 1m visual (2x retina factor)](decisions/architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor) — _architecture_
|
||||
- [D-067: Recognition chime fires at onset of cognitive delay](decisions/perception.md#d-067-recognition-chime-fires-at-onset-of-cognitive-delay) — _perception_
|
||||
- [D-068: 5-bus audio architecture](decisions/architecture.md#d-068-5-bus-audio-architecture) — _architecture_
|
||||
- [D-069: Audio dip profiles for dialogue and confrontation](decisions/perception.md#d-069-audio-dip-profiles-for-dialogue-and-confrontation) — _perception_
|
||||
- [D-070: Confrontation as cognitive vulnerability](decisions/perception.md#d-070-confrontation-as-cognitive-vulnerability) — _perception_
|
||||
- [D-071: No ambient dip for eavesdropping — ListeningFocus boost](decisions/perception.md#d-071-no-ambient-dip-for-eavesdropping--listeningfocus-boost) — _perception_
|
||||
- [D-072: Universal event-driven conversation murmur](decisions/perception.md#d-072-universal-event-driven-conversation-murmur) — _perception_
|
||||
- [D-073: Zone crossfade approach — hard boundary, soft audio transition](decisions/architecture.md#d-073-zone-crossfade-approach--hard-boundary-soft-audio-transition) — _architecture_
|
||||
- [D-074: Audio aesthetic identity — insert-tech vs organic](decisions/content.md#d-074-audio-aesthetic-identity--insert-tech-vs-organic) — _content_
|
||||
- [D-075: Dialogue filtering — layered confidence gate on trust tier (OQ-18 resolution)](decisions/content.md#d-075-dialogue-filtering--layered-confidence-gate-on-trust-tier-oq-18-resolution) — _content_
|
||||
- [D-076: Dialogue box max-width — 1200px (OQ-29 resolution)](decisions/perception.md#d-076-dialogue-box-max-width--1200px-oq-29-resolution) — _perception_
|
||||
- [D-077: Zone temperature memory — server-tracked zone_id (OQ-09 resolution)](decisions/perception.md#d-077-zone-temperature-memory--server-tracked-zone-id-oq-09-resolution) — _perception_
|
||||
- [D-078: ~~Overheard NPC conversation — passive dialogue panel with occlusion filter~~ SCRAPPED (R-012)](decisions/perception.md#d-078-overheard-npc-conversation--passive-dialogue-panel-with-occlusion-filter-scrapped-r-012) — _perception_
|
||||
- [D-079: Knowledge Grant Architecture](decisions/perception.md#d-079-knowledge-grant-architecture) — _perception_
|
||||
- [D-080: NPC-to-NPC Knowledge Propagation](decisions/perception.md#d-080-npc-to-npc-knowledge-propagation) — _perception_
|
||||
- [D-081: Unprompted Disclosure Design](decisions/perception.md#d-081-unprompted-disclosure-design) — _perception_
|
||||
- [D-082: NPC Information Boundaries — MVP Scope](decisions/perception.md#d-082-npc-information-boundaries--mvp-scope) — _perception_
|
||||
- [D-083: Contradiction Detection Pipeline](decisions/perception.md#d-083-contradiction-detection-pipeline) — _perception_
|
||||
- [D-084: Dual-namespace line ID scheme — role pool + instance override](decisions/content.md#d-084-dual-namespace-line-id-scheme--role-pool--instance-override) — _content_
|
||||
- [D-085: Per-game save directory structure](decisions/architecture.md#d-085-per-game-save-directory-structure) — _architecture_
|
||||
- [D-086: Insert icon system — custom SVG, no icon font](decisions/perception.md#d-086-insert-icon-system--custom-svg-no-icon-font) — _perception_
|
||||
- [D-087: v0.1 triangle configuration — 3 active forks, 2 passive tensions [SUPERSEDED]](decisions/scope.md#d-087-v01-triangle-configuration--3-active-forks-2-passive-tensions-superseded) — _scope_
|
||||
- [D-088: 3-state pause system — Normal/Overlay/Paused, server-authoritative](decisions/architecture.md#d-088-3-state-pause-system--normaloverlaypaused-server-authoritative) — _architecture_
|
||||
- [D-089: Self-contained triangle forks for v0.1, no cross-triangle cascade [SUPERSEDED]](decisions/scope.md#d-089-self-contained-triangle-forks-for-v01-no-cross-triangle-cascade-superseded) — _scope_
|
||||
- [D-090: PC voice registers — smuggler and detective speech patterns `[SUPERSEDED]`](decisions/content.md#d-090-pc-voice-registers--smuggler-and-detective-speech-patterns-superseded) — _content_
|
||||
- [D-091: Complicity as named thematic core [SUPERSEDED]](decisions/scope.md#d-091-complicity-as-named-thematic-core-superseded) — _scope_
|
||||
- [D-092: Anchor line requirement in NPC style guide](decisions/content.md#d-092-anchor-line-requirement-in-npc-style-guide) — _content_
|
||||
- [D-093: Sova Transit District — Spatial Layout and District Topology](decisions/content.md#d-093-sova-transit-district--spatial-layout-and-district-topology) — _content_
|
||||
- [D-094: District Spatial Hierarchy — Chunk, Block, District Naming and Sizes](decisions/architecture.md#d-094-district-spatial-hierarchy--chunk-block-district-naming-and-sizes) — _architecture_
|
||||
- [D-095: Horizon Stations and Gate Infrastructure — Transport Lore](decisions/content.md#d-095-horizon-stations-and-gate-infrastructure--transport-lore) — _content_
|
||||
- [D-096: DistrictLayoutMode — Grid and Organic Support](decisions/architecture.md#d-096-districtlayoutmode--grid-and-organic-support) — _architecture_
|
||||
- [D-097: Guarantee Tier System — Universal / Full-Only / Conditional](decisions/architecture.md#d-097-guarantee-tier-system--universal--full-only--conditional) — _architecture_
|
||||
- [D-098: TrianglePurpose Enum](decisions/content.md#d-098-trianglepurpose-enum) — _content_
|
||||
- [D-099: WallBackside / TileBehindState — Dual Classification](decisions/architecture.md#d-099-wallbackside--tilebehindstate--dual-classification) — _architecture_
|
||||
- [D-100: Dynamic Modification via Overlay — DamageOverlay and RegenerationStrategy](decisions/architecture.md#d-100-dynamic-modification-via-overlay--damageoverlay-and-regenerationstrategy) — _architecture_
|
||||
- [D-101: ZonePalette Modifier System](decisions/architecture.md#d-101-zonepalette-modifier-system) — _architecture_
|
||||
- [D-102: Horizon View Corridor as Coastal Guarantee](decisions/architecture.md#d-102-horizon-view-corridor-as-coastal-guarantee) — _architecture_
|
||||
- [D-103: Assassin Lens Spatial Guarantees — A-1 through A-4](decisions/architecture.md#d-103-assassin-lens-spatial-guarantees--a-1-through-a-4) — _architecture_
|
||||
- [D-104: Heritage Grammar Overlay for Non-Urban Palettes](decisions/content.md#d-104-heritage-grammar-overlay-for-non-urban-palettes) — _content_
|
||||
- [D-105: Non-Urban Informal Zone Typology](decisions/content.md#d-105-non-urban-informal-zone-typology) — _content_
|
||||
- [D-106: Vertical Scale Architecture and Rooftop Bar Clause](decisions/architecture.md#d-106-vertical-scale-architecture-and-rooftop-bar-clause) — _architecture_
|
||||
- [D-107: Trauma Events as EraModification Subtypes](decisions/content.md#d-107-trauma-events-as-eramodification-subtypes) — _content_
|
||||
- [D-108: MobileChunk Specification](decisions/architecture.md#d-108-mobilechunk-specification) — _architecture_
|
||||
- [D-109: DamageOverlay / RegenerationStrategy Prohibition — Architectural Mandate](decisions/architecture.md#d-109-damageoverlay--regenerationstrategy-prohibition--architectural-mandate) — _architecture_
|
||||
- [D-110: Signed Z-Level Addressing — base_z u8 → i8](decisions/architecture.md#d-110-signed-z-level-addressing--base-z-u8--i8) — _architecture_
|
||||
- [D-111: MobileChunk Idle State Covers Stationary Player Installations](decisions/architecture.md#d-111-mobilechunk-idle-state-covers-stationary-player-installations) — _architecture_
|
||||
- [D-112: No Separate Location Instancing System](decisions/architecture.md#d-112-no-separate-location-instancing-system) — _architecture_
|
||||
- [D-113: Tile data model — extensible per-tile properties](decisions/architecture.md#d-113-tile-data-model--extensible-per-tile-properties) — _architecture_
|
||||
- [D-114: v0.2 proof-of-life — generator + graphics, not hand-built slice](decisions/scope.md#d-114-v02-proof-of-life--generator--graphics-not-hand-built-slice) — _scope_
|
||||
- [D-115: Character creation scoped to skills + bookmark for v0.2](decisions/scope.md#d-115-character-creation-scoped-to-skills--bookmark-for-v02) — _scope_
|
||||
- [D-116: Religion is not a game system](decisions/scope.md#d-116-religion-is-not-a-game-system) — _scope_
|
||||
- [D-117: Tycoon is the v0.2 bookmark — zero investigation content](decisions/scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) — _scope_
|
||||
- [D-118: Small business owner starting state — tycoon is aspiration, not starting position](decisions/scope.md#d-118-small-business-owner-starting-state--tycoon-is-aspiration-not-starting-position) — _scope_
|
||||
- [D-119: Generator spike confirmed for Sprint 25 — critical path](decisions/scope.md#d-119-generator-spike-confirmed-for-sprint-25--critical-path) — _scope_
|
||||
- [D-120: No skill ceiling in v0.2 — transhumanist ladder deferred](decisions/scope.md#d-120-no-skill-ceiling-in-v02--transhumanist-ladder-deferred) — _scope_
|
||||
- [D-121: Voice is culture-driven — job as modifier](decisions/content.md#d-121-voice-is-culture-driven--job-as-modifier) — _content_
|
||||
- [D-122: All NPCs generated — no named hand-authored characters](decisions/content.md#d-122-all-npcs-generated--no-named-hand-authored-characters) — _content_
|
||||
- [D-123: Generative AI for NPC content — build-time authoring tool and runtime voice pipeline](decisions/content.md#d-123-generative-ai-for-npc-content--build-time-authoring-tool-and-runtime-voice-pipeline) — _content_
|
||||
- [D-124: In-game ollama for live NPC dialogue — ~~deferred~~ SUPERSEDED by D-138](decisions/content.md#d-124-in-game-ollama-for-live-npc-dialogue--deferred-superseded-by-d-138) — _content_
|
||||
- [D-125: World is quietly responsive — gradient of caring by social proximity](decisions/content.md#d-125-world-is-quietly-responsive--gradient-of-caring-by-social-proximity) — _content_
|
||||
- [D-126: Groundhog Day alarm clock homage — first game day only](decisions/content.md#d-126-groundhog-day-alarm-clock-homage--first-game-day-only) — _content_
|
||||
- [D-127: Player choices are the content — Rimworld model, job as rails](decisions/content.md#d-127-player-choices-are-the-content--rimworld-model-job-as-rails) — _content_
|
||||
- [D-128: Culture implicit in starting location — Van Maanen's Star equals Van Maanen's Star culture](decisions/content.md#d-128-culture-implicit-in-starting-location--van-maanens-star-equals-van-maanens-star-culture) — _content_
|
||||
- [D-129: NPC personality — traits + behavior first, relationships codified for systems](decisions/content.md#d-129-npc-personality--traits--behavior-first-relationships-codified-for-systems) — _content_
|
||||
- [D-130: Fully emergent moral arc for v0.2 — generator proves relationships readable first](decisions/content.md#d-130-fully-emergent-moral-arc-for-v02--generator-proves-relationships-readable-first) — _content_
|
||||
- [D-131: Broad economic verb vocabulary — life verbs, not tycoon-specific](decisions/content.md#d-131-broad-economic-verb-vocabulary--life-verbs-not-tycoon-specific) — _content_
|
||||
- [D-132: Dual-scale consequence model — Rimworld sharp events and DF slow accumulation](decisions/content.md#d-132-dual-scale-consequence-model--rimworld-sharp-events-and-df-slow-accumulation) — _content_
|
||||
- [D-133: Skills affect outcome — same verbs available, skill determines quality](decisions/architecture.md#d-133-skills-affect-outcome--same-verbs-available-skill-determines-quality) — _architecture_
|
||||
- [D-134: Full character customization — hair, clothing, colors at tile scale](decisions/architecture.md#d-134-full-character-customization--hair-clothing-colors-at-tile-scale) — _architecture_
|
||||
- [D-135: Setting delivery via both layers — visual world + insert in parallel](decisions/architecture.md#d-135-setting-delivery-via-both-layers--visual-world--insert-in-parallel) — _architecture_
|
||||
- [D-136: First Settled Reach moment — auto-generated apartment + insert activation](decisions/architecture.md#d-136-first-settled-reach-moment--auto-generated-apartment--insert-activation) — _architecture_
|
||||
- [D-137: Generator produces both structural and cosmetic variety at different scales](decisions/architecture.md#d-137-generator-produces-both-structural-and-cosmetic-variety-at-different-scales) — _architecture_
|
||||
- [D-138: LLM Re-voicing Pipeline for NPC Voice](decisions/content.md#d-138-llm-re-voicing-pipeline-for-npc-voice) — _content_
|
||||
- [D-139: Composable behavior primitives — three-layer assembly model](decisions/content.md#d-139-composable-behavior-primitives--three-layer-assembly-model) — _content_
|
||||
- [D-140: Dialogue re-voicing quality constraints — Paula's six rules](decisions/content.md#d-140-dialogue-re-voicing-quality-constraints--paulas-six-rules) — _content_
|
||||
- [D-141: PlatformInfo — client-side OS abstraction autoload](decisions/architecture.md#d-141-platforminfo--client-side-os-abstraction-autoload) — _architecture_
|
||||
- [D-142: Zone-type template architecture for scalable NPC behavior](decisions/content.md#d-142-zone-type-template-architecture-for-scalable-npc-behavior) — _content_
|
||||
- [D-143: GD calendar epoch — Gate Discovery (2300 AD) as year 0](decisions/content.md#d-143-gd-calendar-epoch--gate-discovery-2300-ad-as-year-0) — _content_
|
||||
- [D-144: Sirius (GJ 244A / S-067) as Reach capital — seat of the Concord Assembly](decisions/content.md#d-144-sirius-gj-244a--s-067-as-reach-capital--seat-of-the-concord-assembly) — _content_
|
||||
- [D-145: Base building DLC — GJ 902 unclaimed moon as player settlement site](decisions/scope.md#d-145-base-building-dlc--gj-902-unclaimed-moon-as-player-settlement-site) — _scope_
|
||||
- [D-146: Character creation preview — tile-scale sprite with heavy zoom](decisions/scope.md#d-146-character-creation-preview--tile-scale-sprite-with-heavy-zoom) — _scope_
|
||||
- [D-147: Aesthetic taste as character personality trait — shared root for cosmetic and environmental expression](decisions/content.md#d-147-aesthetic-taste-as-character-personality-trait--shared-root-for-cosmetic-and-environmental-expression) — _content_
|
||||
- [D-148: 30° low-angle camera with 45° map rotation — supersedes D-019](decisions/architecture.md#d-148-30-low-angle-camera-with-45-map-rotation--supersedes-d-019) — _architecture_
|
||||
- [D-149: 3D characters rendered live in scene — not pre-rendered sprites](decisions/architecture.md#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites) — _architecture_
|
||||
- [D-150: Character outline — inverted hull method](decisions/architecture.md#d-150-character-outline--inverted-hull-method) — _architecture_
|
||||
- [D-151: Direction count — 8 server-side facings, 4 visual groups client Sprint 28](decisions/architecture.md#d-151-direction-count--8-server-side-facings-4-visual-groups-client-sprint-28) — _architecture_
|
||||
- [D-152: Character LOD — performance-driven budget, not distance threshold](decisions/architecture.md#d-152-character-lod--performance-driven-budget-not-distance-threshold) — _architecture_
|
||||
- [D-153: Player character not visually distinct from NPCs](decisions/scope.md#d-153-player-character-not-visually-distinct-from-npcs) — _scope_
|
||||
- [D-154: Character outline is not a relationship indicator — uniform dark](decisions/scope.md#d-154-character-outline-is-not-a-relationship-indicator--uniform-dark) — _scope_
|
||||
- [D-155: Character editor rotation — cardinal directions only, no free-spin](decisions/scope.md#d-155-character-editor-rotation--cardinal-directions-only-no-free-spin) — _scope_
|
||||
- [D-156: Faction colors are narrative, not a visual compositor concern](decisions/scope.md#d-156-faction-colors-are-narrative-not-a-visual-compositor-concern) — _scope_
|
||||
- [D-157: Game start sequence — alarm clock fade from black, not camera pull-back](decisions/scope.md#d-157-game-start-sequence--alarm-clock-fade-from-black-not-camera-pull-back) — _scope_
|
||||
- [D-158: Frontal camera angle is default for character editor / mugshot UI](decisions/scope.md#d-158-frontal-camera-angle-is-default-for-character-editor--mugshot-ui) — _scope_
|
||||
- [D-159: Character body type enum: 5 types × 2 genders + 1 child skeleton (11 total)](decisions/scope.md#d-159-character-body-type-enum-5-types--2-genders--1-child-skeleton-11-total) — _scope_
|
||||
- [D-160: Body meshes must be segmented into 18 bone-group regions](decisions/architecture.md#d-160-body-meshes-must-be-segmented-into-18-bone-group-regions) — _architecture_
|
||||
- [D-161: Head is always a separate mesh on the Head bone](decisions/architecture.md#d-161-head-is-always-a-separate-mesh-on-the-head-bone) — _architecture_
|
||||
- [D-162: Clothing is pre-baked per body type via Blender Surface Deform](decisions/architecture.md#d-162-clothing-is-pre-baked-per-body-type-via-blender-surface-deform) — _architecture_
|
||||
- [D-163: Trellis generates unique heads per character via BoneAttachment3D](decisions/architecture.md#d-163-trellis-generates-unique-heads-per-character-via-boneattachment3d) — _architecture_
|
||||
- [D-164: Fork Quaternius skeleton, replace all body meshes](decisions/architecture.md#d-164-fork-quaternius-skeleton-replace-all-body-meshes) — _architecture_
|
||||
- [D-165: Character creator color palette: 5x9 muted hues + 1x9 neutral gray](decisions/scope.md#d-165-character-creator-color-palette-5x9-muted-hues--1x9-neutral-gray) — _scope_
|
||||
- [D-166: Development Cascade — 6-Phase First-Things-First Build Order](decisions/architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order) — _architecture_
|
||||
- [D-167: Heritage Roots Superseded — Corridor Cultural System Replaces Abstract Roots](decisions/content.md#d-167-heritage-roots-superseded--corridor-cultural-system-replaces-abstract-roots) — _content_
|
||||
- [D-168: Iserlohn (GJ-532c) planet name — keep, real-city origin documented](decisions/content.md#d-168-iserlohn-gj-532c-planet-name--keep-real-city-origin-documented) — _content_
|
||||
- [D-169: Implant UI component library — Control node tree with custom Theme](decisions/architecture.md#d-169-implant-ui-component-library--control-node-tree-with-custom-theme) — _architecture_
|
||||
- [D-170: HUD visibility groups — gameplay vs implant layers](decisions/architecture.md#d-170-hud-visibility-groups--gameplay-vs-implant-layers) — _architecture_
|
||||
- [D-171: Three-Currency System](decisions/economics.md#d-171-three-currency-system) — _economics_
|
||||
- [D-172: Currency Zone Initialization](decisions/economics.md#d-172-currency-zone-initialization) — _economics_
|
||||
- [D-173: Commodity Taxonomy](decisions/economics.md#d-173-commodity-taxonomy) — _economics_
|
||||
- [D-174: Shadow Economy Layer](decisions/economics.md#d-174-shadow-economy-layer) — _economics_
|
||||
- [D-175: Corporation Taxonomy and Prerequisite](decisions/economics.md#d-175-corporation-taxonomy-and-prerequisite) — _economics_
|
||||
- [D-176: Productivity Seeding](decisions/economics.md#d-176-productivity-seeding) — _economics_
|
||||
- [D-177: Productivity Constraints (Lore-Derived)](decisions/economics.md#d-177-productivity-constraints-lore-derived) — _economics_
|
||||
- [D-178: Economic Model Architecture](decisions/economics.md#d-178-economic-model-architecture) — _economics_
|
||||
- [D-179: Stability Acceptance Criteria](decisions/economics.md#d-179-stability-acceptance-criteria) — _economics_
|
||||
- [D-180: Event Input Port](decisions/economics.md#d-180-event-input-port) — _economics_
|
||||
- [D-181: Signal Vocabulary](decisions/economics.md#d-181-signal-vocabulary) — _economics_
|
||||
- [D-182: TOML Source of Truth for Economics Data](decisions/economics.md#d-182-toml-source-of-truth-for-economics-data) — _economics_
|
||||
- [D-183: Iterative Economics Development Cycle](decisions/economics.md#d-183-iterative-economics-development-cycle) — _economics_
|
||||
- [D-184: Commodity Catalog (36 Types)](decisions/economics.md#d-184-commodity-catalog-36-types) — _economics_
|
||||
- [D-185: Brands Are Not Commodities](decisions/economics.md#d-185-brands-are-not-commodities) — _economics_
|
||||
- [D-186: Gate Transmission Levels (Mass + Data + Energy)](decisions/economics.md#d-186-gate-transmission-levels-mass--data--energy) — _economics_
|
||||
- [D-187: Fusion Fuel as Intermediate (8:1 Water Yield)](decisions/economics.md#d-187-fusion-fuel-as-intermediate-81-water-yield) — _economics_
|
||||
- [D-188: Rename biome_summary to planet_class across codebase](decisions/architecture.md#d-188-rename-biome-summary-to-planet-class-across-codebase) — _architecture_
|
||||
- [D-189: Brand Layer Architecture](decisions/economics.md#d-189-brand-layer-architecture) — _economics_
|
||||
- [D-190: Brand Volume Calibration — Population-Relative Scale](decisions/economics.md#d-190-brand-volume-calibration--population-relative-scale) — _economics_
|
||||
- [D-191: Atlas of the Reach — Phase 3 Scope and Pipeline](decisions/architecture.md#d-191-atlas-of-the-reach--phase-3-scope-and-pipeline) — _architecture_
|
||||
- [D-192: Drop PROTOCOL_VERSION lockstep handshake](decisions/architecture.md#d-192-drop-protocol-version-lockstep-handshake) — _architecture_
|
||||
- [D-193: Lattice Commission — canonical long-form of the Commission](decisions/content.md#d-193-lattice-commission--canonical-long-form-of-the-commission) — _content_
|
||||
- [D-194: Three-Component District Mix Algorithm for City District Type Distribution](decisions/architecture.md#d-194-three-component-district-mix-algorithm-for-city-district-type-distribution) — _architecture_
|
||||
- [D-195: Attractor-Matching Compatibility Matrix for Generative City Placement](decisions/architecture.md#d-195-attractor-matching-compatibility-matrix-for-generative-city-placement) — _architecture_
|
||||
- [D-196: SettlementClass Enum and Latent Settlement Active/Ghost Logic](decisions/architecture.md#d-196-settlementclass-enum-and-latent-settlement-activeghost-logic) — _architecture_
|
||||
- [D-197: prosperity_baseline Derivation Formula with Topographic Gradient](decisions/architecture.md#d-197-prosperity-baseline-derivation-formula-with-topographic-gradient) — _architecture_
|
||||
- [D-198: Economic Simulation Independence from Layer 1–2 Spatial Data](decisions/architecture.md#d-198-economic-simulation-independence-from-layer-12-spatial-data) — _architecture_
|
||||
- [D-199: 6-Field Minimum Economic Read Set for City Generation Context](decisions/architecture.md#d-199-6-field-minimum-economic-read-set-for-city-generation-context) — _architecture_
|
||||
- [D-200: Three-Tier Execution Model (Build-Time / Runtime-Background / Runtime-On-Demand)](decisions/architecture.md#d-200-three-tier-execution-model-build-time--runtime-background--runtime-on-demand) — _architecture_
|
||||
- [D-201: Spatial Hierarchy — Eight Tiers with Locked Dimensions](decisions/architecture.md#d-201-spatial-hierarchy--eight-tiers-with-locked-dimensions) — _architecture_
|
||||
- [D-202: Heightmap BLOB Storage Schema (atlas_body_heightmaps)](decisions/architecture.md#d-202-heightmap-blob-storage-schema-atlas-body-heightmaps) — _architecture_
|
||||
- [D-203: BodyWorldState Bevy Resource with LRU Cache](decisions/architecture.md#d-203-bodyworldstate-bevy-resource-with-lru-cache) — _architecture_
|
||||
- [D-204: body_radius_km Column on bodies Table](decisions/architecture.md#d-204-body-radius-km-column-on-bodies-table) — _architecture_
|
||||
- [D-205: Province Boundary Pre-Computation (atlas_province_boundaries)](decisions/architecture.md#d-205-province-boundary-pre-computation-atlas-province-boundaries) — _architecture_
|
||||
- [D-206: Background Generation Priority Queue and Rayon Thread Infrastructure](decisions/architecture.md#d-206-background-generation-priority-queue-and-rayon-thread-infrastructure) — _architecture_
|
||||
- [D-207: Fully Generative Placement — markers.json Stripped to Topographic Features](decisions/architecture.md#d-207-fully-generative-placement--markersjson-stripped-to-topographic-features) — _architecture_
|
||||
- [D-208: D8 Priority-Flood Drainage Routing — Layer 1 Empty World](decisions/architecture.md#d-208-d8-priority-flood-drainage-routing--layer-1-empty-world) — _architecture_
|
||||
- [D-209: Geographic Feature Tag Extraction (7 Settlement Attractor Tags)](decisions/architecture.md#d-209-geographic-feature-tag-extraction-7-settlement-attractor-tags) — _architecture_
|
||||
- [D-210: Sub-Biome Variant Classification and terrain_modification_cost](decisions/architecture.md#d-210-sub-biome-variant-classification-and-terrain-modification-cost) — _architecture_
|
||||
- [D-211: Attractor-Matching Five-Phase Pipeline for Settlement Placement](decisions/architecture.md#d-211-attractor-matching-five-phase-pipeline-for-settlement-placement) — _architecture_
|
||||
- [D-212: TerritorialStatus Priority-Ordered Derivation Algorithm](decisions/architecture.md#d-212-territorialstatus-priority-ordered-derivation-algorithm) — _architecture_
|
||||
- [D-213: FoundingOrientation Enum and Spatial Grid Rotation](decisions/architecture.md#d-213-foundingorientation-enum-and-spatial-grid-rotation) — _architecture_
|
||||
- [D-214: PoliticalArchetype Enum and Settlement Spatial Character](decisions/architecture.md#d-214-politicalarchetype-enum-and-settlement-spatial-character) — _architecture_
|
||||
- [D-215: Five Explicit Political Archetype Spatial Arrangement Patterns](decisions/architecture.md#d-215-five-explicit-political-archetype-spatial-arrangement-patterns) — _architecture_
|
||||
- [D-216: BlockIrregularity from founding_age — Layout Age Character](decisions/architecture.md#d-216-blockirregularity-from-founding-age--layout-age-character) — _architecture_
|
||||
- [D-217: Tile Condition Thresholds (0.63 / 0.43 / 0.23)](decisions/architecture.md#d-217-tile-condition-thresholds-063--043--023) — _architecture_
|
||||
- [D-218: WorldTier Enum Canonical Values (Epicenter/Regional/Backwater/Passage/Waypoint)](decisions/architecture.md#d-218-worldtier-enum-canonical-values-epicenterregionalbackwaterpassagewaypoint) — _architecture_
|
||||
- [D-220: Settlement Density Model — Tile Scale, Density Classes, and Vertical Pressure](decisions/architecture.md#d-220-settlement-density-model--tile-scale-density-classes-and-vertical-pressure) — _architecture_
|
||||
- [D-221: Replace sprint workflow with kanban + milestones](decisions/process.md#d-221-replace-sprint-workflow-with-kanban--milestones) — _process_
|
||||
- [D-222: Spatial hierarchy and naming — Subtile to District, lore vs code](decisions/architecture.md#d-222-spatial-hierarchy-and-naming--subtile-to-district-lore-vs-code) — _architecture_
|
||||
- [D-223: Authored content as a flavored name pool — markers names-only, hand-authored templates removed](decisions/architecture.md#d-223-authored-content-as-a-flavored-name-pool--markers-names-only-hand-authored-templates-removed) — _architecture_
|
||||
- [D-224: SeedChain — deterministic seed-derivation contract](decisions/architecture.md#d-224-seedchain--deterministic-seed-derivation-contract) — _architecture_
|
||||
- [D-225: Atlas layer-stream proxy — compute-on-demand, mod-first (resolves Q-098)](decisions/architecture.md#d-225-atlas-layer-stream-proxy--compute-on-demand-mod-first-resolves-q-098) — _architecture_
|
||||
- [D-226: Live-pause inspection harness — agent-navigable, real-UI debug/review](decisions/architecture.md#d-226-live-pause-inspection-harness--agent-navigable-real-ui-debugreview) — _architecture_
|
||||
- [D-227: Deterministic-rebuild world model — derive-don't-store, cache, tile mutators, volumetric](decisions/architecture.md#d-227-deterministic-rebuild-world-model--derive-dont-store-cache-tile-mutators-volumetric) — _architecture_
|
||||
- [D-228: Composite tile schema — orthogonal axes, derived shape, region-level morphology](decisions/architecture.md#d-228-composite-tile-schema--orthogonal-axes-derived-shape-region-level-morphology) — _architecture_
|
||||
- [D-229: Building-property-tag schema — the step-3 fill output](decisions/architecture.md#d-229-building-property-tag-schema--the-step-3-fill-output) — _architecture_
|
||||
- [D-230: FillChunk two-phase execution model — background-plan / on-demand-derive](decisions/architecture.md#d-230-fillchunk-two-phase-execution-model--background-plan--on-demand-derive) — _architecture_
|
||||
- [D-231: DoorSpec and InteriorDescriptor — the step3→step4 boundary and the Phase-6 seed](decisions/architecture.md#d-231-doorspec-and-interiordescriptor--the-step3step4-boundary-and-the-phase-6-seed) — _architecture_
|
||||
- [D-232: Architecture-flavor — trait-template catalog (economically gated, seed-drawn, wiki-biased)](decisions/architecture.md#d-232-architecture-flavor--trait-template-catalog-economically-gated-seed-drawn-wiki-biased) — _architecture_
|
||||
- [D-233: Economic signal → block-fill vocabulary — `BulkClass` × `ProductionUbiquity`](decisions/architecture.md#d-233-economic-signal--block-fill-vocabulary--bulkclass--productionubiquity) — _architecture_
|
||||
- [D-234: Morphology zone → street and footprint constraints](decisions/architecture.md#d-234-morphology-zone--street-and-footprint-constraints) — _architecture_
|
||||
- [D-235: Building exterior visual grammar and material vocabulary](decisions/architecture.md#d-235-building-exterior-visual-grammar-and-material-vocabulary) — _architecture_
|
||||
- [D-236: Sol / GJ-0 — player-inaccessible, Atlas highest-level only, deeper Sol is future DLC](decisions/scope.md#d-236-sol--gj-0--player-inaccessible-atlas-highest-level-only-deeper-sol-is-future-dlc) — _scope_
|
||||
- [D-237: Authored per-system specialisation layer — `economic_specialization` + `cultural_specialization` + `dominant_faction`](decisions/architecture.md#d-237-authored-per-system-specialisation-layer--economic-specialization--cultural-specialization--dominant-faction) — _architecture_
|
||||
- [D-238: Symmetric shadowcasting (Albert Ford) selected for LOS computation](decisions/perception.md#d-238-symmetric-shadowcasting-albert-ford-selected-for-los-computation) — _perception_
|
||||
|
||||
## Open questions
|
||||
|
||||
- [Q-003: Art direction / presentation style](questions/perception.md#q-003-art-direction--presentation-style) — _perception_
|
||||
- [Q-008: Licensing / distribution model](questions/scope.md#q-008-licensing--distribution-model) — _scope_
|
||||
- [Q-010: Storyteller AI design](questions/content.md#q-010-storyteller-ai-design) — _content_
|
||||
- [Q-013: Line previewer temporal progression](questions/content.md#q-013-line-previewer-temporal-progression) — _content_
|
||||
- [Q-017: Triangle pressure threshold](questions/content.md#q-017-triangle-pressure-threshold) — _content_
|
||||
- [Q-019: Entity ID stability strategy](questions/architecture.md#q-019-entity-id-stability-strategy) — _architecture_
|
||||
- [Q-020: Multi-entity collision resolution](questions/architecture.md#q-020-multi-entity-collision-resolution) — _architecture_
|
||||
- [Q-021: Tick budget overflow policy](questions/architecture.md#q-021-tick-budget-overflow-policy) — _architecture_
|
||||
- [Q-022: NPC pathfinding cache eviction](questions/architecture.md#q-022-npc-pathfinding-cache-eviction) — _architecture_
|
||||
- [Q-023: Debug visualization scope](questions/architecture.md#q-023-debug-visualization-scope) — _architecture_
|
||||
- [Q-027: Fast-travel system design](questions/scope.md#q-027-fast-travel-system-design) — _scope_
|
||||
- [Q-029: Save file format design](questions/architecture.md#q-029-save-file-format-design) — _architecture_
|
||||
- [Q-030: Seed configuration schema](questions/architecture.md#q-030-seed-configuration-schema) — _architecture_
|
||||
- [Q-031: Combined content style guide](questions/content.md#q-031-combined-content-style-guide) — _content_
|
||||
- [Q-032: Cultural ingredients menu](questions/scope.md#q-032-cultural-ingredients-menu) — _scope_
|
||||
- [Q-033: Three-system NPC architecture](questions/content.md#q-033-three-system-npc-architecture) — _content_
|
||||
- [Q-034: PC archetypes](questions/scope.md#q-034-pc-archetypes) — _scope_
|
||||
- [Q-035: Sacred/Profane/Middle Kingdom framework](questions/scope.md#q-035-sacredprofanemiddle-kingdom-framework) — _scope_
|
||||
- [Q-036: District skeleton as generator output](questions/scope.md#q-036-district-skeleton-as-generator-output) — _scope_
|
||||
- [Q-037: Generator development pipeline](questions/scope.md#q-037-generator-development-pipeline) — _scope_
|
||||
- [Q-038: Authored content estimate at 300-world scale](questions/scope.md#q-038-authored-content-estimate-at-300-world-scale) — _scope_
|
||||
- [Q-042: Intra-system transport networks — passenger vs. freight, vehicles and modes](questions/content.md#q-042-intra-system-transport-networks--passenger-vs-freight-vehicles-and-modes) — _content_
|
||||
- [Q-045: Axis 11 — Network Footprint NPC tag](questions/content.md#q-045-axis-11--network-footprint-npc-tag) — _content_
|
||||
- [Q-047: Mobile environment social arc — structural representation of journey timeline](questions/content.md#q-047-mobile-environment-social-arc--structural-representation-of-journey-timeline) — _content_
|
||||
- [Q-048: DramaDensity enum naming — 3-level vs 5-level](questions/content.md#q-048-dramadensity-enum-naming--3-level-vs-5-level) — _content_
|
||||
- [Q-049: ObjectTag vocabulary co-maintenance — Miri and Araminta shared dependency](questions/content.md#q-049-objecttag-vocabulary-co-maintenance--miri-and-araminta-shared-dependency) — _content_
|
||||
- [Q-050: Assassination difficulty synthesis — formal spec combining stored baseline with on-demand computation](questions/content.md#q-050-assassination-difficulty-synthesis--formal-spec-combining-stored-baseline-with-on-demand-computation) — _content_
|
||||
- [Q-051: Speech bubble indicator over speaking NPCs](questions/perception.md#q-051-speech-bubble-indicator-over-speaking-npcs) — _perception_
|
||||
- [Q-052: Storyteller hint delivery — parallel diegetic channels when player does not act](questions/content.md#q-052-storyteller-hint-delivery--parallel-diegetic-channels-when-player-does-not-act) — _content_
|
||||
- [Q-053: Insert workspace boards — design philosophy and information architecture](questions/perception.md#q-053-insert-workspace-boards--design-philosophy-and-information-architecture) — _perception_
|
||||
- [Q-054: Insert workspace board — rendering primitive and data contract](questions/perception.md#q-054-insert-workspace-board--rendering-primitive-and-data-contract) — _perception_
|
||||
- [Q-056: Zone spec needs location_context field (surface/station/vessel)](questions/content.md#q-056-zone-spec-needs-location-context-field-surfacestationvessel) — _content_
|
||||
- [Q-058: Runtime behavior text serving system](questions/scope.md#q-058-runtime-behavior-text-serving-system) — _scope_
|
||||
- [Q-060: Can Surface Deform produce acceptable clothing at extreme body types?](questions/architecture.md#q-060-can-surface-deform-produce-acceptable-clothing-at-extreme-body-types) — _architecture_
|
||||
- [Q-061: How many base clothing meshes needed for v0.2 proof-of-life?](questions/scope.md#q-061-how-many-base-clothing-meshes-needed-for-v02-proof-of-life) — _scope_
|
||||
- [Q-062: What does Quaternius Source tier include for body types?](questions/scope.md#q-062-what-does-quaternius-source-tier-include-for-body-types) — _scope_
|
||||
- [Q-063: Footstep VFX system (Godot Asset Library #4122)](questions/architecture.md#q-063-footstep-vfx-system-godot-asset-library-4122) — _architecture_
|
||||
- [Q-065: Shooting mechanics — Deep RayCast 3D vs Ballistic Penetration System vs server-side](questions/architecture.md#q-065-shooting-mechanics--deep-raycast-3d-vs-ballistic-penetration-system-vs-server-side) — _architecture_
|
||||
- [Q-066: PathMesh3D for procedural environment geometry](questions/architecture.md#q-066-pathmesh3d-for-procedural-environment-geometry) — _architecture_
|
||||
- [Q-067: Vehicle physics for in-world transport](questions/architecture.md#q-067-vehicle-physics-for-in-world-transport) — _architecture_
|
||||
- [Q-068: Procedural terrain generation patterns — chunk loading and noise](questions/architecture.md#q-068-procedural-terrain-generation-patterns--chunk-loading-and-noise) — _architecture_
|
||||
- [Q-069: GPU cloth simulation for dynamic clothing](questions/architecture.md#q-069-gpu-cloth-simulation-for-dynamic-clothing) — _architecture_
|
||||
- [Q-070: NobodyWho LLM patterns vs our Rust voice pipeline](questions/architecture.md#q-070-nobodywho-llm-patterns-vs-our-rust-voice-pipeline) — _architecture_
|
||||
- [Q-071: Steam integration template for multiplayer lobbies](questions/architecture.md#q-071-steam-integration-template-for-multiplayer-lobbies) — _architecture_
|
||||
- [Q-072: BitTorrent for P2P asset/mod/world state distribution](questions/architecture.md#q-072-bittorrent-for-p2p-assetmodworld-state-distribution) — _architecture_
|
||||
- [Q-073: BehaviourToolkit patterns for Rust NPC AI](questions/architecture.md#q-073-behaviourtoolkit-patterns-for-rust-npc-ai) — _architecture_
|
||||
- [Q-074: Screenshot manager for in-game captures and bug reports](questions/architecture.md#q-074-screenshot-manager-for-in-game-captures-and-bug-reports) — _architecture_
|
||||
- [Q-075: RichText3D for in-world text rendering](questions/architecture.md#q-075-richtext3d-for-in-world-text-rendering) — _architecture_
|
||||
- [Q-076: DeformableMesh for runtime environment and damage variation](questions/architecture.md#q-076-deformablemesh-for-runtime-environment-and-damage-variation) — _architecture_
|
||||
- [Q-077: World generation architecture → PROMOTED TO WORKSHOP](questions/architecture.md#q-077-world-generation-architecture--promoted-to-workshop) — _architecture_
|
||||
- [Q-078: God rays for atmospheric lighting](questions/architecture.md#q-078-god-rays-for-atmospheric-lighting) — _architecture_
|
||||
- [Q-079: GridMapLayer — 2D tile logic driving 3D grid rendering](questions/architecture.md#q-079-gridmaplayer--2d-tile-logic-driving-3d-grid-rendering) — _architecture_
|
||||
- [Q-080: Mod loader architecture reference](questions/architecture.md#q-080-mod-loader-architecture-reference) — _architecture_
|
||||
- [Q-081: VisionCone3D for client-side fog refinement](questions/architecture.md#q-081-visioncone3d-for-client-side-fog-refinement) — _architecture_
|
||||
- [Q-082: VoronoiShatter for destruction effects](questions/architecture.md#q-082-voronoishatter-for-destruction-effects) — _architecture_
|
||||
- [Q-083: ThemeGen for dynamic insert styling and value-level theming](questions/architecture.md#q-083-themegen-for-dynamic-insert-styling-and-value-level-theming) — _architecture_
|
||||
- [Q-084: Isometric point-and-click navigation pattern](questions/architecture.md#q-084-isometric-point-and-click-navigation-pattern) — _architecture_
|
||||
- [Q-085: Portal rendering for spatial transitions and viewports](questions/architecture.md#q-085-portal-rendering-for-spatial-transitions-and-viewports) — _architecture_
|
||||
- [Q-086: Day/night cycle — server time driving client lighting](questions/architecture.md#q-086-daynight-cycle--server-time-driving-client-lighting) — _architecture_
|
||||
- [Q-087: Water shader for environment zones](questions/architecture.md#q-087-water-shader-for-environment-zones) — _architecture_
|
||||
- [Q-088: Spatial audio for information-aware sound](questions/architecture.md#q-088-spatial-audio-for-information-aware-sound) — _architecture_
|
||||
- [Q-089: Procedural star rendering for space viewports and star map](questions/architecture.md#q-089-procedural-star-rendering-for-space-viewports-and-star-map) — _architecture_
|
||||
- [Q-090: Markov chains for procedural name/text generation in Rust](questions/architecture.md#q-090-markov-chains-for-procedural-nametext-generation-in-rust) — _architecture_
|
||||
- [Q-091: Event-driven audio system](questions/architecture.md#q-091-event-driven-audio-system) — _architecture_
|
||||
- [Q-092: Modular settings menu as foundation for #735](questions/architecture.md#q-092-modular-settings-menu-as-foundation-for-735) — _architecture_
|
||||
- [Q-093: Tile-based exploration map in player insert (Google Maps for the implant)](questions/architecture.md#q-093-tile-based-exploration-map-in-player-insert-google-maps-for-the-implant) — _architecture_
|
||||
- [Q-097: Strip "What They Don't Talk About" from corporation pages](questions/content.md#q-097-strip-what-they-dont-talk-about-from-corporation-pages) — _content_
|
||||
- [Q-099: Mod content catalog — body rows / terrain_reference overlay for systems.db](questions/architecture.md#q-099-mod-content-catalog--body-rows--terrain-reference-overlay-for-systemsdb) — _architecture_
|
||||
- [Q-101: Refinement / derivation contract — coarse hint → fine geometry + morphology algorithm family](questions/architecture.md#q-101-refinement--derivation-contract--coarse-hint--fine-geometry--morphology-algorithm-family) — _architecture_
|
||||
- [Q-102: Cohesion-matrix algorithm — seam-free continuous variation](questions/architecture.md#q-102-cohesion-matrix-algorithm--seam-free-continuous-variation) — _architecture_
|
||||
- [Q-103: Tile-mutator op schema](questions/architecture.md#q-103-tile-mutator-op-schema) — _architecture_
|
||||
- [Q-105: Region seasonal/clock state — the shared cheap-dynamism source](questions/architecture.md#q-105-region-seasonalclock-state--the-shared-cheap-dynamism-source) — _architecture_
|
||||
- [Q-107: Wiki → Atlas content-set consolidation](questions/architecture.md#q-107-wiki--atlas-content-set-consolidation) — _architecture_
|
||||
- [Q-108: Subterranean / domed / sealed-habitat settlement morphology — does the built-world fill model need a surface-vs-enclosed branch](questions/architecture.md#q-108-subterranean--domed--sealed-habitat-settlement-morphology--does-the-built-world-fill-model-need-a-surface-vs-enclosed-branch) — _architecture_
|
||||
- [Q-109: Cascade generation-source dispatch — planetary / station / mod-DLC-forked / save-only](questions/architecture.md#q-109-cascade-generation-source-dispatch--planetary--station--mod-dlc-forked--save-only) — _architecture_
|
||||
|
||||
## Resolved questions
|
||||
|
||||
- [Q-001: Game engine selection](questions/architecture.md#q-001-game-engine-selection) — _architecture_
|
||||
- [Q-002: Scope of v0.1 playable prototype](questions/scope.md#q-002-scope-of-v01-playable-prototype) — _scope_
|
||||
- [Q-004: One campaign spanning all eras or separate era scenarios?](questions/scope.md#q-004-one-campaign-spanning-all-eras-or-separate-era-scenarios) — _scope_
|
||||
- [Q-005: Scale for prototype - locations, characters, factions](questions/scope.md#q-005-scale-for-prototype---locations-characters-factions) — _scope_
|
||||
- [Q-006: Multiplayer or single-player only?](questions/architecture.md#q-006-multiplayer-or-single-player-only) — _architecture_
|
||||
- [Q-007: Target platform(s)](questions/scope.md#q-007-target-platforms) — _scope_
|
||||
- [Q-009: Time system](questions/architecture.md#q-009-time-system) — _architecture_
|
||||
- [Q-011: Character selection and playable characters](questions/scope.md#q-011-character-selection-and-playable-characters) — _scope_
|
||||
- [Q-012: Generation expansion method for dialogue](questions/content.md#q-012-generation-expansion-method-for-dialogue) — _content_
|
||||
- [Q-014: Audio timing with monologue chime](questions/perception.md#q-014-audio-timing-with-monologue-chime) — _perception_
|
||||
- [Q-015: Generation expansion for THE FRIEND content](questions/content.md#q-015-generation-expansion-for-the-friend-content) — _content_
|
||||
- [Q-016: Knowledge hierarchy for monologue prerequisites](questions/perception.md#q-016-knowledge-hierarchy-for-monologue-prerequisites) — _perception_
|
||||
- [Q-018: Shadowcasting algorithm selection](questions/architecture.md#q-018-shadowcasting-algorithm-selection) — _architecture_
|
||||
- [Q-024: Gossip propagation timing](questions/perception.md#q-024-gossip-propagation-timing) — _perception_
|
||||
- [Q-025: Knowledge graph cap and eviction strategy](questions/perception.md#q-025-knowledge-graph-cap-and-eviction-strategy) — _perception_
|
||||
- [Q-026: Contradiction detection algorithm](questions/perception.md#q-026-contradiction-detection-algorithm) — _perception_
|
||||
- [Q-028: Collision-resistant line IDs for auto-generated NPCs](questions/content.md#q-028-collision-resistant-line-ids-for-auto-generated-npcs) — _content_
|
||||
- [Q-039: Gate topology generation](questions/scope.md#q-039-gate-topology-generation) — _scope_
|
||||
- [Q-040: Gate dual-use topology — freight and commuter on shared span gate infrastructure](questions/content.md#q-040-gate-dual-use-topology--freight-and-commuter-on-shared-span-gate-infrastructure) — _content_
|
||||
- [Q-041: Interstellar travel mechanics — horizon stations and gate architecture](questions/content.md#q-041-interstellar-travel-mechanics--horizon-stations-and-gate-architecture) — _content_
|
||||
- [Q-043: Station internal transit — intra-station transport system between districts](questions/content.md#q-043-station-internal-transit--intra-station-transport-system-between-districts) — _content_
|
||||
- [Q-044: Gate-train integration — do transport vehicles use gates directly or transfer on each side](questions/content.md#q-044-gate-train-integration--do-transport-vehicles-use-gates-directly-or-transfer-on-each-side) — _content_
|
||||
- [Q-046: Departure schedule model — departure windows as generator output for docked vessels](questions/architecture.md#q-046-departure-schedule-model--departure-windows-as-generator-output-for-docked-vessels) — _architecture_
|
||||
- [Q-057: Composable behavior generation — decompose culture × role × context into assembled behaviors](questions/content.md#q-057-composable-behavior-generation--decompose-culture--role--context-into-assembled-behaviors) — _content_
|
||||
- [Q-059: PlatformInfo full interface scope](questions/architecture.md#q-059-platforminfo-full-interface-scope) — _architecture_
|
||||
- [Q-064: 3D planet generator for wiki system screenshots](questions/architecture.md#q-064-3d-planet-generator-for-wiki-system-screenshots) — _architecture_
|
||||
- [Q-094: Chart widgets for economy/market insert UI](questions/architecture.md#q-094-chart-widgets-for-economymarket-insert-ui) — _architecture_
|
||||
- [Q-095: Commission formal name — authoritative designation](questions/content.md#q-095-commission-formal-name--authoritative-designation) — _content_
|
||||
- [Q-096: Replace sprint workflow with kanban + milestones](questions/process.md#q-096-replace-sprint-workflow-with-kanban--milestones) — _process_
|
||||
- [Q-098: Persistence of generated river/city mapping outputs](questions/architecture.md#q-098-persistence-of-generated-rivercity-mapping-outputs) — _architecture_
|
||||
- [Q-100: Biome authority — Python sim vs Rust cascade](questions/architecture.md#q-100-biome-authority--python-sim-vs-rust-cascade) — _architecture_
|
||||
- [Q-104: Floor-index ↔ absolute voxel-z coordinate mapping](questions/architecture.md#q-104-floor-index--absolute-voxel-z-coordinate-mapping) — _architecture_
|
||||
- [Q-106: Era-band stacking depth for layered architecture-flavor](questions/architecture.md#q-106-era-band-stacking-depth-for-layered-architecture-flavor) — _architecture_
|
||||
|
||||
## Rejected
|
||||
|
||||
- [R-001: Stellaris mod](rejected/architecture.md#r-001-stellaris-mod) — _architecture_
|
||||
- [R-002: CK3 total conversion](rejected/architecture.md#r-002-ck3-total-conversion) — _architecture_
|
||||
- [R-003: Other existing games (Distant Worlds 2, GalCiv IV, Sins of a Solar Empire II, Victoria 3)](rejected/architecture.md#r-003-other-existing-games-distant-worlds-2-galciv-iv-sins-of-a-solar-empire-ii-victoria-3) — _architecture_
|
||||
- [R-004: Pure Bevy (Rust) — no Godot](rejected/architecture.md#r-004-pure-bevy-rust--no-godot) — _architecture_
|
||||
- [R-005: Pure Godot (GDScript or C#)](rejected/architecture.md#r-005-pure-godot-gdscript-or-c) — _architecture_
|
||||
- [R-006: Godot + Rust via GDExtension](rejected/architecture.md#r-006-godot--rust-via-gdextension) — _architecture_
|
||||
- [R-007: Godot + C++ via GDExtension](rejected/architecture.md#r-007-godot--c-via-gdextension) — _architecture_
|
||||
- [R-008: Fyrox (pure Rust engine)](rejected/architecture.md#r-008-fyrox-pure-rust-engine) — _architecture_
|
||||
- [R-009: Custom framework (Rust + raylib/macroquad)](rejected/architecture.md#r-009-custom-framework-rust--raylibmacroquad) — _architecture_
|
||||
- [R-010: protobuf for client-server serialization](rejected/architecture.md#r-010-protobuf-for-client-server-serialization) — _architecture_
|
||||
- [R-011: Single currency for Phase 2 economics](rejected/economics.md#r-011-single-currency-for-phase-2-economics) — _economics_
|
||||
- [R-012: Overheard NPC conversation system (D-078) — scrapped](rejected/perception.md#r-012-overheard-npc-conversation-system-d-078--scrapped) — _perception_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,624 @@
|
||||
# Content Decisions
|
||||
|
||||
How narrative, NPCs, and world content are created: content tiers, NPC generation, templates, dialogue, population, audio aesthetic identity.
|
||||
|
||||
---
|
||||
|
||||
### D-023: Three-tier content model with life-sim substrate
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** The game uses a three-tier content architecture: Tier 1 (authored drama modules drawn from a pool at game start — plural, optional, relocatable), Tier 2 (templated content with combinatorial variation — both intrigue and life templates), Tier 3 (procedural filler with systemic hooks for Tier 2 colonization). Daily life is the substrate; conspiracies are weather. Players can investigate, pursue careers/relationships, or both. All are valid playthroughs. The storyteller activates Tier 1 modules based on player proximity and engagement, not timers.
|
||||
- **Rationale:** A galaxy-spanning game needs content architecture that scales without hand-crafting everything. The life-sim substrate creates attachment that gives conspiracies emotional weight. Pool-based Tier 1 modules enable replayability and DLC expansion.
|
||||
- **Raised by:** Team Leader (Jeroen), with full team endorsement across 3 rounds
|
||||
- **Dissent:** None
|
||||
- **Amendment (2026-03-05, Where's the Fun? Workshop):** Tier 1 "authored drama modules" concept is deferred for v0.2. [D-114](scope.md#d-114-v02-proof-of-life--generator--graphics-not-hand-built-slice) (generator-first proof-of-life) and [D-127](#d-127-player-choices-are-the-content--rimworld-model-job-as-rails) (player choices are the content) establish that v0.2 ships zero authored drama modules. The three-tier architecture remains valid for the full game, but the Tier 1 pool is empty by design in v0.2 — generator-first validates Tier 2 and Tier 3 before Tier 1 modules are authored. Tier 1 will be authored after the generator spike (D-119) proves legible characters and readable relationships.
|
||||
|
||||
### D-024: NPC generation model — 10 axes + combat component
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** NPCs are generated with 10 axes: 7 essential (Want, Secret/vulnerability, Relationships 1-3, Tolerance threshold, Daily routine, Information inventory, Contentment) and 3 supporting (Personality traits 2-3, Tell system, Skill set including combat tag). Combat capability lives as an optional CombatCapability ECS component triggered by the combat-trained skill tag, not as an axis. Faction loyalty is folded into Relationships+Secret (discoverable, not labeled). Romantic profile is folded into Want+Personality+compatibility tag. Cultural/origin template is generation-time flavor, not a runtime axis. Triangles (3 NPCs with conflicting interests) are the atomic unit of social intrigue — 2 per template minimum, 1 cross-template.
|
||||
- **Rationale:** Axes that create contradictions within NPCs produce player decisions. The 5 key interactions (Want×Secret, Routine×Secret, Tolerance×Relationships, Want×Relationships, Personality×Tolerance) drive the full investigation-and-social gameplay loop. Contentment axis (proposed by Gore) connects generated NPCs to the thematic spine. Combat as component follows the same pattern as perception modes ([D-017](perception.md#d-017-perception-modes-as-character-build-system)).
|
||||
- **Raised by:** Gestalt (consolidation), Gore (contentment axis), Paula (triangle model), Tyre (combat component). Full team endorsed.
|
||||
- **Dissent:** None
|
||||
- **Amendment (2026-03-05, Where's the Fun? Workshop):** The 10-axis model and core generation logic survive. However, [D-122](#d-122-all-npcs-generated--no-named-hand-authored-characters) (all NPCs generated) removes all named hand-authored NPCs from v0.2. Named NPCs and hand-authored triangles are now generator outputs, not authored content. The 10 axes apply to all generated NPCs. The `NpcBlueprint` struct (Tyre prerequisite for D-119 generator spike) must encode these axes as generator output format. Cultural/origin template (previously called "generation-time flavor") is now the primary driver per [D-128](#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) and [D-121](#d-121-voice-is-culture-driven--job-as-modifier).
|
||||
|
||||
### D-025: Social site / functional cluster as atomic template unit
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** The atomic Tier 2 template unit is a "social site" (mechanical term) housed in a "functional cluster" (spatial term): 4-8 NPCs who regularly interact, within 15-40 tiles of connected space with internal sightlines. Social group defines systemic identity (who, what triangles). Physical cluster defines spatial identity (sightlines, overhearing, public/private). Templates define roles; NPCs fill roles. One NPC can hold roles in multiple social sites. NPC identity is independent of template instantiation. NPCs are owned by exactly one template with reference links (carrying relationship metadata) to others.
|
||||
- **Rationale:** Life in the Settled Reach happens in clusters of connected spaces. The functional cluster is the natural unit of social observation, which is the natural unit of gameplay. Single-ownership with reference links prevents lifecycle conflicts while enabling cross-template contamination.
|
||||
- **Raised by:** Gestalt (social site), Miri (functional cluster), Tyre (ownership model), Paula (reference metadata)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-028: Dialogue architecture — tagged line pools with four relational layers
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** Dialogue uses tagged line pools with systemic selection, not branching trees. Four relational layers, all planned from authoring day one, built in sequence: (1) Access tiers — insider/outsider/authority/peer filter on every line, (2) Relationship history — interaction log modifying greeting and topic selection, (3) Trust-gated gossip — three disclosure tiers per role (surface/real/secret), (4) Unprompted disclosure — NPCs volunteer information weighted by trust and mood. Trait modifiers (not per-trait scripts) reshape delivery — base lines + trait transformation guide per template. Template content packs as writing deliverable: role voice kits, situation scripts, monologue hooks, environmental text, trait transformation guide. ~165-210 authored lines per Tier 2 template, generation-expanded 4x. Social dialogue budgeted 40% more than investigation. Line previewer CLI required as authoring tool and regression test harness.
|
||||
- **Rationale:** All four layers are load-bearing — each enriches the previous ones. Tagged pools avoid combinatorial explosion while trait modifiers produce character variety. The generation pass (write 10, generate 40) scales authored content. Every memorable line needs a human hand; the generation pass fills the background.
|
||||
- **Raised by:** Mellanie (authoring model), Paula (relational layers), Gestalt (axis-to-pipeline mapping), Tyre (previewer feasibility)
|
||||
- **Dissent:** None on model. Minor ordering difference: Mellanie front-loads access tiers (structural), Paula front-loads relationship history (narrative). Both sequences work.
|
||||
- **Amendment (2026-03-05, Where's the Fun? Workshop):** The tagged line pool architecture survives for authored content, but the v0.2 NPC content pipeline pivots to AI-assisted templating. [D-123](#d-123-generative-ai-for-npc-content-templating-via-culture-vectors) (generative AI for NPC content) replaces the hand-authoring model for NPC dialogue pools. The four relational layers remain valid as a selection architecture, but pools will be populated by template assembly (culture vectors + job modifiers + AI generation) rather than hand-authoring. Hand-authored content (anchor lines per D-092, player monologue) remains hand-authored.
|
||||
|
||||
### D-029: Population entanglement ratio — 30/50/20
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** NPC population split: ~30% truly flat (routine + greeting, social wallpaper), ~50% mundane triangles (neighbor disputes, workplace rivalries, relationship tensions — no conspiracy connection), ~20% entangled with intrigue content. The entanglement rate varies per seed to prevent metagaming calibration. Module attachment to known NPCs uses a ~60-70/30-40 ratio (known vs stranger), also varying per seed. The unentangled majority is both thematically essential ("is this enough?" needs honest counterweight) and mechanically essential (investigation signal requires noise floor).
|
||||
- **Cross-reference:** Simulation tier budgets in [D-026](architecture.md#d-026-simulation-tiers-with-timestamp-based-eviction).
|
||||
- **Rationale:** If every NPC is suspicious, investigation collapses. The mundane triangles ARE the life-sim game — hours of play that never touch conspiracy. Variable entanglement rate defeats metagaming across playthroughs. Quiet life must feel genuinely good, not empty.
|
||||
- **Raised by:** Gore (thematic), Paula (30/50/20 split), Nigel (anti-metagaming), Team Leader (majority unentangled)
|
||||
- **Dissent:** None
|
||||
- **Amendment (2026-03-05, Where's the Fun? Workshop):** The 30/50/20 population split rationale survives but implementation context changes. [D-122](#d-122-all-npcs-generated--no-named-hand-authored-characters) (all NPCs generated) means no NPC is hand-authored. The "entangled 20%" are generated NPCs whose triangles happen to be flagged for intrigue content. For the tycoon v0.2 bookmark ([D-117](scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content)), the split applies to economic, social, and mundane triangles rather than investigation-intrigue triangles. The specific ratios will be revisited after the generator spike ([D-119](scope.md#d-119-generator-spike-confirmed-for-sprint-25--critical-path)) proves what population density the generator can sustain.
|
||||
|
||||
### D-032: Separate monologue pools per character [SUPERSEDED — deferred to Phase 6]
|
||||
- **Date:** 2026-02-11
|
||||
- **Superseded by:** Development cascade (CLAUDE.md) — character/NPC monologue content is Phase 6 detail-coloring, below the current Phase 1 (wiki content). The smuggler/detective archetype enum and its hard-partitioned monologue pools were pre-cascade scaffolding and have been fully stripped from the server codebase (Sprint 37, #878, PR #137). The original D-117 supersession framing (single tycoon character in v0.2) is itself obsolete now that v0.2 is dropped (CLAUDE.md: "v0.2 target is dropped"). The partition *design pattern* is preserved in this record for when culture-driven / generator-produced monologue is reintroduced in Phase 6, but no corresponding code or content exists today.
|
||||
- **Amendment (2026-04-22, Sprint 37, PR #137):** Monologue pool selection is now unkeyed by archetype until a Phase 6 character system exists. `MonologueState.character` field and `CharacterArchetype` enum deleted from `server/src/bridge/types.rs`, `server/src/simulation/monologue.rs`, observer relabeling logic, and `server/content/modules/tier1/smuggling_ring_v0_1.yaml`. Uniform single-pool behavior is the intended end state pre-Phase-6 — not scaffolding deferred in place with a stub, but retired pending the real character system. Lead override recorded in `docs/architecture/sprint-37-878-audit.md` (2026-04-21 override section). Reintroduction gate: a confirmed Phase 6 character-model design is a prerequisite before this decision is revived.
|
||||
- **Decision:** Internal monologue content is hard-partitioned by playable character. The smuggler and detective have completely separate monologue pools — no shared lines. The `character` tag on monologue lines is a hard partition, not a filter. File structure uses separate files per character per location (e.g., `monologue-smuggler.yaml`, `monologue-detective.yaml`).
|
||||
- **Rationale:** Shared monologue would dilute character voice and undermine the dual-lens experience. Each character's internal voice must be independently coherent. Same trigger, different pool — this is how mirror moments work without either pool knowing about the other.
|
||||
- **Cross-reference:** Dialogue lines remain character-agnostic — the access tier system (D-028 Layer 1) handles per-character filtering without separate pools.
|
||||
- **Raised by:** Mellanie (Round 1 proposal), confirmed as non-negotiable by project lead
|
||||
- **Dissent:** None
|
||||
|
||||
### D-034: THE FRIEND — production-level NPC pattern
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** Each playable character has one "FRIEND" NPC — a production-level complex character that exercises every content and systems pipeline at full depth. THE FRIEND is the emotional centerpiece of v0.1 and carries D-027 success criterion #3 ("player names an NPC they felt conflicted about"). THE FRIEND follows a reusable pattern: 3+ relationship phases (warmth → trust → doubt → conflict), observable contradiction discoverable through observation not dialogue, sympathetic motivation, no clean resolution, dual-lens resonance, triangle integration, tell progression, and dialogue shift pre/post discovery.
|
||||
- **Assignments:**
|
||||
- **Smuggler's FRIEND: Kael Davan** — dock worker, ring member, smuggler's closest colleague. Contradiction: meeting with unknown contact in restricted corridor (trying to exit the ring to protect partner Naia). Exercises: full 10-axis model, multi-phase dialogue, tell system, named monologue, dual-lens notes.
|
||||
- **Detective's FRIEND: Sera Venn** — Commission field tech, bar regular, detective's social anchor. Contradiction: avoids Torek Lintar (sitting on unreported evidence about Kael's manifest discrepancies, protecting friend Naia). Exercises: institutional access + personal loyalty conflict, avoidance pattern as tell, trust-contamination arc.
|
||||
- **Content requirements per FRIEND NPC:** ~70-100 authored lines (25-35 dialogue, 15-20 trust-gated, 5-8 unprompted, 10-15 monologue per character, 5-8 tell observation, 3-5 contradiction discovery). No generation expansion — all hand-authored.
|
||||
- **Cross-reference:** NPC triangle model ([D-024](#d-024-npc-generation-model--10-axes--combat-component)), relationship web ([D-029](#d-029-population-entanglement-ratio--305020)), vertical slice criteria ([D-027](scope.md#d-027-vertical-slice--smuggler--detective-two-character-proof))
|
||||
- **Raised by:** Ozzie (emotional concept, Round 1), Paula (structural design and both FRIEND profiles, Round 2), project lead (confirmed, directive #4). Sera Venn confirmed by project lead over Mellanie's alternative proposal (Lera Sessik).
|
||||
- **Dissent:** Mellanie proposed Lera Sessik (bar owner) as detective's FRIEND. Project lead selected Paula's Sera Venn design. Lera remains bar owner / mundane triangle member.
|
||||
- **Amendment (2026-03-05, Where's the Fun? Workshop):** The FRIEND pattern (3+ relationship phases, observable contradiction, sympathetic motivation, no clean resolution, tell progression, dual-lens resonance) survives as a generator template for v0.2. Kael Davan and Sera Venn do not exist — [D-122](#d-122-all-npcs-generated--no-named-hand-authored-characters) eliminates all named hand-authored NPCs. In v0.2, the FRIEND role is filled by a generated NPC whose generator profile matches the FRIEND pattern template. The FRIEND pattern is now a generator instruction set, not an authoring assignment. Workshop convergence note: warmth with generated NPCs is earned through observed relationship progression, not authored backstory — this may produce stronger emotional investment than the hand-authored approach (Paula, Mellanie in Where's the Fun? Workshop §Phase Zero).
|
||||
|
||||
### D-035: Converged tag taxonomy for dialogue and monologue line pools
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** Tagged line pools (D-028) use a converged taxonomy of 6 structural tags + 3 selection tags per dialogue line. Monologue lines add 3 additional tags.
|
||||
- **Structural tags (required on every dialogue line):**
|
||||
- `id` (string): `{template}_{d|m|e}_{###}` — machine-parseable, stable
|
||||
- `text` (string): the authored line
|
||||
- `role` (enum): template-defined role (not NPC name — NPC assignment is runtime)
|
||||
- `access` (list\<enum\>): `public`, `insider`, `authority`, `peer`, `hostile` — D-028 Layer 1 hard filter
|
||||
- `trust` (enum): `surface`, `real`, `secret` — D-028 Layer 3 hard filter
|
||||
- `situation` (list\<enum\>): 13 situations for v0.1 — D-028 Layer 2 context filter
|
||||
- **Selection tags (recommended, defaults if empty):**
|
||||
- `topic` (list\<enum\>): 9 topics for v0.1 — D-028 Layer 4 weighted selection
|
||||
- `mood` (list\<enum\>): 8 moods for v0.1 — D-028 Layer 4 weighted selection
|
||||
- `tags` (list\<string\>): freeform escape hatch for author intent
|
||||
- **Monologue-specific additions:**
|
||||
- `character` (enum): historically `smuggler`, `detective` — removed. Per [D-032 SUPERSEDED] and the development cascade (CLAUDE.md), character-partitioned monologue is Phase 6 and has been stripped from the codebase (Sprint 37, #878). Field is unused; do not reintroduce without a confirmed Phase 6 design.
|
||||
- `trigger` (enum): 9 trigger types (enter_location, observe_npc, hear_sound, observe_anomaly, post_conversation, discover_evidence, witness_interaction, time_idle, return_visit)
|
||||
- `prerequisite` (map or null): knowledge state gate
|
||||
- **Authoring-only tags (not consumed by engine):** `dual_lens` (map, per-character notes), `notes` (string)
|
||||
- **Key design choices:** Location and content type dropped from per-line tags (implicit from directory structure and file naming). `access` is list (a line can be eligible for multiple tiers). `topic` and `mood` are lists. Layer 2 relationship history expressed through engine-state-to-situation mapping, not per-line tags.
|
||||
- **Cross-reference:** Dialogue architecture ([D-028](#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers))
|
||||
- **Raised by:** Gestalt (schema design, Round 1/2), Mellanie (authoring validation, Round 1/2). Converged across both agents in Round 2.
|
||||
- **Dissent:** None. Minor consolidations: Mellanie's 8 moods mapped to Gestalt's 8 (different names, same concepts). Mellanie's `crime` topic deliberately excluded (NPCs think of it as `cargo` or `money`).
|
||||
- **Amendment (Sprint 8):** `focused` added as 9th mood (used in Kael dialogue at The Terminal and maintenance corridors). `greeting` added as 14th situation (used in PC dialogue pools for initial contact lines). Schema updated to match.
|
||||
- **Amendment (Sprint 14):** Mood vocabulary renamed to match voice guide (monologue-voice-guide.md). Old → new: `fond`→`warm`, `comfortable`→`content`, `worried`→`anxious`, `concerned`→`frustrated`. Dropped: `analytical` (merged into `focused`), `conflicted` (modeled as `suspicious`+`warm` collision). Added: `hostile`. Final 8 moods: `anxious`, `frustrated`, `content`, `suspicious`, `warm`, `hostile`, `relieved`, `focused`. Neutral = untagged.
|
||||
- **Amendment (Sprint 24):** `triangle_activated` added as 15th situation (fires post-TriangleActivated when player observes anchor NPCs). Two freeform tags registered as conventions: `triangle-signal` (line is part of the triangle activation sequence) and `tell-observation` (line observes a behavioral tell without naming its cause). `npc_in_los` prerequisite added for LOS-gated monologue lines. Schema updated to match.
|
||||
- **Amendment (Sprint 15):** Line ID namespace changed from location-scoped to NPC-scoped. Old scheme: `{location_slug}_{d|m}_{###}` (e.g., `the-terminal_d_039`) — all NPCs at a location share one ID sequence, requiring cross-file coordination and causing collisions at scale. New scheme: `{npc-slug}_{d|m}_{###}` for dialogue, `{npc-slug}_m_{s|d}_{###}` for monologue (e.g., `kael-davan_d_001`, `dock-worker_d_001`). Each NPC's IDs are independent — no cross-file coordination needed. Auto-generated NPCs use their generated slug. Schema regex patterns unchanged (prefix is still `^[a-z][a-z0-9-]*`), only the `description` field and convention documentation update. Migration: mechanical rename of all existing line IDs across ~20 dialogue files and monologue pools.
|
||||
- **Amendment (2026-04-22, Sprint 37, PR #137):** The `character` monologue-specific tag (historically `smuggler | detective`) is retired pending a Phase 6 character-model design — not deferred in place with a stub enum. Per the development cascade (CLAUDE.md), character-partitioned monologue is Phase 6 detail-coloring; the codebase has been stripped of the `CharacterArchetype` enum and the `MonologueState.character` field that keyed pool selection (#878). Pool selection is now archetype-independent. Authoring files that carry historical `character:` tags are content artifacts and will be re-evaluated when the Phase 6 character system is designed; engine consumption of the field is gone. Reintroduction gate: a confirmed Phase 6 character-model design is a prerequisite. See `docs/architecture/sprint-37-878-audit.md` (lead override section) for the cascade rationale.
|
||||
|
||||
### D-036: Sova Transit District / Van Maanen's Star as v0.1 setting
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** The v0.1 vertical slice is set in Sova Transit District, a freight logistics hub on Station Sova in Van Maanen's Star. This is the first concrete, named star system in The Settled Reach. Van Maanen's Star is a mid-Reach G3V system, ~180 years settled, population ~2.4 million, working-class pragmatic culture. Station Sova is a logistics hub (~12,000 population). Sova Transit District is a 40-year-old prefab-modular-retrofitted freight district with three social sites: The Terminal (logistics hub), The Last Shift (bar), and maintenance corridors/smuggling spaces.
|
||||
- **Setting details (canonical):**
|
||||
- NPC naming: Van Maanen's Star conventions — compact, consonant-heavy, first-name-primary in social contexts (Kael, Voss, Lera, Torek, Drin, Maret, Naia, Sera, Nils, Kosse, Pael, Tev, Ren)
|
||||
- Bar naming: "The Last Shift" (official), "Lera's" (informal, used by regulars)
|
||||
- Atmosphere: "quotidian-with-undertow" — comfortable enough to be complacent, tight enough that extra income is tempting
|
||||
- Sensory: span gate hum, industrial lubricant, recycled air, cargo machinery
|
||||
- **Cross-reference:** Vertical slice ([D-027](scope.md#d-027-vertical-slice--smuggler--detective-two-character-proof)), contraband ([D-037](#d-037-contraband-specification))
|
||||
- **Raised by:** Miri (Sova setting brief, Round 1; Van Maanen's Star profile, Round 2), project lead (confirmed as worldbuilding milestone, directive #6)
|
||||
- **Dissent:** None
|
||||
- **Amendment (2026-03-05, Where's the Fun? Workshop):** Station Sova / Van Maanen's Star confirmed as the v0.2 setting. [D-128](#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) makes Van Maanen's Star culture the cultural context for the tycoon bookmark — Van Maanen's Star IS Van Maanen's Star culture by default. The setting details (naming conventions, atmosphere, sensory palette) survive as generator inputs and culture profile content. However, the Sova Transit District spatial layout (D-093) was designed for the v0.1 hand-built slice. v0.2 generates the location via the generator ([D-114](scope.md#d-114-v02-proof-of-life--generator--graphics-not-hand-built-slice)); the Van Maanen's Star culture profile (Miri prerequisite for [D-119](scope.md#d-119-generator-spike-confirmed-for-sprint-25--critical-path)) captures the setting identity as generator inputs. Sova remains the canonical example system and the first culture profile to author.
|
||||
|
||||
### D-037: Contraband specification — unlicensed lattice components
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** The primary contraband in the v0.1 smuggling scenario is unlicensed lattice components — aftermarket neural lattice modifications that bypass Commission regulation. Secondary contraband: medical-grade neural lattice replacements (diverted from Syndic supply chains) and Severance counter-surveillance technology.
|
||||
- **Moral dimension:** The ring is smuggling *access*, not weapons. People want better lattice capability than Commission-regulated channels provide. Medical-grade replacements serve people whose lattices are degrading and who can't afford institutional replacement. This creates genuine moral ambiguity: the smuggler isn't a villain, they're providing a service the legitimate system won't.
|
||||
- **Gameplay relevance:** Lattice components connect to the perception system (D-017) — a smuggled upgrade could theoretically change what the player perceives. Manifest discrepancies are the primary investigation vector. The detective's analytical lattice can flag cargo anomalies.
|
||||
- **Cross-reference:** Perception modes ([D-017](perception.md#d-017-perception-modes-as-character-build-system)), setting ([D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting))
|
||||
- **Raised by:** Miri (Round 1 proposal, Round 2 validation), Paula (moral dimension endorsement), full team validated
|
||||
- **Dissent:** None
|
||||
|
||||
### D-050: Velen — Van Maanen's Star primary world
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Velen is the canonical name for Van Maanen's Star's primary habitable world. Temperate-maritime climate, ~0.9G, regular rain, morning/evening fog, mild temperature range, occasional heavy squalls. Station Sova orbits Velen. The span gate connects Sova to a planetary freight depot on Velen's surface. Naming convention: compact, consonant-weighted, two-syllable, Nordic-influenced.
|
||||
- **Weather as gameplay (cross-ref D-046):** Fog degrades everyone's vision cones equally — shared vulnerability. The storyteller can time weather for dramatic effect without breaking environmental neutrality (D-045). Foggy mornings = shorter cones = smuggler's early drops safer, detective's dawn surveillance harder.
|
||||
- **Cross-reference:** Setting ([D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting))
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.13, §1.15
|
||||
- **Raised by:** Miri (Round 2 proposal), confirmed by project lead (Round 3). Unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-062: Invisible locked dialogue options
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Dialogue options the player hasn't unlocked are completely invisible. No grayed-out options. No lock icons. No hint that more options exist. The player doesn't know what they don't know. Exception: NPC holding back is communicated via monologue ("She changed the subject. Fast."), not via locked UI elements.
|
||||
- **Rationale:** Four reasons: (1) Asymmetry — you don't know what you don't know. (2) Dopamine — new options appearing on repeat visits IS the reward. (3) Anti-metagaming — no checklist to complete. (4) Confrontation surprise — Confront option appearing for the first time is a dramatic moment. Strongest consensus point of the entire workshop — unanimous across all 8 participants.
|
||||
- **Cross-reference:** Dialogue architecture ([D-028](#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers)), knowledge graph confidence tiers ([D-041](architecture.md#d-041-knowledge-graph-data-model)), dialogue box ([D-061](perception.md#d-061-dialogue-box--bottom-screen-max-20-height-no-portraits))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Gestalt (proposal + four-reason rationale), Nigel (emphatic reinforcement: "non-negotiable")
|
||||
- **Dissent:** None. Unanimous.
|
||||
|
||||
### D-063: Confrontation — same box, different weight
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Confrontation uses the same dialogue UI as casual conversation — no separate confrontation mode. Different weight communicated through four mechanisms: (1) Confrontation options written in character's internal voice — italicized, first-person (regular: "Shift schedule" / confrontation: *"I saw you in corridor B-7"*). (2) Pre-delivery monologue beat (1-2 seconds: *"This changes things. No taking it back."*) — character hesitates internally before speaking. (3) World responds — NPC shifts to Tier 2 animation ([D-047](perception.md#d-047-art-direction--two-tier-animation-system)), entity D-033 color may fade, monologue frequency spikes, available topics narrow post-confrontation. (4) Walk-away mid-confrontation contaminates social space — NPC routine may shift, KG records incompleteness.
|
||||
- **v0.1 staging:** Proximity check + audio dip + text styling. Camera tighten deferred to post-v0.1.
|
||||
- **Explicitly NOT:** Separate confrontation UI, timed responses, visible relationship meter, correct/incorrect dialogue approaches.
|
||||
- **Rationale:** Confrontation should feel heavy because of what you're saying, not because the UI changed. The weight comes from pacing, voice, and consequence.
|
||||
- **Cross-reference:** Dialogue architecture ([D-028](#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers)), two-tier animation ([D-047](perception.md#d-047-art-direction--two-tier-animation-system)), entity color ([D-033](perception.md#d-033-entity-color--relationship-to-player)), walk-away ([D-064](#d-064-walk-away--three-phase-consequences))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Paula (four mechanisms), Ozzie (physical staging), Stig (UI container)
|
||||
- **Dissent:** None.
|
||||
|
||||
### D-064: Walk-away — three-phase consequences
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Walking away from dialogue (WASD during conversation) triggers three distinct phases: (1) Immediate break — dialogue fades over 300ms, silence. No close button. (2) NPC reacts — animation shifts, may call after player, routine may change. (3) KG records incompleteness — the knowledge graph logs that the interaction was initiated but not completed. This is queryable and affects future dialogue, monologue, and NPC behavior. Walk-away consequences vary by NPC tolerance threshold per seed — no universal social rules to metagame.
|
||||
- **Rationale:** Walking away is an action with meaning. Leaving mid-confrontation is different from leaving mid-smalltalk. The KG recording means the game remembers what you started. Per-seed tolerance prevents players from learning universal "safe to walk away" rules across playthroughs.
|
||||
- **Cross-reference:** Confrontation ([D-063](#d-063-confrontation--same-box-different-weight)), knowledge graph ([D-041](architecture.md#d-041-knowledge-graph-data-model)), dialogue box ([D-061](perception.md#d-061-dialogue-box--bottom-screen-max-20-height-no-portraits))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Paula (three phases + KG recording), Stig (WASD mechanic + 300ms fade), Ozzie (consequences), Nigel (tolerance per seed)
|
||||
- **Dissent:** None.
|
||||
|
||||
### D-074: Audio aesthetic identity — insert-tech vs organic
|
||||
- **Date:** 2026-02-16
|
||||
- **Decision:** Audio design uses two sonic families with distinct aesthetic identities:
|
||||
- **Insert-tech sounds:** Synthetic, precise, clinical, no reverb. Monologue chimes ([D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open) assets 7-8), UI feedback, future: lattice interface sounds, biometric scan confirmations. Represents neural lattice interface — artificial, computational, clinical.
|
||||
- **Organic sounds:** Warm, breathy, natural decay, environmental reverb. Footsteps, ambient layers, NPC movement, environmental events. Represents human cognition and physical reality — warm, imperfect, lived-in.
|
||||
- **Thematic mapping:** Insert-tech = neural lattice (computational precision, trustworthy but inhuman). Organic = human cognition and environment (warm, ambiguous, interpretive). Maps to [D-018](perception.md#d-018-three-range-sound-model) trust model: close/organic sounds = reliable, long-range/insert sounds = potentially compromised.
|
||||
- **Station palette — "functional warmth":**
|
||||
- Low-freq foundation (60-120Hz): station hum, span gate vibration, machinery drone.
|
||||
- Mid-freq texture (200-800Hz): footsteps, object handling, conversation murmur.
|
||||
- High-freq detail (2-8kHz, sparse): scanner pings, metal impacts, environmental detail.
|
||||
- No harsh frequencies, no industrial brutality. The station is SETTLED — lived-in, maintained, comfortable enough to be complacent.
|
||||
- **Environmental neutrality per [D-045](perception.md#d-045-art-direction--environmental-neutrality-strict-zero-shift):** Ambient audio does NOT shift with narrative state. Same station hum before and after conspiracy discovery. No music stingers for investigation progress. Emotional weight comes from monologue and player knowledge, not audio cues.
|
||||
- **Cross-reference:** Audio assets ([D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open)), sound model ([D-018](perception.md#d-018-three-range-sound-model)), environmental neutrality ([D-045](perception.md#d-045-art-direction--environmental-neutrality-strict-zero-shift)), setting ([D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting))
|
||||
- **Raised by:** Inigo (insert-tech/organic split), Paula (cognitive architecture framing and trust model connection)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-075: Dialogue filtering — layered confidence gate on trust tier (OQ-18 resolution)
|
||||
- **Date:** 2026-02-19
|
||||
- **Decision:** KnowledgeConfidence ([D-041](architecture.md#d-041-knowledge-graph-data-model)) acts as a co-gate on TrustTier ([D-028](#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers) Layer 3), not on AccessTier (Layer 1). Access tier and trust tier remain two separate filtering dimensions with different drivers:
|
||||
1. **AccessTier (Layer 1):** Gated by `RelationshipState` only. Social position determines what *categories* of dialogue are available. No change from current implementation. Character archetype effects are emergent — the detective's investigation naturally creates PersonOfInterest relationships (Authority access), the smuggler's social arc naturally creates Known/Friendly relationships (Peer/Insider access). No archetype tag on the pipeline.
|
||||
2. **TrustTier (Layer 3):** Gated by both `RelationshipState` AND `KnowledgeConfidence`:
|
||||
- **Surface:** any relationship + any confidence — baseline, always available.
|
||||
- **Real:** (Friendly or Known) + KnowsOf+ — requires both rapport and substantive knowledge.
|
||||
- **Secret:** Friendly + KnowsDetails+ — requires both deep rapport and actionable knowledge.
|
||||
3. **KnowledgeConfidence does NOT gate AccessTier.** Access is a social/positional concept ("who are you to me?"), not an information concept ("what do you know about me?"). A stranger can have Authority access (detective flashes badge) with zero knowledge. An insider can have Peer access before they know anything specific about the target.
|
||||
- **Key design choice — no archetype dimension.** The dialogue pipeline does not add a character-archetype tag (detective/smuggler) as a filtering axis. Instead, archetype effects on dialogue emerge from: (a) different starting RelationshipStates driven by gameplay (detective institutions → Authority access, smuggler social network → Insider access), (b) different knowledge accumulation rates (detective's analytical lattice gains KnowsOf faster → Real trust earlier), (c) D-028 Layer 1 access tags on lines already encode "this line is for authority figures" vs "this line is for insiders." This is architecturally consistent with D-010 principle 3 (no baking player identity into the game loop).
|
||||
- **Rationale:** Three reasons for layered-but-not-archetype:
|
||||
1. *Separation of concerns.* Access (social position) and trust (relationship depth x knowledge depth) answer different questions. Collapsing them into one axis would require rewriting D-028's four-layer model and D-035's tag taxonomy — both confirmed and implemented.
|
||||
2. *Minimal code change.* The only implementation change is adding a `KnowledgeConfidence` parameter to `relationship_to_trust()` in `server/src/simulation/dialogue.rs`. The caller already has access to the observer's KnowledgeGraph. No new components, no new tags, no content format changes.
|
||||
3. *Emergent archetype distinction.* Hardcoding archetype tags creates a maintenance burden (new character = new tag = new content variant) and reduces the "two keyholes on the same world" experience. When the detective and smuggler experience different dialogue from the same NPC, it should be because they have different *relationships* and *knowledge*, not because a tag excluded them.
|
||||
- **Implementation change to #305:** `relationship_to_trust()` gains a `confidence` parameter. Mapping: `(Friendly, KnowsDetails+) → Secret`, `(Friendly|Known, KnowsOf+) → Real`, `(_ , _) → Surface`. Caller in `process_talk_interaction` passes `observer_kg.confidence_of(&target_sid)` to the updated function.
|
||||
- **Resolves:** OQ-18
|
||||
- **Amends:** [D-041](architecture.md#d-041-knowledge-graph-data-model) (confirms confidence-to-trust mapping; supersedes the preliminary 1:1 sketch in D-041 "Key design choices" bullet 3 with the layered model above), [D-028](#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers) (Layer 3 trust now requires both relationship AND confidence)
|
||||
- **Cross-reference:** [D-028](#d-028-dialogue-architecture--tagged-line-pools-with-four-relational-layers), [D-035](#d-035-converged-tag-taxonomy-for-dialogue-and-monologue-line-pools), [D-041](architecture.md#d-041-knowledge-graph-data-model), [D-062](#d-062-invisible-locked-dialogue-options) (confidence progression naturally unlocks new trust tiers, creating the "new options appearing" reward)
|
||||
- **Raised by:** Tyre (technical analysis, architecture synthesis)
|
||||
- **Dissent:** Gestalt endorses D-075 (reviewed 2026-02-19). The emergent archetype distinction is sufficient: access tier tags already encode "authority figure lines" vs "insider lines" in content; starting knowledge differentials produce different dialogue gate timings per character; adding an archetype filter would create per-character content maintenance burden and dilute the "two keyholes on the same world" experience (D-027). Knowledge vocabulary doc (#368) confirms this works in practice — same fact IDs, different starting confidence levels, different gate-open timing per character. *Nigel's input still pending.*
|
||||
|
||||
### D-084: Dual-namespace line ID scheme — role pool + instance override
|
||||
- **Date:** 2026-02-25
|
||||
- **Decision:** Line IDs for auto-generated NPC content use a dual-namespace approach that eliminates the Q-028 collision problem without altering the existing ID format.
|
||||
- **Role namespace (unchanged, primary):** `{role-slug}_{d|m|e}_{###}` — e.g., `dock-worker_d_001`. These are shared lines delivered by any instance of the role. One file, one ID sequence per role-at-location. No per-instance authoring, no collision possible. All existing authored content is unaffected.
|
||||
- **Instance namespace (new, opt-in):** `{role-slug}-{zero-padded counter}_{d|m|e}_{###}` — e.g., `dock-worker-07_d_001`. Counter is the generation-order rank within the role group for that district, starting at 01, assigned deterministically from the world seed. Used only when a specific generated NPC needs authored content that differs from the role pool.
|
||||
- **Key design choices:**
|
||||
- **Why the collision problem is mostly already solved:** The Q-028 collision framing assumed NPC-scoped IDs require per-instance ID sequences. They don't. D-028 tagged line pools are role-scoped: `dock-worker_d_001` is content that any dock worker can deliver. Forty dock workers all drawing from `dock-worker_d_###` is correct behavior, not a collision. A collision would only occur if two *distinct authored lines* shared the same ID — which the role namespace prevents by definition (one file, one sequence).
|
||||
- **Instance namespace scope:** Opt-in only. Tier 3 (flat wallpaper) and Tier 2 (mundane triangles) auto-generated NPCs use the role pool exclusively. Instance pools are authored only when a specific generated NPC needs content variation the role pool cannot supply (e.g., a generated NPC flagged as a triangle member with unique tell lines).
|
||||
- **History log disambiguation:** The speaker of a line is identified by `StableId`, not by line ID. Line ID identifies content; `StableId` identifies the speaker. `(StableId: 42, line_id: "dock-worker_d_001")` and `(StableId: 43, line_id: "dock-worker_d_001")` are two different log entries for the same content line — no collision in the log.
|
||||
- **Counter stability:** Generation order within a role group is seeded from the world seed. Same seed → same order → same counter assignments. Counter is recorded in the district's NPC roster at world-gen time. The counter survives save/load because it is part of the generated NPC's profile, not recomputed at runtime.
|
||||
- **Schema compatibility:** The existing ID regex `^[a-z][a-z0-9-]*_[dme]_\d{3}$` already accepts `dock-worker-07_d_001`. No regex change required. No content migration required.
|
||||
- **Rejected alternatives:**
|
||||
- **StableId prefix (`npc-00042_d_001`):** StableId is assigned at load time from sorted canonical IDs. Authors cannot know it before writing files. A generate-then-bake pipeline would break the content/generation separation principle. Rejected.
|
||||
- **UUID suffix (`dock-worker-a3f2_d_001`):** UUIDs are stable per seed but change across seeds, orphaning any authored instance content on replay. Rejected.
|
||||
- **Slug registry with collision resolution (`dock-worker`, `dock-worker-2`, ...):** First instance gets a privileged non-suffixed slug while all others get a counter, creating asymmetry with no upside. Rejected.
|
||||
- **Implementation requirement:** The content registry (`server/src/knowledge/registry.rs` or a new `server/src/content/npc_slug.rs`) tracks a `RoleCounter: BTreeMap<String, u32>` per district. Incremented when a generated NPC claims an instance namespace slot. Stored in the district manifest. Provides `generate_instance_slug(role_slug) -> String` returning `{role-slug}-{counter:02}`.
|
||||
- **Hand-authored NPCs:** Unchanged. `kael-davan`, `sera-venn`, and all named authored NPCs keep their current slugs and ID sequences. No migration.
|
||||
- **Resolves:** Q-028
|
||||
- **Cross-reference:** Line ID scheme ([D-035](#d-035-converged-tag-taxonomy-for-dialogue-and-monologue-line-pools)), population model ([D-029](#d-029-population-entanglement-ratio--305020)), NPC generation ([D-024](#d-024-npc-generation-model--10-axes--combat-component))
|
||||
- **Raised by:** Gestalt (Sprint 18, #544). Endorsed by Tyre pending implementation review.
|
||||
- **Dissent:** None.
|
||||
|
||||
### D-090: PC voice registers — smuggler and detective speech patterns `[SUPERSEDED]`
|
||||
- **Date:** 2026-02-12
|
||||
- **Superseded by:** [D-117](scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) (2026-03-05). The smuggler/detective dual-lens frame is eliminated for v0.2. The tycoon is the single playable character. Voice register design for v0.2 follows culture-driven voice (D-121) applied to the player character, not the smuggler/detective partition below.
|
||||
- **Decision:** Each playable character has a defined voice register for monologue and dialogue:
|
||||
- **Smuggler:** Feeling-first. Sentence fragments. Concrete/physical vocabulary. Notices bodies, spaces, exits. Emotional baseline: wary comfort. Lies by omission. Relationship to authority: avoidance.
|
||||
- **Detective:** Analysis-first. Complete sentences. Institutional vocabulary. Notices patterns, inconsistencies, procedural gaps. Emotional baseline: professional detachment. Lies by reframing. Relationship to authority: representative.
|
||||
These registers govern all authored content per character (monologue pools per D-032, dialogue access per D-028).
|
||||
- **Rationale:** Register differences must be architectural, not incidental. Without defined registers, authors default toward a single generic voice and the dual-lens effect (D-027 criterion 2) collapses. The registers encode the characters' relationships to the world, not just vocabulary preferences.
|
||||
- **Raised by:** Mellanie, Paula
|
||||
- **Dissent:** None
|
||||
- **Source:** v0.1 Content Scoping Workshop, Mellanie Round 2 synthesis
|
||||
- **Cross-reference:** D-032 (separate monologue pools), D-034 (THE FRIEND pattern)
|
||||
|
||||
### D-092: Anchor line requirement in NPC style guide
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Every NPC at Tier 1 and Tier 2 depth must have anchor lines — signature phrases or verbal tics that make them instantly recognizable in text. Requirements: Tier 1 NPCs (THE FRIEND, key triangle members): minimum 2 anchor lines per arc phase. Tier 2 NPCs (triangle periphery): minimum 1 anchor line. Tier 3 NPCs (background): no anchor requirement, generic pool lines only. Anchor lines must be authored, never generated.
|
||||
- **Rationale:** Anchor lines create the "I know that voice" moment on repeat encounters. Generation cannot produce this — generated lines are statistically average, not distinctively characteristic. The generation expansion pass (D-028) fills volume; anchor lines create identity.
|
||||
- **Raised by:** Mellanie
|
||||
- **Dissent:** None
|
||||
- **Source:** Wiki Review Workshop, Mellanie Round 2 proposal, consensus C-19
|
||||
- **Cross-reference:** D-034 (THE FRIEND pattern), D-028 (dialogue architecture), D-023 (three-tier content model)
|
||||
|
||||
---
|
||||
|
||||
### D-093: Sova Transit District — Spatial Layout and District Topology
|
||||
- **Date:** 2026-02-25
|
||||
- **Decision:** The Sova Transit District spatial layout is confirmed. Four social sites (D-025): Terminal (Sova Logistics Hub, 44×28 visual), Bar/Last Shift (28×22 + 6m east ext.), Gate Cluster (40×32 visual, 7 zones — see zone spec below), Sector 3 residential (Drin/Naia anchor, ~15×12 visual, adjacent maintenance spine). Transit platform (The Loop stop, ~12×8 visual, bar-side) is classified as an encounter node, not a social site. District bounding box: 256×256 visual tiles (4×4 blocks per D-094). Three investigation paths confirmed: Path A (pattern recognition via camera logs/manifest), Path B (physical traversal via acoustic gap at restricted storage door seal → maintenance hatch), Path C (institutional, via Commission inspector relationship). Zone palette (surface hex / fog tint): gate cluster #b8bec4 / #0a1222; terminal #7a8490 / #0d1520; bar #6b4018 / #200c04; maintenance #4e5054 / #101214. Gate cluster zone spec (Araminta): aperture chamber 8×4 (restricted); freight staging 24×8 (private); passenger arrival 12×8 (semi-public); freight customs 20×10 (semi-private, 3–5 lanes at 2vt/lane); pedestrian customs 12×10 (semi-public, 3 lanes at 1vt); gate concourse 40×8 (public); observation gallery z=2 32×10 (Commission-only). Corridor widths: maintenance 2vt; internal building 3–4vt; secondary public 4vt; transition 6vt; gate concourse 8vt; service alcoves 1–2vt. Z-level scheme: z=0 maintenance corridor (Era 1, no Meridian), z=1 all main structures, z=2 gate cluster observation gallery only. Cross-z LOS: gallery rail = transparent low wall (player on z=2 sees z=1 below; upward LOS blocked except at staircase). Gate cluster social triangle: operations manager + senior freight handler + Commission inspector. Invisible infrastructure principle (G-08): every ring location reads as mundane; criminal function visible only to those who know. G-11: detective enters via gate cluster (Commission arrival); workers enter via transit platform (bar-side).
|
||||
- **Rationale:** Emerged from three-round workshop synthesis. Layout satisfies D-025 (social sites), D-036 (Sova Transit District), D-054 (tile movement), D-059 (fog zone palette), D-066 (dual-scale grid), D-011 (fog of perception), D-018 (sound model), D-027 (vertical slice criteria). Chunk/district hierarchy establishes architectural precedent for Q-036 generator.
|
||||
- **Raised by:** Full team — Gestalt (gameplay constraints), Miri (worldbuilding/lore), Araminta (visual/spatial), Tyre (technical), Paula (narrative), Ozzie (player experience). Compiled by Qatux.
|
||||
- **Dissent:** Araminta preferred 32×32 visual chunk size (overruled by lead and team majority). No other dissent.
|
||||
- **Source:** Station District Layout Workshop, Ticket #153, Sprint 20. Round document: `docs/discussions/round-20-station-district-layout.md`
|
||||
- **Cross-reference:** D-025 (social sites), D-036 (Sova setting), D-054 (tile movement), D-059 (fog system), D-066 (dual-scale grid), D-094 (district hierarchy), D-095 (transport lore), Q-036 (generator), Q-040–Q-044 (transport lore questions)
|
||||
|
||||
---
|
||||
|
||||
### D-095: Horizon Stations and Gate Infrastructure — Transport Lore
|
||||
- **Date:** 2026-02-25
|
||||
- **Decision:** Span gates are human-built structures with a single aperture enabling near-instantaneous transit. Operating schedule uses dual-use windows: freight (bulk of hours) and passenger (scheduled slots). Physical layout: aperture chamber → freight staging / passenger arrival → customs lanes → gate concourse. Horizon stations are alien-built installations (no identified builder species), self-maintaining, located at Oort-cloud distance, with **1–8 apertures per station** (revised from 4–8; single-aperture stations are valid and produce isolated dead-end systems with one way in and one way out). Per-system canonical name: "The Ring." Travel is sequential-hop only (A→B→C through intermediate systems; no direct long-range transit). Per-system access tiers vary (4 tiers — some systems allow single-hop to orbital customs; no direct planetary span gate). Station Sova's horizon gates are located at The Ring (Oort-cloud orbital); the Administrative Hub contains booking offices only (not the gates themselves — correction to prior station profile text). "The Loop" is Sova's internal tram network: 6 districts, 4-minute run from Residential Core to Transit District. Workers arrive at the transit platform (bar-side) and disperse to Terminal or bar.
|
||||
- **Rationale:** Resolves transport lore questions Q-040, Q-041, Q-043, Q-044 raised during Workshop #153. Miri's Round 3 contribution. Horizon station as alien-built infrastructure adds worldbuilding depth without requiring a named builder species. Sequential-hop travel creates natural story hooks (layover locations, transit records, smuggling route complexity). Aperture count revised to 1–8 (from 4–8) to allow single-aperture stations, which produce the most isolated and narratively interesting dead-end systems — and leave open the question of what a single-aperture station pointing at an unknown destination means.
|
||||
- **Raised by:** Miri (worldbuilding), confirmed by team.
|
||||
- **Amendment (2026-03-13):** Aperture count range revised from 4–8 to **1–8** per project lead direction. Single-aperture horizon stations are valid; they are the mechanism for the most isolated dead-end systems, and for any system whose single gate points to a destination that is not (or not yet) part of the Reach. This change has downstream implications for the Earth question — see note in systems-framework-miri.md §7.
|
||||
- **Amendment (2026-03-14):** Clarified the inter-system / intra-system gate distinction and technology lineage:
|
||||
- **Inter-system gates (horizon gates / founder gates):** Alien-built. Aperture count and connections are properties of the alien infrastructure. Humans cannot add, remove, activate, or deactivate inter-system apertures. Gate topology is *given*, not chosen. The one known exception — a dormant aperture at Struve activating ~40 years ago — was not a human action; the alien infrastructure did something on its own, for reasons the Veil Institute has not explained. Whether dormant apertures exist elsewhere, and what triggers activation, is unknown.
|
||||
- **Intra-system gates (span gates):** Human-built technology, derived from the Veil Institute's study of alien horizon station architecture. The Institute reverse-engineered the principles governing short-range aperture formation and licensed the technology to a gate construction corporation, which now owns and operates span gate infrastructure across the Reach (and owns an entire system as its industrial base). Span gates are well-understood engineering: buildable, modifiable, commercially operated.
|
||||
- **Key constraint for wiki authors:** No system's aperture count or inter-system connections are the result of human decisions. Systems cannot "vote for" or "apply for" additional horizon gate apertures. A system's gate topology is an alien-determined fact that humans have adapted to, not chosen.
|
||||
- **Dissent:** None.
|
||||
- **Source:** Station District Layout Workshop, Ticket #153, Sprint 20. Round document: `docs/discussions/round-20-station-district-layout.md`
|
||||
- **Cross-reference:** D-093 (gate cluster spatial layout), Q-040 (gate dual-use topology — resolved), Q-041 (horizon station model — resolved), Q-042 (intra-system transport — partially resolved), Q-043 (station internal transit — resolved), Q-044 (gate-train integration — resolved)
|
||||
|
||||
---
|
||||
|
||||
### D-098: TrianglePurpose Enum
|
||||
- **Date:** 2026-02-27
|
||||
- **Decision:** Social triangles carry `Vec<TrianglePurpose>` — a multi-tag set for playstyle accessibility. Enum values: `Investigation, Economic, Social, Political, Tactical, Mundane`. `Tactical` encodes the assassination contract in spatial form (target + protector + informant/witness). Multiple purpose tags per triangle: a smuggling operation can be `Economic + Tactical` simultaneously. Purpose tags ensure the right drama is surfaced to the player whose active lens matches — they add no generation cost, categorizing existing output.
|
||||
- **Rationale:** Purpose tags are the bridge between the generator's social structure and the player's active playstyle. The generator doesn't build for one playstyle — it tags what's already there.
|
||||
- **Source:** Generator Architecture Workshop (#562), 2026-02-27. `docs/workshops/generator-architecture/workshop-outcomes.md` §D-READY-3.
|
||||
- **Raised by:** Gestalt (triangle purpose model). Full team sign-off.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** D-025 (social site / functional cluster — triangles populate social sites), D-097 (guarantee tier system — triangles feed the audit)
|
||||
|
||||
### D-104: Heritage Grammar Overlay for Non-Urban Palettes
|
||||
- **Date:** 2026-02-27
|
||||
- **Decision:** Data-driven `HeritageGrammarOverlay` structs (10 per heritage root). Loaded once at generator startup, applied at Phase 2 chunk fill by weighted blending. Blend rules: continuous fields (decorative_density, repair_visibility, etc.) use weighted average; categorical fields (boundary_character, open_space_character) use dominant heritage weight; object tag lists use union of preferred/accent tags and intersection-exclusion of excluded tags. Phase 1 exception: `gathering_probability` evaluated at block planning for quarter pre-assignment. Authoring domain separation: **Miri** authors organizational principles, boundary character, spacing, social grammar (HeritageGrammarOverlay Rust struct / authored data). **Araminta** authors visual expression — object sets, arrangement algorithms, floor surface variants, overhead flora density and character, wall/structure material character, boundary material type, lighting temperature (TOML modifier files, one per heritage root). Shared: `ObjectTag` vocabulary must be co-maintained (see Q-049).
|
||||
- **Rationale:** Heritage roots must be spatially legible — the visual grammar of a Frost community versus a Tide community must be apparent to the observant player without a label.
|
||||
- **Source:** Generator Architecture Workshop (#562), 2026-02-27. `docs/workshops/generator-architecture/workshop-outcomes.md` §D-READY-9.
|
||||
- **Raised by:** Miri (cultural grammar spec), Araminta (TOML modifier design and authoring domain). Full team sign-off.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** D-101 (ZonePalette — heritage modifier axis A), D-105 (informal zone typology — heritage correlations), Q-049 (ObjectTag co-maintenance)
|
||||
- **Superseded by:** [D-167](#d-167-heritage-roots-superseded--corridor-cultural-system-replaces-abstract-roots) (2026-03-24). The 7 abstract heritage roots and their grammar overlays are retired. Cultural grammar is now authored per-system using the corridor framework.
|
||||
- **Superseded 2026-05-25 by D-232** (HeritageGrammarOverlay → per-body `ArchitectureFlavorEntry` + `allow`/`block` filter; never wired).
|
||||
|
||||
### D-105: Non-Urban Informal Zone Typology
|
||||
- **Date:** 2026-02-27
|
||||
- **Decision:** Informal zones (spaces outside the community's social field) are defined by the type of social permission governing them, not by institutional absence. Three types: `physical_distance` — sparse objects, unmaintained floor; isolation is the visual. `social_permission` — normal zone palette; gathering infrastructure present; cover is about convention, not geography. `utilitarian_cover` — functional work objects; space reads as work space; unofficial use invisible to casual observation. Heritage root correlations: Frost/Stone → `physical_distance`; Tide/Vine/Dust → `social_permission`; Iron/Salt → `utilitarian_cover`. (Dust = maximum communal observation, privacy is negotiated not physical; Iron = labor function covers presence.) Location within terrain seeded independently. Visual grammar per type: `docs/workshops/generator-architecture/araminta-round4.md`.
|
||||
- **Rationale:** Privacy mechanics emerge from community culture. How you hide in a Frost community (physical distance) is architecturally different from how you hide in a Dust community (social agreement). The typology makes privacy mechanics culturally legible.
|
||||
- **Source:** Generator Architecture Workshop (#562), 2026-02-27. `docs/workshops/generator-architecture/workshop-outcomes.md` §D-READY-10.
|
||||
- **Raised by:** Miri (heritage root correlations, canonical mapping corrected Round 5), Araminta (visual grammar per type). Full team sign-off.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** D-104 (heritage grammar overlay)
|
||||
- **Superseded by:** [D-167](#d-167-heritage-roots-superseded--corridor-cultural-system-replaces-abstract-roots) (2026-03-24). Heritage root correlations (Frost/Stone/Tide etc.) are retired; informal zone typology must be re-authored against corridor cultural identities.
|
||||
- **Superseded in part 2026-05-25 by D-232** — the three informal-zone *types* survive as a typology; the heritage-root lookup is replaced by flavor-filtered zone selection.
|
||||
|
||||
### D-107: Trauma Events as EraModification Subtypes
|
||||
- **Date:** 2026-02-27
|
||||
- **Decision:** Trauma events are a subtype of `EraModification` with dual-track effects. Five subtypes: `PhysicalDestruction, EconomicDisruption, PoliticalShock, ViolenceEvent, MigrationShock`. Separate tracks: (1) structural damage via `StructuralChange` in ChunkMutations (applied as `LocalOverlay` per D-109); (2) cultural response via NPC weight distribution shift in `DistrictRuntimeState.npc_pattern_weights`. Decay rate seeded per-community with variation around heritage-root baseline (`trauma_visual_decay_rate: slow | medium | fast`, default medium). Design principle: **Trauma intensifies culture, it does not transform it.** A stressed community becomes a more concentrated version of itself — Frost communities close harder, Tide communities grief more publicly, Iron communities organize more collectively. Decay is toward the community's pre-trauma baseline, not toward a new equilibrium. Players who have learned a heritage root's trust model can predict community behavior in the aftermath.
|
||||
- **Rationale:** Cultural response must be legible — and predictable to a player who has invested in understanding the heritage root. Trauma as amplifier (not transformer) rewards prior observation.
|
||||
- **Source:** Generator Architecture Workshop (#562), 2026-02-27. `docs/workshops/generator-architecture/workshop-outcomes.md` §D-READY-12.
|
||||
- **Raised by:** Miri (trauma subtypes and heritage decay model, "trauma intensifies culture" principle added Round 5), Tyre (struct design and decay architecture). Full team sign-off.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** D-100 (DamageOverlay — structural track), D-104 (heritage grammar — cultural baseline), D-109 (LocalOverlay mandate)
|
||||
- **Superseded (partial):** Heritage-root-based decay model superseded by [D-167](#d-167-heritage-roots-superseded--corridor-cultural-system-replaces-abstract-roots) (2026-03-24). Trauma-intensifies-culture principle and structural track remain valid; heritage root baseline references must be re-interpreted via the corridor cultural system.
|
||||
- **Superseded 2026-05-25 by D-232** — per-root trauma decay → per-body `trauma_decay_rate`; the 'trauma intensifies culture' principle survives.
|
||||
|
||||
---
|
||||
|
||||
### D-121: Voice is culture-driven — job as modifier
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** NPC voice is authored at the culture level with job-specific modifiers layered on top. Culture is primary — a character IS their background. Job adds a layer. A Van Maanen's Star tycoon sounds like a Van Maanen's Star person who runs businesses, not a generic tycoon. This is an inversion of the prior assumption that job drove voice with culture as modifier.
|
||||
- **Rationale:** Culture-primary voice produces characters that feel like they belong to a place. Job-primary voice produces archetypes. The life-sim vision requires characters legible as inhabitants of Van Maanen's Star, not as representatives of occupational categories.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 6
|
||||
- **Raised by:** Team Leader (Jeroen) — inversion of Mellanie's prior option C
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-128](#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) (Van Maanen's Star culture as starting context)
|
||||
|
||||
### D-122: All NPCs generated — no named hand-authored characters
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** All NPCs in v0.2 are generated. There are no named, hand-authored characters. Kael Davan, Naia, Maret, and Sera Venn do not exist in v0.2. The generator produces NPCs that fit positions based on location characteristics. Limited vocabulary is acceptable at first. The FRIEND pattern (D-034) survives as a generator template, not an authoring assignment.
|
||||
- **Rationale:** Rimworld and The Sims are capable of generating characters that players form attachments to, even without dialogue or backstory. The generator-first approach (D-114) requires proving this foundation before hand-authored characters are layered on. Named NPCs and fixed triangles were a source of the rigidity that made v0.1 feel like a game level, not a place.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 7
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Supersedes:** Named NPC assignments in [D-034](#d-034-the-friend--production-level-npc-pattern) (Kael/Sera as hand-authored characters — see amendment on D-034)
|
||||
- **Cross-reference:** [D-123](#d-123-generative-ai-for-npc-content-templating-via-culture-vectors) (AI templating), [D-129](#d-129-npc-personality-traits--behavior-first-relationships-codified-for-systems) (NPC personality model)
|
||||
|
||||
### D-123: Generative AI for NPC content — build-time authoring tool and runtime voice pipeline
|
||||
- **Date:** 2026-03-05
|
||||
- **Date (amended):** 2026-03-07
|
||||
- **Decision:** The AI pipeline operates in two distinct modes with different safety profiles:
|
||||
- **Build-time mode (authoring tool):** Content generated at build time for baked hub zones. Subject to mandatory human review before shipping. AI as an accelerated authoring tool producing content humans review and approve.
|
||||
- **Runtime mode (background enhancement):** Content generated during gameplay for non-baked zones, via a background inference queue, when "AI-Enhanced Dialogue" is enabled. Not human-reviewed per line. Safety provided by three layers: (1) base-text-as-fallback — always present and complete; (2) build-time-validated injectors — only pre-validated prompts used, never ad-hoc; (3) runtime contamination filter — lightweight check before content is served.
|
||||
- **Non-negotiable constraints (both modes):** Culture vectors are the primary prompt constraint. The AI does not default to genre conventions. Authorial control governs what the LLM may and may not produce through injector clauses, negative constraints, and pipeline routing rules. The AI pipeline applies voice to authored semantic content; it does not generate narrative decisions, base text, tell behaviors, secret-tier dialogue (D-028 Layer 3), or anchor lines (D-092). These categories are always authored and always served as-authored.
|
||||
- **Rationale:** Full pipeline (behaviors + dialogue) is the correct scope. A system that voices observed behavior but not spoken dialogue creates register whiplash at the highest-investment moment of player engagement. Build-time mode preserves the human-review safety model. Runtime mode enables scaling to the generated world with base-text fallback as the permanent safety net.
|
||||
- **Source:** Where's the Fun? Workshop (original); LLM Voice Pipeline Workshop (amendment)
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None on amendment
|
||||
- **Amendment attribution:** The two-mode distinction (build-time authoring tool vs. runtime background enhancement) and the six dialogue re-voicing quality constraints are Paula's contribution from LLM Voice Pipeline Workshop Round 3. The two-mode framing is the organizing principle: build-time mode inherits the original D-123 safety model (human review); runtime mode operates under a different safety model (three-layer fallback) that was validated in Spikes 1 and 2.
|
||||
- **Amended by:** [D-138](#d-138-llm-re-voicing-pipeline-for-npc-voice) (LLM Voice Pipeline Workshop, 2026-03-07)
|
||||
- **Cross-reference:** [D-121](#d-121-voice-is-culture-driven--job-as-modifier) (culture-primary voice), [D-128](#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) (culture profile as generator input), [D-140](#d-140-dialogue-re-voicing-quality-constraints--paulas-six-rules) (dialogue re-voicing quality constraints)
|
||||
|
||||
### D-124: In-game ollama for live NPC dialogue — ~~deferred~~ SUPERSEDED by D-138
|
||||
- **Date:** 2026-03-05
|
||||
- **Date (superseded):** 2026-03-07
|
||||
- **Decision:** ~~Running a dressed-down version of ollama in-game for live NPC dialogue is possible and interesting, but deferred.~~ **Superseded by [D-138](#d-138-llm-re-voicing-pipeline-for-npc-voice).** The in-game AI system uses `llama-cpp-rs` (not ollama) with GGUF Q4_K_M quantization, bundled with the game, running background inference via an isolated thread pool. The key constraint from D-124 remains binding through D-123 (amended): this system does not drive live narrative decisions. It applies voice to authored semantic content.
|
||||
- **Rationale:** The LLM Voice Pipeline Workshop (2026-03-07) walked through the door D-124 left open. The quality, performance, and determinism questions D-124 cited as blockers are addressed by cache-as-determinism, base-text fallback, and layered hardware detection.
|
||||
- **Source:** Where's the Fun? Workshop (original); LLM Voice Pipeline Workshop (supersession)
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Superseded by:** [D-138](#d-138-llm-re-voicing-pipeline-for-npc-voice)
|
||||
|
||||
### D-125: World is quietly responsive — gradient of caring by social proximity
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The world does not care globally but notices locally. Primary social contacts (colleagues, neighbors) develop responsiveness over time. The gradient of caring is based on social proximity — the world is neither Kenshi-indifferent nor uniformly caring. The player should never encounter a truly indifferent world; even early builds will have localized responsiveness around primary contacts. Gore's concern about indifference is addressed by design — authored content will layer in before v1.0.
|
||||
- **Rationale:** True indifference breaks the life-sim emotional loop. Characters can't form attachments to a world that doesn't register their existence. The gradient model (socially close = responsive, globally = neutral) reflects realistic social structure and produces the "quietly alive" feel the workshop converged on.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 10
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-126: Groundhog Day alarm clock homage — first game day only
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The first game day begins with an alarm clock that opens with the *click* pa-pa pa-pa opening from Groundhog Day, cut short. This happens on the first day of a new game only. The tone is a wink: "new day, new start, new chances." It sets the life-sim framing without exposition.
|
||||
- **Rationale:** A single tonal signal at game start establishes the day-cycle framing and communicates the game's tone — forward-moving, possibility-oriented, gently aware of its own conceits — without explicit explanation. First day only; repeating it would undermine the freshness.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 14
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None (legality of the reference to be verified)
|
||||
- **Cross-reference:** [D-136](architecture.md#d-136-first-settled-reach-moment-auto-generated-apartment--insert-activation) (first game moment design)
|
||||
|
||||
### D-127: Player choices are the content — Rimworld model, job as rails
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** Phase 1 of the game experience is not "an empty world before content arrives." It is "a world full of opportunity where the player's choices ARE the content." Rimworld model: one authored starting beat (the crash / the alarm clock + apartment wakeup), then agency and options. A job is rails to take off from, not a script to follow. The world provides opportunity and consequence; the player provides the story.
|
||||
- **Rationale:** The prior "no objectives" stance was a design stance, not a design solution. The Rimworld model is a design solution: curated starting beat, then genuine agency. Phase 1 is not empty — it is a full world of potential actions, economic choices, social encounters, and consequences. The player's story is the content.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 15
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-128: Culture implicit in starting location — Van Maanen's Star equals Van Maanen's Star culture
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** Culture is implicit in the starting bookmark location. The tycoon bookmark in Van Maanen's Star means Van Maanen's Star culture. The player does not select culture at character creation; it derives from where the bookmark places them. This resolves the culture-everywhere-but-nowhere tension: culture IS in the game from day one, it's just not a character creation slider. Van Maanen's Star provides the cultural context; NPC generation uses regional culture as the primary vector.
|
||||
- **Rationale:** Seven of nine workshop agents independently flagged the tension between D-115 (culture deferred from creation) and D-121 (culture primary for voice). Implicit culture unblocks five downstream pipelines simultaneously: voice cards (Mellanie), culture profiles (Miri), NpcBlueprint culture field (Tyre), cultural visual grammar (Araminta), systems integration (Gestalt).
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 16
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-121](#d-121-voice-is-culture-driven--job-as-modifier) (culture-primary voice), [D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting) (Van Maanen's Star canonical details)
|
||||
|
||||
### D-129: NPC personality — traits + behavior first, relationships codified for systems
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** NPC personality starts with traits and observable behavior. Relationships form through two channels: Sims-style accumulation through repeated interaction, and Rimworld-style bonding through shared adversity (surviving a crisis together, helping each other). The player's subjective feeling is the real metric, but relationships must be codified in the system so that game systems (storyteller, consequences, NPC behavior changes) can reference relationship state.
|
||||
- **Rationale:** All nine workshop agents identified NPC legibility as the universal gate. Generated NPCs must have sufficient personality surface area for emotional attachment. Without legible NPCs, the life-sim loop cannot fire. Codifying relationships for systems enables the storyteller to use them as triggers and the consequence model (D-132) to escalate through them.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 17 (resolves Q-WTF-034/035)
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-024](#d-024-npc-generation-model--10-axes--combat-component) (NPC axes — see amendment), [D-132](#d-132-dual-scale-consequence-model--rimworld-sharp-events-and-df-slow-accumulation) (consequence model)
|
||||
|
||||
### D-130: Fully emergent moral arc for v0.2 — generator proves relationships readable first
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** v0.2 ships a fully emergent moral arc — no authored arc structure. The tycoon bookmark has no pre-designed story arc. The explicit test before layering narrative depth: can the player tell "this is a relationship my character has" from generator output alone? Full flavor and generated content will be layered in later, but only after the relationship foundation is proven solid. This is a deliberate proof-of-concept sequence: generator proves relationships are readable → then add narrative depth.
|
||||
- **Rationale:** The full flavor and generated narrative content would get in the way of properly evaluating the generator's strength. The generator must be rock solid and usable before truly interesting threads are pulled. Fully emergent may feel artificial, but it is the right v0.2 test.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 18 (resolves Q-WTF-043)
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-129](#d-129-npc-personality--traits--behavior-first-relationships-codified-for-systems) (relationship legibility as test), [D-119](scope.md#d-119-generator-spike-confirmed-for-sprint-25--critical-path) (generator spike as prerequisite)
|
||||
|
||||
### D-131: Broad economic verb vocabulary — life verbs, not tycoon-specific
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The verb vocabulary is broad and economic, serving all careers, not tycoon-specific. Life verbs: buy, sell, hire, rent, contract, inspect, negotiate, invest. A detective also uses contracts (hiring informants, renting surveillance equipment). Implementation follows the speed of the interpreting systems — each verb requires its backing system (ownership registration for buy/sell, contract tracking for hire/rent). This is a life-sim verb set, not a job-specific verb set.
|
||||
- **Rationale:** Tycoon-specific verbs would lock the gameplay loop to one archetype. Broad economic verbs serve the life-sim vision where "detective, smuggler, tycoon are jobs you can have, not the game's identity" (workshop executive summary). The verb map is the mechanical expression of that philosophy.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 19 (resolves Q-WTF-027)
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-132: Dual-scale consequence model — Rimworld sharp events and DF slow accumulation
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The consequence model operates at two scales simultaneously. Rimworld-style sharp events (raids, crises, dramatic reversals) AND Dwarf Fortress-style slow accumulation (gradual relationship erosion, creeping debt, reputation shifts). Sharp events create drama; slow accumulation creates texture. Rimworld already manages both — sharp storyteller events on top of slow colony degradation. The Settled Reach follows the same dual-scale model.
|
||||
- **Rationale:** The dual-scale model produces both moment-to-moment drama and long-term narrative texture. A single-scale model either feels like it has no consequences (all slow) or like consequence happens arbitrarily (all sharp). Both are load-bearing.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 21 (resolves Q-WTF-037)
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-129](#d-129-npc-personality--traits--behavior-first-relationships-codified-for-systems) (relationships as consequence substrate)
|
||||
|
||||
### D-138: LLM Re-voicing Pipeline for NPC Voice
|
||||
- **Date:** 2026-03-07
|
||||
- **Decision:** NPC observable behaviors and dialogue are processed through an LLM re-voicing pipeline that translates culture-neutral semantic base text into character-voiced output. The pipeline is a background runtime enhancement, not a live generation system. Tell behaviors are base-text passthrough — always. Active tell state influences the re-voicing prompt for surrounding content (tells are read-only inputs to the LLM, never LLM outputs). The game is complete and functional without the pipeline; it is an enhancement that elevates voice quality for players with sufficient hardware.
|
||||
- **Architecture:**
|
||||
- **Model:** Gemma 2 2B IT Q4_K_M (~1.6GB), bundled as `server/models/gemma2.gguf`. No fallback model. *(Amended 2026-03-07: Phi-3 dropped entirely after Spike 1 — Gemma 2B produces superior culturally-differentiated output at the same quantization. Original GGUF: `gemma-2-2b-it-Q4_K_M.gguf` from Hugging Face bartowski/gemma-2-2b-it-GGUF.)*
|
||||
- **Runtime:** `llama-cpp-rs` with GGUF format. Separate inference thread pool at below-normal priority. *(Amended 2026-03-07, Spike 2: IPC is stdin/stdout JSONL pipes, not HTTP. Each worker owns a piped `sr-voice` child process — no network ports. This satisfies Gemma 2 Terms & Conditions: model is only reachable through the game server's queue, never exposed as a service.)*
|
||||
- **Content tiers:** Baked (hub zones, build-time, human-reviewed) → Pre-voiced (background queue, priority-ordered) → Base text fallback (always present).
|
||||
- **Tell treatment:** Passthrough always. Tell state flows into re-voicing prompts as universal tone injectors. Cultural flavor is conditional and additive — humans are humans first; micro-expressions and body language must remain universally recognizable. Per-culture tell-tone tables are optional enrichment, not a launch requirement. *(Amended 2026-03-07, Spike 2: Tell differentiation at 2B — 3/5 tells produce distinguishable output (Nervous, Guarded, Angry). Friendly and RoutineDeviation are inert at 2B capacity — model cannot reliably differentiate them from neutral. Deferred to post-ship or larger model. Angry tell requires length-aware injectors: short/medium content gets standard compression, long content (≥16 words) gets an explicit "keep full claim intact" instruction to prevent destructive information loss.)*
|
||||
- **Determinism:** Cache-as-determinism. LLM generates once per seed; result cached. Cache lookup is deterministic.
|
||||
- **Caching:** Content-length-gated variants. Short lines (≤7 words): neutral only. Medium lines: 3 variants (neutral, high-affect, guarded). Long lines: up to 6 variants. Key: `(npc_stable_id, line_id, tell_state, culture_id)`. *(Amended 2026-03-07: Spike 1 confirmed 2B model cannot produce distinguishable tell-state variants on short lines — 5/5 states produced near-identical output for "Inspection's next week." Length-gated caching reduces wasted compute/storage.)*
|
||||
- **Hardware:** "AI-Enhanced Dialogue" toggle. Layered detection: RAM check → TPT benchmark → recommendation. No hard minimum spec floor. Player can always override.
|
||||
- **Distribution:** Model bundled in game install (~1.5GB).
|
||||
- **Protected categories (never re-voiced):** Tell behaviors, secret-tier dialogue (D-028 Layer 3), anchor lines (D-092), relationship-specific lines naming third parties.
|
||||
- **Composition engine:** Occasional prompt injections (e.g. oath vocabulary, faith expressions) are controlled by the prompt generator at a configurable frequency (e.g. 1-in-4), not by the model. The model never decides injection frequency — it either receives the clause or doesn't. This is a systemic pattern applicable to any culture marker that should appear occasionally. *(Added 2026-03-07: Spike 1 proved 2B models treat vocabulary lists as required markers. Composition-engine gating eliminates both over-use and under-use.)* *(Amended 2026-03-07, Spike 2: Prompt architecture uses a double-prompt technique — critical constraints are repeated in a REMEMBER block immediately before the OUTPUT: stop token to anchor them in the 2B model's attention window. Epistemic markers ("I heard", "apparently", "I think") are preserved via example-based integration, not keyword lists — keyword lists caused the model to emit comma-separated marker dumps. Injections use imperative framing: once fired by the composition engine, the model executes without discretion.)*
|
||||
- **Content classification:** Base text should be classified by content type. `Dialogue` and `Behavior` pass through the LLM. A new `Factual` content type is recommended for lines bearing specific numbers, causal chains, or denial statements — these bypass the LLM entirely and serve base text, because 2B models cannot reliably preserve quantitative precision (e.g., "14 crates in bay seven" became "fourteen crates are missing"). *(Added 2026-03-07, Spike 2: Paula endorsed ContentType::Factual over template-based approaches.)*
|
||||
- **Negative injectors:** All negative injectors (NI-1 through NI-5) belong in per-culture voice personas, not in universal RULES. The universal RULES const contains only format constraints (one line, complete sentences, no invention). Worldbuilding constraints — military ranks, technology vocabulary, humor register, religious language, Earth references — vary by system/planet/location/culture and are authored per-culture in `voice_persona`. *(Amended 2026-03-07, Spike 2: Jeroen directed removal of all worldbuilding from universal RULES. "Military ranks do exist in some parts of the settings." "Why all these assumptions." NI-2/NI-3/NI-4 removed from universal scope; all NIs are now culture-specific.)*
|
||||
- **Validation:** Two-spike strategy. Spike 1: Rust `sr-voice` CLI + manual prompt testing (Jeroen/Mellanie/Paula). Spike 2: full pipeline integration (queue → worker pool → sr-voice child → cache → disk). *(Amended 2026-03-07, Spike 2: Both spikes complete. 39 edge-case test prompts across 8 categories (length, tells, epistemic markers, injections, behaviors, named entities, causal chains, denials). Three rounds of iterative prompt refinement with Paula, Mellanie, and Gestalt reviewing output. Pipeline tested end-to-end with real Gemma 2B at ~16 t/s CPU.)*
|
||||
- **Rationale:** D-122 (all NPCs generated) and D-128 (culture implicit in starting location) require NPC voice to scale across zones and cultures without O(R×Z×C) hand-authoring. The re-voicing model is the only architecture that scales while preserving content quality. Base-text fallback ensures the game is complete without the pipeline.
|
||||
- **Source:** LLM Voice Pipeline Workshop (2026-03-07)
|
||||
- **Raised by:** Team Leader (Jeroen), with Gestalt, Tyre, Paula, Mellanie, Ozzie, Miri, Troblum
|
||||
- **Dissent:** Miri flagged concern about cultural philosophy at 2B model size — addressed via hybrid injector format (instruction + example pairs) and spike validation.
|
||||
- **Amends:** [D-123](#d-123-generative-ai-for-npc-content--build-time-authoring-tool-and-runtime-voice-pipeline) (scope extended from authoring tool to authoring + runtime)
|
||||
- **Supersedes:** [D-124](#d-124-in-game-ollama-for-live-npc-dialogue--deferred-superseded-by-d-138) (in-game AI no longer deferred)
|
||||
- **Resolves:** Q-057 (composable behavior generation), Q-012 (generation expansion method)
|
||||
- **Cross-reference:** [D-010](architecture.md#d-010) (information boundaries), [D-121](#d-121-voice-is-culture-driven--job-as-modifier) (culture-primary voice), [D-122](#d-122-all-npcs-generated--named-npcs-deferred) (all NPCs generated), [D-128](#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) (culture as generator input), [D-029](#d-029-population-entanglement-ratio--305020) (NPC tier model), [D-092](perception.md#d-092) (anchor lines), [D-140](#d-140-dialogue-re-voicing-quality-constraints--paulas-six-rules) (dialogue re-voicing quality constraints)
|
||||
|
||||
### D-139: Composable behavior primitives — three-layer assembly model
|
||||
- **Date:** 2026-03-13
|
||||
- **Decision:** Observable NPC behaviors are composed from three layers rather than authored as flat strings per culture×zone×role combination. The three layers are:
|
||||
1. **BehaviorPrimitive** (on `RoleSpec`): role-generic physical stage directions (e.g., "moves freight containers", "runs diagnostics on a terminal"). Tagged with a `BehaviorContext` (OnShift/OffDuty/Social/Any) that gates when the behavior is eligible. Optional `modifier_hint` for category matching.
|
||||
2. **BehaviorModifier** (on `CultureProfile`): culture-specific clauses appended to actions (e.g., "with mechanical efficiency", "with a watchful eye"). Categorized for matching (work_style, demeanor, social, etc.).
|
||||
3. **Assembly function** (`assemble_behaviors`): at NpcBlueprint instantiation time, filters primitives by context, selects a culture modifier per primitive (preferring hint matches, falling back to any), concatenates `action + " " + modifier.clause`. No modifier → action text used as-is.
|
||||
- **Rationale:** The current model has `typical_behaviors: Vec<String>` on RoleSpec — flat strings per culture×zone×role. At ~50 behaviors × 4 roles × N zones × M cultures, this is O(roles × zones × cultures) custom content. Decomposition to primitives + modifiers reduces to O(roles + cultures) authored content. Assembly is deterministic via SimRng, so behavior output is reproducible for a given seed. The three-layer model maps directly to the existing CultureProfile/RoleSpec/NpcBlueprint data flow — no new serialization formats or pipeline stages.
|
||||
- **Implementation:** `server/src/npc/blueprint.rs` — `BehaviorPrimitive`, `BehaviorContext`, `BehaviorModifier` structs + `assemble_behaviors()` function. `RoleSpec.behavior_primitives: Vec<BehaviorPrimitive>` (serde default, backward-compatible). `CultureProfile.behavior_modifiers: Vec<BehaviorModifier>` (serde default). Legacy `typical_behaviors` field preserved until content migration complete.
|
||||
- **Migration path:** Copy team populates `behavior_primitives` on zone spec RON files and `behavior_modifiers` on culture RON files. Generator switches from `typical_behaviors` to `assemble_behaviors()` when primitives are present. Once verified equivalent for seed 42, legacy field can be removed.
|
||||
- **Source:** Sprint 26, ticket #633 (implements Q-057)
|
||||
- **Raised by:** Tyre (Technical Architect)
|
||||
- **Dissent:** None (design resolves the scaling problem identified in #630 sprint review)
|
||||
- **Resolves:** Q-057 (composable behavior generation — data structure definition)
|
||||
- **Cross-reference:** [D-138](#d-138-llm-re-voicing-pipeline-for-npc-voice) (resolved pipeline, this resolves data format), [D-121](#d-121-voice-is-culture-driven--job-as-modifier) (culture-primary voice), [D-122](#d-122-all-npcs-generated--named-npcs-deferred) (all NPCs generated)
|
||||
|
||||
### D-140: Dialogue re-voicing quality constraints — Paula's six rules
|
||||
- **Date:** 2026-03-13
|
||||
- **Decision:** Six binding constraints govern the LLM re-voicing queue for all dialogue lines. These rules protect the information asymmetry mechanic (D-005), character voice integrity, and game narrative legibility. They are implemented in the prompt engineering layer and validated in baked content review.
|
||||
- **D-140-R1 — Secret-tier passthrough:** Lines tagged `trust: secret` (D-028 Layer 3) never enter the re-voicing queue. They are served as authored base text unconditionally. Re-voicing risks dramatization (inflating the disclosure) or trivialization (flattening the weight of the secret) — both failures corrupt the earned relationship payload.
|
||||
- **D-140-R2 — Epistemic weight must not shift:** Certainty level of factual claims must survive re-voicing unchanged. Hedge words ("I think," "I heard," "might be," "probably") and direct evidential markers ("I saw," "I was there," "he told me") must appear in re-voiced output with the same epistemic force as in the base text. Epistemic drift is the dialogue re-voicing failure mode most invisible to reviewers and most damaging to gameplay — the player reads voiced text and constructs a knowledge model. A shifted hedge changes what the player knows.
|
||||
- **D-140-R3 — Access tier feel must be preserved:** The social register appropriate to the D-028 access tier tag must survive re-voicing. `public` stays neutral-transactional; `peer` stays lateral-relaxed; `insider` stays familiar-complicit; `authority` stays institutional-asymmetric; `hostile` stays minimal-closed. The tag governs eligibility; the register governs feel. An `insider` line re-voiced into institutional language reads as `authority` to the player regardless of tag. Implementation: access tier injected as a constraint clause alongside the culture injector.
|
||||
- **D-140-R4 — Named entities are passthrough within output:** Any proper noun in the base text (NPC names, location names, faction names, technology terms) must appear verbatim in the re-voiced output. Named entities carry specific information — "Kael" and "that dock worker" are not interchangeable in an information-asymmetry game. Implementation: extraction step before re-voicing; protected entity list injected as a hard constraint. The extractor need not understand lore — capitalized terms are sufficient for identification.
|
||||
- **D-140-R5 — Relationship-specific lines are passthrough:** Any dialogue line naming a specific third-party NPC or describing a specific interpersonal event is not re-voiced. It is served as authored base text. These lines carry social information whose phrasing is load-bearing — the hesitation, the neutral delivery, the precise ambiguity are all authored intentionally. Re-voicing risks substituting the named NPC with a reference, dramatizing the event, or adding social judgment not in the original.
|
||||
- **D-140-R6 — Tell-context modifier cannot override culture register:** When a tell-context injector is active, it shapes emotional inflection within the culture register — it does not replace the register. A Van Maanen's Star NPC with a Nervous tell still speaks in Van Maanen's Star register (direct, minimal pleasantries, working-class pragmatic) while the content reflects nervous pressure. Culture is primary (D-121); tell-context is situational. Implementation: culture injector is always applied before tell-context modifier; tell-context is framed as inflection, not override.
|
||||
- **Rationale:** D-138 established the architecture; these rules operationalize the quality floor for dialogue content specifically. Dialogue re-voicing carries higher information risk than behavior re-voicing — dialogue is direct player-NPC exchange where epistemic signals and relationship registers matter most. These rules scale with the pipeline: at 300 systems and thousands of NPCs, the prompt engineering layer must enforce these constraints programmatically, not through per-line human review. The constraints are formalized here so server team, copy team, and QA can reference them independently.
|
||||
- **Scaling note:** R4 (named entity extraction) requires a proper noun tagger that works across all culture naming conventions — Van Maanen's Star names differ structurally from other cultures. The extractor approach (capitalized terms as proxy) is sufficient for the Van Maanen's Star launch system but must be culture-aware for systems with non-capitalized or logographic naming conventions. This is a DLC-scope concern, not a v0.2 blocker.
|
||||
- **Source:** LLM Voice Pipeline Workshop (2026-03-07), Paula Round 3 (`docs/workshops/llm-voice-pipeline/paula-round3.md`)
|
||||
- **Raised by:** Paula (LLM Voice Pipeline Workshop, Round 3)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-123](#d-123-generative-ai-for-npc-content--build-time-authoring-tool-and-runtime-voice-pipeline) (pipeline modes), [D-138](#d-138-llm-re-voicing-pipeline-for-npc-voice) (full architecture), [D-028](#d-028-four-relational-dialogue-layers) (access tier model), [D-005](scope.md#d-005-core-concept---single-character-first-person-story-generator) (single character, information asymmetry as core), [D-092](perception.md#d-092) (anchor lines)
|
||||
|
||||
### D-142: Zone-type template architecture for scalable NPC behavior
|
||||
- **Date:** 2026-03-13
|
||||
- **Decision:** Behavior primitives are zone-type-generic, not per-location. The content architecture for NPC behavior across 300+ systems is a three-layer composition model:
|
||||
|
||||
**Layer 1 — Zone-type primitives (what the body does):** Universal physical stage directions per role, defined at the zone-type level. A `farmer` role in a `rural_agricultural` zone does the same base actions in any system. Primitives are authored once per role per zone type. They are context-tagged (`OnShift`, `OffDuty`, `Social`) and carry an optional `modifier_hint` for category-matched culture assembly.
|
||||
|
||||
**Layer 2 — Culture modifiers (how this culture does it):** Clauses appended to primitives at assembly time, defined on `CultureProfile`. Seven categories: `work_pace`, `physical_manner`, `social_signal`, `task_completion`, `environmental_scan`, `offduty_posture`, `authority_response`. Culture modifiers are authored once per culture, work with all zone types immediately.
|
||||
|
||||
**Layer 3 — Gemma LLM flavor (what's happening here and now):** Runtime enrichment only. Adds location-specific sensory and environmental detail: weather, time of day, lighting, ambient sound, physical environment state. Layer 3 is **culture-neutral** — it must not introduce cultural vocabulary, must not generate named entities, must not override culture register (D-140-R6), must not alter epistemic markers (D-140-R2). Layer 3 follows the pre-voiced three-layer safety model from D-138 (base-text fallback on failure, validated injector vocabulary, contamination filter for named entities). If Layer 3 fails or is unavailable, the Layer 1+2 assembly is served as-is.
|
||||
|
||||
**Standalone readability constraint:** Layer 1+2 assembly (base text) must be playable and informative without the LLM. A player reading base text must be able to read what an NPC is doing. "Works a crop row, stopping to pull weeds, without wasted motion" is informative; "farms" is not. This constraint governs primitive authoring across all zone types.
|
||||
|
||||
**Location spec format:** Location files (`content/locations/{system}-{zone}.ron`) declare a `zone_type` identifier and reference a `culture`. They carry metadata (economic_level, population_density, role weights, social sites) but contain **no primitives**. All behavior content lives at the zone-type and culture layers.
|
||||
|
||||
- **Zone-type taxonomy (31 types, v1.0):** The following zone types constitute the canonical behavior template library. Each produces a distinct NPC behavior pool and distinct map generator layout template. Zone types sharing a group prefix differ enough in physical layout to require separate templates.
|
||||
|
||||
| Group | Zone Types |
|
||||
|-------|-----------|
|
||||
| Rural | `rural_agricultural`, `rural_pastoral`, `rural_aquaculture`, `rural_orbital` |
|
||||
| Industrial | `industrial_freight`, `industrial_manufacturing`, `industrial_processing` |
|
||||
| Port | `port_space`, `port_surface`, `port_maritime`, `port_fishing` |
|
||||
| Extraction | `extraction_space`, `extraction_surface`, `extraction_platform` |
|
||||
| Commercial | `commercial_market`, `commercial_transit` |
|
||||
| Administrative | `administrative_civil`, `administrative_judicial` |
|
||||
| Single | `research_station`, `medical_facility`, `military_garrison`, `security_checkpoint`, `entertainment_hospitality`, `entertainment_venue`, `residential_station`, `residential_surface`, `residential_dispersed`, `detention_facility`, `archaeological_site`, `wilderness_frontier`, `diplomatic_elite` |
|
||||
|
||||
Subtype distinctions within groups are map-generator-significant: a `port_space` (docking bays, airlocks, approach corridors) generates a physically different layout from `port_maritime` (piers, wharves, waterfront) or `port_fishing` (jetties, small craft, catch processing), and the NPC actions differ accordingly.
|
||||
|
||||
- **POI system (three-tier):** Points of interest that create narrative destinations (monuments, gatebuilder ruins, prisons, pilgrimage sites, abandoned installations) are handled at three levels without requiring new zone types for each:
|
||||
|
||||
*Tier 1 — POI-as-zone-type:* Sites large enough to have distinct layout, NPC population, and behavior pool are zone types. `archaeological_site` and `detention_facility` are in the canonical 31. Additional large POI zone types can be added as content permits.
|
||||
|
||||
*Tier 2 — `abandoned` flag:* Any zone type can carry `abandoned: true` on its location spec. The map generator produces a decay variant of the base layout; the behavior pool switches to a cross-cutting scavenger/squatter/investigator primitive set. This generates abandoned station variants, ruined industrial facilities, collapsed residential blocks, and derelict extraction rigs without pre-authoring each as a separate zone type.
|
||||
|
||||
*Tier 3 — `poi_overlay` field:* Small POIs (monuments, memorials, commemorative markers, shrines, public art) exist within an existing zone rather than as their own map. The location spec carries a `poi_overlay` list; the map generator places overlay elements within the zone layout. No new behavior pool required.
|
||||
|
||||
The combination handles the full POI design space: `gatebuilder_ruin` = `archaeological_site` zone type; `abandoned_station` = any station zone type + `abandoned: true`; `monument` = `poi_overlay` on a `commercial_transit` or `residential_surface` zone; `pilgrimage_site` = `poi_overlay` cluster on appropriate base zone, or its own zone type if narrative scale warrants.
|
||||
|
||||
- **Scale math:** 31 zone types × ~4 roles × ~15 primitives = ~1,860 authored primitive lines. 300+ cultures × ~12 modifiers = ~3,600+ modifier clauses. ~5,500 authored lines produce behavior across unlimited locations. Authoring cost is O(zone_types + cultures), not O(locations). New location: pick zone type + culture + metadata — zero behavior authoring. New culture: ~12 modifiers + voice persona — works with all 31 zone types immediately. New zone type: ~60 primitives — works with all cultures immediately.
|
||||
|
||||
- **File layout:**
|
||||
- Zone-type templates: `content/global/zone-types/{zone_type}.ron`
|
||||
- Culture profiles: `content/global/culture-{name}.ron` (existing)
|
||||
- Location specs: `content/locations/{system}-{zone}.ron` (metadata only, no primitives)
|
||||
|
||||
- **Rationale:** The per-location primitive model (current `typical_behaviors` and per-location `behavior_primitives` arrays) does not scale to 300 systems. A Van Maanen's Star farmer and a Vael farmer doing the same physical work in the same zone type are authoring the same primitives twice — the content that differs between them is the *how* (culture), not the *what* (the physical action). Separating these dimensions reduces authoring cost by an order of magnitude and ensures that adding a new system is a metadata operation, not a content sprint. The standalone readability constraint ensures the system degrades gracefully when the LLM is unavailable, which is a runtime reliability requirement for a 300-system game, not just a fallback policy.
|
||||
|
||||
- **Layer 3 grammar constraint:** When Gemma appends environmental flavor to Layer 1+2 assembled text, the flavor clause must grammatically attach as a prepositional phrase or coordinating conjunction. Absolute and participial phrases (e.g., "tool already in hand") require a leading comma separator. Culture-specific modifier clauses that use absolute-phrase construction must include the separator (e.g., ", tool already in hand") or be rewritten as prepositional form ("with tool in hand") to ensure clean assembly. This constraint applies to all culture profile modifier authoring.
|
||||
|
||||
- **Source:** Sprint 26 zone-type taxonomy discussion (2026-03-13); behavior review (#634); user requirements for 300-system scalability
|
||||
- **Raised by:** Paula (zone-type taxonomy and POI system); Gestalt (assembly engine); Mellanie (primitive content); Tyre (architectural review)
|
||||
- **Dissent:** None
|
||||
- **Supersedes:** Per-location behavior pool approach from current zone spec format (`behavior_primitives` arrays on location RON files). Location files retain metadata but behavior content migrates to zone-type template files.
|
||||
- **Amends:** [D-139](#d-139-composable-behavior-primitives-three-layer-assembly) — D-139 defined the assembly mechanics (BehaviorPrimitive, BehaviorModifier, assemble_behaviors); this decision defines the content architecture that feeds it. D-139 remains the implementation record; D-142 is the content architecture record.
|
||||
- **Cross-reference:** [D-138](#d-138-llm-re-voicing-pipeline-for-npc-voice) (LLM pipeline — Layer 3 safety model), [D-140](#d-140-dialogue-re-voicing-quality-constraints--paulas-six-rules) (quality constraints — R4, R6 apply to Layer 3), [D-139](#d-139-composable-behavior-primitives-three-layer-assembly) (assembly mechanics), [D-121](#d-121-voice-is-culture-driven--job-as-modifier) (culture-primary voice), [D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting) (Van Maanen's Star setting origin of first zone specs), [D-128](#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) (culture implicit in location)
|
||||
|
||||
---
|
||||
|
||||
### D-143: GD calendar epoch — Gate Discovery (2300 AD) as year 0
|
||||
- **Date:** 2026-03-14
|
||||
- **Decision:** The Settled Reach uses the Gate Discovery (GD) calendar. Year 0 GD = 2300 AD. The game present is ~600 GD (~2900 AD). The secession occurred ~300 GD (~2600 AD). The five settlement waves span 0–600 GD. Earth dates (AD/BC) exist but are an Earth-internal reference most Reach residents wouldn't use. All `age_years` fields in the systems framework measure years before game present, not GD years directly.
|
||||
- **Rationale:** A civilization that seceded from Earth would not use an Earth religious calendar. The gate discovery is the founding event of the Reach — the moment human settlement beyond Sol became possible. 2300 AD provides enough time (~275 years from present day) for pre-gate spacefaring development including Mars terraforming (~2100-2200 AD, or roughly -200 to -100 GD).
|
||||
- **Implications:** Mars terraforming predates the gates — it's an Earth-only achievement, which adds to the "we built everything" obligation narrative. The ~12,900-year span of human civilization becomes a number only Earth institutions would cite. Reach residents measure history from the gates forward.
|
||||
- **Reference timeline:**
|
||||
|
||||
| Event | GD | AD |
|
||||
|---|---|---|
|
||||
| Human civilization origin | ~-10600 GD | ~10,000 BC |
|
||||
| Mars terraforming begins | ~-200 GD | ~2100 AD |
|
||||
| **Gate Discovery (epoch)** | **0 GD** | **2300 AD** |
|
||||
| Five settlement waves | 0–600 GD | 2300–2900 AD |
|
||||
| Secession | ~300 GD | ~2600 AD |
|
||||
| Game present | ~600 GD | ~2900 AD |
|
||||
- **Cross-reference:** [D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting) (setting), Sol wiki page (GJ-0)
|
||||
|
||||
---
|
||||
|
||||
### D-144: Sirius (GJ 244A / S-067) as Reach capital — seat of the Concord Assembly
|
||||
- **Date:** 2026-03-14
|
||||
- **Decision:** Sirius is the political capital of the Settled Reach and the seat of the Concord Assembly. It is a hub system (5 apertures, 5 gate connections) in the institutional core, settled in wave_1, 8.6 ly from Sol. Its real-world prominence (brightest star in Earth's sky) maps to its in-setting political centrality. Marked as `generation_priority: campaign_anchor`.
|
||||
- **Rationale:** The capital needs to be a recognizable name that players immediately associate with importance. Sirius's existing topology (hub, 5 connections) already makes it structurally central. Wave_1 settlement means it has the institutional depth to house the Assembly. The symbolic weight of the brightest star as the seat of power writes itself.
|
||||
- **Cross-reference:** [D-143](#d-143-gd-calendar-epoch--gate-discovery-2300-ad-as-year-0) (timeline), [D-036](#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting) (v0.1 setting)
|
||||
|
||||
---
|
||||
|
||||
### D-147: Aesthetic taste as character personality trait — shared root for cosmetic and environmental expression
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** Characters have an `aesthetic_taste` personality trait (preferred palette, style leanings) that naturally expresses in both personal appearance and living space. This is NOT a cosmetic→apartment pipeline — hair color does not map to wall color. Instead, taste is a shared root: someone who gravitates toward teal will pick teal clothing AND own a teal vase. The apartment generator reads the character's taste trait (alongside economic position from #615 and cultural context from #679); the character customisation screen lets the player express that same taste through appearance choices. Neither system depends on the other — both read the same underlying trait.
|
||||
- **Rationale:** The naive approach (pipe cosmetic choices into apartment generator) creates a crude "team color" mapping that feels artificial. The elegant approach: taste is a personality attribute, like traits or skills. It manifests independently in multiple contexts. This keeps #619 (customisation) and #617 (apartment) architecturally independent while producing coherent identity expression. The taste trait is also reusable: NPC aesthetic preferences, gift preferences, "does this room feel like home" comfort checks, cultural style variations.
|
||||
- **Dependency implication:** #619 does NOT block #617. Both read the character's taste trait independently. The taste trait definition belongs to the character data model (server), not to either consuming system.
|
||||
- **Information boundary (D-010):** `aesthetic_taste` is a public trait — visible to other entities and the client. NPCs can observe the player's taste (e.g. gift relevance, comfort assessment). This is not private knowledge behind the information boundary.
|
||||
- **Source:** Sprint 27 planning pass — Q-WTF-040 resolution
|
||||
- **Raised by:** Project lead (taste-as-shared-root framing), Gestalt (ColorHint concept evolved into trait), Paula (culture + economics as primary apartment drivers)
|
||||
- **Dissent:** Ozzie argued for direct cosmetic→apartment pipeline. Tyre and Paula argued for no connection at all. The taste trait is the synthesis: connection through personality, not through data pipeline.
|
||||
- **Cross-reference:** [D-125](#d-125-world-is-quietly-responsive--gradient-of-caring-by-social-proximity) (quiet responsiveness), [D-134](architecture.md#d-134-full-character-customisation--hair-clothing-colors-at-tile-scale) (full character customisation), [D-136](architecture.md#d-136-first-settled-reach-moment-auto-generated-apartment--insert-activation) (first game moment), ticket #617 (auto-generated apartment), ticket #619 (full character customisation)
|
||||
- **Resolves:** Q-WTF-040
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
### ~~Content Pattern Note: Generator-compatible overheard conversation format (ticket #664)~~ SCRAPPED (R-012)
|
||||
- **Superseded:** 2026-04-10. NPC ambient interaction model scrapped. See [R-012](../rejected/perception.md#r-012-overheard-npc-conversation-system-d-078--scrapped).
|
||||
|
||||
---
|
||||
|
||||
### D-167: Heritage Roots Superseded — Corridor Cultural System Replaces Abstract Roots
|
||||
- **Date:** 2026-03-24
|
||||
- **Decision:** The 7 abstract heritage roots (Frost / Stone / Tide / Vine / Dust / Iron / Salt) are retired. Clean break. The real-world cultural corridor system is canonical:
|
||||
- **North Reach:** Commonwealth (British / Australian / Canadian / South African / Indian / Nigerian)
|
||||
- **South Reach:** Iberian / Latin American + Southern African
|
||||
- **East Reach:** East Asian + South / Southeast Asian
|
||||
- **West Reach:** Northern / Central European + Central / Eastern European
|
||||
|
||||
Cultural data is authored per-system in `systems.db` and the 301 wiki entries. The wiki IS the cultural register — the corridor framework from `docs/design/cultural-migration-pressure.md` was the input to wiki authoring, and now the wiki text is the input to generation and naming.
|
||||
- **Rationale:** The heritage root system was an abstract intermediate layer that never mapped cleanly onto the actual cultural material being authored. The corridor framework produced 301 grounded wiki entries with real cultural specificity. Retiring the abstract roots in favour of the concrete wiki-and-corridor system eliminates the translation step and keeps the cultural register in one canonical place.
|
||||
- **Raised by:** Jeroen, established 2026-03-24 during world generation workshop.
|
||||
- **Dissent:** None.
|
||||
- **Supersedes:** D-104 (heritage grammar overlay for non-urban palettes), D-105 (non-urban informal zone typology — heritage root correlations), D-101 axis A (ZonePalette modifier axis A = HeritageRoot, in `decisions/architecture.md`), D-107 (trauma events — heritage root baseline in cultural decay model).
|
||||
- **Cross-reference:** `docs/design/cultural-migration-pressure.md`, `wiki/star-systems/` (301 entries), `docs/workshops/world-generation/sw1-interview-answers.md`
|
||||
|
||||
---
|
||||
|
||||
### D-168: Iserlohn (GJ-532c) planet name — keep, real-city origin documented
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The planet name "Iserlohn" (GJ-532c, in the Kettenschmied system) is **retained**. The name derives from Iserlohn, a real industrial city in the Sauerland region of North Rhine-Westphalia, Germany — historically a centre of wire-drawing, chain manufacturing, and metal fabrication. This origin is directly coherent with Kettenschmied's identity as a west_reach German-heritage metalworking community. The real-city reading is the intended and primary reading.
|
||||
- **IP note:** Iserlohn Fortress is an iconic location in *Legend of the Galactic Heroes* (Ginga Eiyuu Densetsu). The name collision is acknowledged. The decision to retain is deliberate: the real-world German city predates the anime by centuries; real geographic names are not protectable; and the concept diverges fundamentally — a cold marginal mining/fabrication planet (1,000 population, component fabrication, asteroid mining) is the structural opposite of a strategic military megastructure. No reader can point at GJ-532c and say "that's the LoGH fortress" — the contexts share only a name.
|
||||
- **Preferred alternative on record (if future team prefers a rename):** **Altena** — a Sauerland city at the confluence of Lenne and Volme rivers, historically the actual birthplace of German wire-drawing and chain manufacture. The Altena castle became the site of the first industrial wire-drawing operation in the German states. Altena has no known SF franchise association and carries stronger historical precision for chain/cable fabrication. It would require an atlas rename of `GJ532c` and corresponding wiki edits.
|
||||
- **Raised by:** Miri (Sprint 31, ticket #773)
|
||||
- **Dissent:** None.
|
||||
|
||||
### D-193: Lattice Commission — canonical long-form of the Commission
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** The Concord Assembly's regulatory authority is formally named **"the Lattice Commission"**. In-prose short form remains "the Commission" (unambiguous in context). Drift forms that appeared in earlier copy reviews — "Concord Commission" and "Assembly Commission" — are **non-canonical** and must be corrected wherever they appear. The long-form is required for institutional POI signage, tractus fee legal text, wiki page headers, and any formal/legal context.
|
||||
- **Rationale:** The Commission's regulated domain — implant hardware, medical-grade replacements, pharmaceutical production, and safety-critical manufactured goods that feed the Lattice — is what authorizes and scopes its jurisdiction. Naming it after the regulated domain (rather than the parent Assembly) mirrors how real-world regulatory bodies are often named by what they regulate (FDA, FAA, NRC) rather than by their chartering body. It also disambiguates from "Concord" which otherwise appears in the Concord Assembly itself, the Concord's member systems, etc. The Commission has no authority in Compact member systems — its identity is Lattice-scoped, not Concord-scoped.
|
||||
- **Affects:** Wiki content (all `wiki/factions/`, `wiki/technology/`, `wiki/corporations/` pages that reference the Commission), marker POI naming (e.g. `"Lattice Commission — Sirius Office"`), formal legal text in tractus fee documentation, institutional signage, institution templates in `wiki/_templates/`, dialogue pools, copy guides.
|
||||
- **Resolves:** [Q-095](../questions/content.md#q-095-commission-formal-name--authoritative-designation)
|
||||
- **Raised by:** Copy review (Sprint 35, PR #127); resolved by Jeroen on 2026-04-21
|
||||
- **Dissent:** None.
|
||||
|
||||
---
|
||||
|
||||
*47 decisions. Last updated: 2026-04-21 (D-193 Lattice Commission name resolved)*
|
||||
@@ -0,0 +1,424 @@
|
||||
# Economics Decisions
|
||||
|
||||
Confirmed decisions, open questions, and rejected alternatives for the economics layer of The Settled Reach.
|
||||
|
||||
This domain covers: currency system, commodity taxonomy, shadow economy, corporation structure, productivity seeding, simulation architecture, and the data pipeline. Cross-reference [architecture.md](architecture.md) for Phase 2 deliverable framing (D-166) and [content.md](content.md) for economic verb vocabulary (D-131, Phase 3+).
|
||||
|
||||
---
|
||||
|
||||
### D-171: Three-Currency System
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The Settled Reach uses three currencies with distinct political identities and geographic zones:
|
||||
- **Tractus** — issued by the Concord Assembly (headquartered at Sirius). The Reach-wide standard currency. Accepted everywhere. Numeraire for all simulation pricing. The establishment currency. Groombridge hosts the clearing house (D-175 Tier 1 gap) but is not a co-issuer.
|
||||
- **Mark** — issued by the Compact of Westphalia. Created to disconnect from Tractus; circulates within the Compact zone (west reach hops 6+). Mostly refused outside Compact territory. Tractus is accepted within the Compact at punitive exchange rates.
|
||||
- **Sol** — Earth legacy currency. Finite pool, no active issuer, no formal exchange rate. Used for crime and untraceable transactions, and as payment for premium Earth luxury imports (wines, foods, exclusive goods). Sol is NOT a currency zone — it is modeled as a shadow economy commodity, not a simulation numeraire.
|
||||
- Commission fines and certification fees are Tractus-denominated (the Commission is Assembly-funded). Compact members paying Commission costs face currency conversion friction — this is a structural driver of the shadow economy in the Compact zone, not a coincidence.
|
||||
- **Rationale:** Three currencies create structural economic bloc tension without requiring event generation. The Tractus/Mark divide maps directly to the Assembly vs. Compact political divide. Sol's untraceable nature makes it the natural medium for crime — it has lore grounding and mechanical function without requiring a formal exchange rate.
|
||||
- **Raised by:** Full planning team, Sprint 32 Workshop #796. Lead directive on political framing.
|
||||
- **Dissent:** Burnelli-Sheldon (economist) recommended single currency for Phase 2 — see [R-011](../rejected/economics.md#r-011-single-currency-for-phase-2-economics). Overruled by lead.
|
||||
|
||||
---
|
||||
|
||||
### D-172: Currency Zone Initialization
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Each star system receives a currency zone flag at initialization:
|
||||
- `TRACTUS_PRIMARY` — default for all Assembly-compliant systems
|
||||
- `MARK_PRIMARY` — Compact of Westphalia member systems
|
||||
- `MIXED` — Compact-sympathetic systems (west reach hops 5–6); both currencies accepted, neither dominant
|
||||
- Sol has no zone flag — tracked in shadow economy layer only (see [D-174](#d-174-shadow-economy-layer))
|
||||
- Mark-to-Tractus friction: ~3% conversion cost on cross-zone trade
|
||||
- Within `MARK_PRIMARY` zones: zero internal conversion friction (Compact's "no internal tariffs" principle extends to currency)
|
||||
- Zone assignment derives from political affiliation (Compact membership, Commission presence), NOT from hop distance. Hop distance correlates with Compact membership but is not the rule.
|
||||
- **Rationale:** Currency zones encode political reality, not geography. A hop-5 system that joined the Compact is `MARK_PRIMARY`; a hop-8 system that stayed Assembly-compliant is `TRACTUS_PRIMARY`. The zone flag must be authorable, not calculated.
|
||||
- **Raised by:** Tyre (schema design), Paula (geographic variance), Miri (lore grounding). Lead corrected political framing from hop-distance to affiliation-based.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-171](#d-171-three-currency-system), [wiki/factions/compact-of-westphalia.md](../wiki/factions/compact-of-westphalia.md)
|
||||
|
||||
---
|
||||
|
||||
### D-173: Commodity Taxonomy
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The simulation uses approximately 30 commodity types organized in four categories:
|
||||
- **7 raw materials** — extracted or harvested, location-bound production
|
||||
- **8 intermediate goods** — processed from raws, transportable
|
||||
- **7 final goods** — assembled from intermediates, carry cultural identity
|
||||
- **~5 professional services** — legal, banking/credit, insurance, logistics management; location-bound (non-transportable through gates)
|
||||
- **~3 luxury/experiential services** — tourism, holo-content/entertainment, cultural experiences; location-bound
|
||||
- Services sit outside the production chain (Raw → Intermediate → Final). Services consume goods but do not produce them.
|
||||
- Each commodity record: tier, elasticity class (4 categories per D-184: perfectly_inelastic, inelastic, unit_elastic, elastic), base price, bulk class, political sub-flags.
|
||||
- Leontief fixed-coefficient production: scarcity in one input cascades to all dependents. No substitution within a tier.
|
||||
- Substitutable inputs at intermediate level: multiple raw sources can satisfy the same intermediate demand (e.g., two ore types producing the same alloy). Substitution is structural (different production chain routes), not smooth.
|
||||
- **Rationale:** Fixed-coefficient production creates legible scarcity cascades — the player can trace why a final good is expensive by following the chain. Services are location-bound by definition (a legal service in Ostmark cannot be freighted to Groenland). The ~30 count is rich enough to generate interesting geographic specialization without becoming intractable to author.
|
||||
- **Raised by:** Burnelli-Sheldon (22-commodity formal model), Gestalt (production chain principles), Paula and lead directive (services and luxury services addition).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-131](content.md#d-131-broad-economic-verb-vocabulary--life-verbs-not-tycoon-specific) (economic verbs — Phase 3+ player interaction), [D-175](#d-175-corporation-taxonomy-and-prerequisite) (corporation archetypes), [D-184](#d-184-commodity-catalog-36-types) (concrete realization: counts revised to 9/10/9/5/3 = 36 total, 4 elasticity classes)
|
||||
|
||||
---
|
||||
|
||||
### D-174: Shadow Economy Layer
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Each economic node has a `shadow_economy_intensity` value (0.0–1.0) set at initialization:
|
||||
- **Seeding inputs (additive):** Commission presence (inverse — high Commission = low shadow), Compact membership (elevated shadow independently of distance), hop distance from Core, gate topology (dead-end systems higher than transit nodes)
|
||||
- **Geographic reference bands:** core systems ~0.0–0.2, mid-reach ~0.3–0.6, Compact and frontier ~0.6–0.9
|
||||
- **Effects of intensity:** Sol black-market premium (higher intensity = higher Sol premium), contraband shadow prices below Commission-certified prices, service quality degradation in formal sector
|
||||
- Sol is the shadow medium of exchange — untraceable, no lattice audit trail, no issuer to cooperate with enforcement
|
||||
- Canonical contraband types (from lore): unlicensed lattice components ([D-037](content.md#d-037)), Sol-denominated luxury goods, unregistered commercial intelligence, unlicensed re-embodiment
|
||||
- Shadow economy is a **structural initialization parameter**, not an event. Events from the storyteller/political layer can temporarily modify intensity, but do not create or destroy the layer.
|
||||
- The Compact's shadow economy is principled economic resistance to Assembly currency friction on enforcement costs — not frontier lawlessness. This distinction matters for NPC dialogue and narrative framing.
|
||||
- **Rationale:** Crime and smuggling are geographic realities with strong variation. Modeling them as a per-node intensity parameter keeps the simulation tractable — no need for a separate "crime sim." The Compact framing is important: Compact members aren't criminals by disposition, they're communities that have rationally priced Commission authority as unacceptable. Their shadow economy is a consequence of currency friction, not cultural character.
|
||||
- **Raised by:** Lead directive. Paula (geographic variance and Compact framing), Nigel (seeding architecture), Gestalt (`official_coverage_ratio` signal), Tyre (schema), Miri (Compact friction analysis).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-171](#d-171-three-currency-system) (Sol as shadow commodity), [D-172](#d-172-currency-zone-initialization) (Compact friction), [D-037](content.md#d-037) (canonical contraband: lattice components)
|
||||
|
||||
---
|
||||
|
||||
### D-175: Corporation Taxonomy and Prerequisite
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The corporation corpus is organized in three tiers and is a **prerequisite for Phase 2**:
|
||||
- **Tier 1: ~38 named, textured corporations** — 13 existing wiki corporations upgraded, 25 new including a Groombridge clearing house. Full identity, political relationships, behavioral archetype, administered silences, named leadership. These are the economic landmarks the player will recognize.
|
||||
- **Tier 2: ~150 regional firms** — proper identity (sector, corridor, backstory, distinct character) but not fully textured. Regional competitors that can fail, grow, or be acquired.
|
||||
- **Tier 3: ~5,000 template instances** — named businesses generated from templates, distributed by population. Name, location, product variation. The economic texture the player walks past.
|
||||
- Two orthogonal archetype systems apply independently:
|
||||
- **28 lore-taxonomy archetypes** (WHAT/WHERE — Miri): extraction (5), agriculture (6), manufacturing (6), trade/logistics (4), services (6), intelligence (1), plus 5 east-reach archetypes
|
||||
- **6 behavioral archetypes** (HOW — Burnelli-Sheldon): Monopolist, Distributor, Producer, Specialist, Cooperative, Intermediary
|
||||
- Priority gaps for Tier 1 creation: financial services, re-embodiment sector, clearing house (Groombridge), Compact-affiliated distributor, east reach anchors, information brokerage
|
||||
- **Phase 2 begins when the corporation corpus reaches commodity coverage threshold** (minimum: 3+ corporations per major commodity type, 1+ per inhabited system above 100K population). The simulation will not be seeded with placeholder corporations.
|
||||
- **Rationale:** Corporation density is what makes the simulation legible. A simulation running on 13 corporations in 3,700 nodes would generate nonsensical price signals — corporations would appear to be everywhere at once. The tier structure enables targeted authoring effort: Tier 1 gets full narrative investment, Tier 3 gets generation rules. The prerequisite gate prevents building a simulation that has nothing meaningful to simulate.
|
||||
- **Raised by:** Lead directive (prerequisite, density, 5,000 template instances). Miri (28 archetypes, east reach gap). Burnelli-Sheldon (6 behavioral archetypes). Paula (Tier 1 gap list, clearing house). Tyre (generation pipeline coverage rules).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-166](architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order) (Phase 1 content completion gates Phase 2), [D-173](#d-173-commodity-taxonomy) (commodity types requiring coverage), [D-183](#d-183-iterative-economics-development-cycle)
|
||||
|
||||
---
|
||||
|
||||
### D-176: Productivity Seeding
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Each run seeds per-run productivity multipliers on five dimensions, attached to **corporation×site pairs** (not abstract nodes):
|
||||
- `extraction_rate` — output per unit time from mines, wells, fisheries
|
||||
- `processing_throughput` — units processed per tick in manufacturing and refineries
|
||||
- `transit_capacity` — freight volume per gate crossing for logistics operators
|
||||
- `service_throughput` — clients served per tick for service firms
|
||||
- `service_capacity` — maximum concurrent engagements for service firms
|
||||
- Standard nodes: 0.4–1.8× multiplier, log-normal distribution, corridor correlation ~0.6 (nearby sites in the same corridor tend toward similar productivity)
|
||||
- Monopoly-source nodes: 0.7–1.4× (tighter range — lore-grounded scarcity ceilings apply; see [D-177](#d-177-productivity-constraints-lore-derived))
|
||||
- The same lore picture appears every run; different underlying productivity cards. Emergence happens DURING play, not seeded before it.
|
||||
- Seeds are computed at runtime from PRNG seed. Stored in game save state. Never authored in TOML files.
|
||||
- **Rationale:** Seeding starting positions (corporate health, pre-existing disruptions) erodes the hand-crafted lore picture from Phase 1. Seeding productivity coefficients preserves the lore picture (same corporations, same locations, same relationships) while ensuring every run has a different underlying economic reality. "Same team, different cards."
|
||||
- **Raised by:** Lead directive (seed productivity, not starting positions). Nigel (architecture, ranges, corridor correlation). Miri (constraints table that defines the seeding bounds).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-177](#d-177-productivity-constraints-lore-derived) (what can and cannot be seeded)
|
||||
|
||||
---
|
||||
|
||||
### D-177: Productivity Constraints (Lore-Derived)
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Lore-derived ceilings constrain what productivity seeding can vary. These constraints are authoritative and not subject to per-run seeding:
|
||||
- **Hard biological ceilings:** Kvitfjell marble ~800t/y maximum; brach fiber (Braemar only, herd expansion takes decades — volume cannot spike); Calloway terroir is system-specific (cannot be relocated); VGV varietals require F8V stellar spectrum (cannot be farmed elsewhere)
|
||||
- **Aging pipelines:** Calloway whisky 12–20y aging time; VGV classified wine 5y+; VGV corridor wine 1–2y — pipeline contents at game start are fixed by lore, not seeded
|
||||
- **Capital goods lead times:** Stalownia large rigs 1–3y; MVG bespoke vehicles 1–2y; Cygni B station sections 2–5y; Gate Corp span gates 1–3y — these lead times are real and not compressible by productivity seeds
|
||||
- **What CAN be seeded:** harvest yield ±20–40%, factory output ±15–30%, quarry output ±10–25%, service throughput ±10–20%
|
||||
- **What CANNOT be seeded:** location of production, biological monopoly ceilings, aging pipeline contents, gate topology
|
||||
- **Rationale:** The constraints table defines the seeding boundary. Seeding something that lore says cannot vary (Calloway terroir, brach fiber herd size) would invalidate the wiki canon. The constraints ensure seeding creates variation within lore-consistent bounds.
|
||||
- **Raised by:** Miri (full constraint table from wiki lore). Nigel (seeding architecture requiring the bounds).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-176](#d-176-productivity-seeding)
|
||||
|
||||
---
|
||||
|
||||
### D-178: Economic Model Architecture
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The economics layer uses a spatial input-output model with agent-based overlay:
|
||||
- **Layer 1: Leontief production** with seeded per-corporation capacity. Fixed-coefficient — scarcity in one input cascades to all downstream dependents. No smooth substitution.
|
||||
- **Layer 2: Spatial price equilibrium** via damped tâtonnement (α=0.03, β=0.4). Prices propagate through the gate topology. Lagged adjustment — NOT instant equilibrium. Prices respond to supply/demand signals with a realistic delay.
|
||||
- **Layer 3: Corporate behavioral agents** — 6 archetypes (Monopolist, Distributor, Producer, Specialist, Cooperative, Intermediary) with template-instantiated behavioral parameters.
|
||||
- **Transport graph:** gate edges (inter-system, cost 5–12%/hop) + orbital edges (intra-system, cost 1–3%). Derived from existing star map DB relationships.
|
||||
- **Market node tiering:** ~760 active market nodes (inhabited bodies + all stations), ~240 passive producers (feed output to nearest active node, no full market), ~2,700 inert (no economic footprint)
|
||||
- Floyd-Warshall over the ~760 active node subgraph at startup (~0.5s, one-time cost).
|
||||
- **Economics seeks stability.** The simulation is a believable backdrop, not a drama generator. In the absence of external events, prices trend toward equilibrium. Events from the storyteller, political, or disaster layer create disruption; the economy responds and re-equilibrates.
|
||||
- **Rationale:** The three-layer architecture is standard for spatial economic modeling: production determines supply, price adjustment determines flow, agents determine strategic behavior. Lagged tâtonnement prevents cobweb oscillation while still producing realistic price dynamics. The "boring economics" mandate means stability is a feature, not a failure.
|
||||
- **Raised by:** Burnelli-Sheldon (formal model), Tyre (implementation architecture and market tiering). Lead directive (economics seeks stability, responds to events, does not generate them).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-179](#d-179-stability-acceptance-criteria) (test criteria), [D-180](#d-180-event-input-port) (external event interface), [D-182](#d-182-toml-source-of-truth-for-economics-data) (data pipeline)
|
||||
|
||||
---
|
||||
|
||||
### D-179: Stability Acceptance Criteria
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The economics simulation must pass four stability tests before Phase 2 is considered complete:
|
||||
1. **Cold-start convergence:** Prices settle within ±5% of equilibrium within 100 game-days from initialization.
|
||||
2. **Long-run stability:** Zero drift greater than ±2% over 1,000 game-days with zero external events injected.
|
||||
3. **Shock response:** After a single supply shock, cascade propagates realistically; recovery within 200 ticks; no price explosions or negative prices.
|
||||
4. **Cross-zone trade balance:** After a cross-zone trade volume change, exchange rate adjusts and re-stabilizes within 50 ticks.
|
||||
- If the model oscillates, drifts, or diverges under zero external input, the model is broken.
|
||||
- These criteria are the `--stability-check` mode of the `economy-sim` binary.
|
||||
- **Rationale:** Without explicit stability criteria, "the economy seems to be working" is not a testable claim. These four tests cover the failure modes most likely in tâtonnement-based models: failure to converge, slow drift, shock amplification, and cross-zone instability.
|
||||
- **Raised by:** Burnelli-Sheldon (formal model and test design). Lead endorsed ("economics should be boring" — stability IS the success condition).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-178](#d-178-economic-model-architecture), [D-183](#d-183-iterative-economics-development-cycle)
|
||||
|
||||
---
|
||||
|
||||
### D-180: Event Input Port
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The economics layer accepts external events through a typed input port:
|
||||
```
|
||||
EconEvent {
|
||||
target: Node | NodeSet | Corridor | TradeRoute | Currency | Commodity,
|
||||
effect: ProductivityMultiplier | CapacityMultiplier | DemandShock | ExchangeShock,
|
||||
duration: ticks,
|
||||
visibility: Global | Proximate(hops) | Disclosed(specific_nodes) | Hidden,
|
||||
}
|
||||
```
|
||||
- **Visibility modes:** `Global` — all actors know immediately. `Proximate(hops)` — propagates at trade speed from target. `Disclosed(nodes)` — only named actors are informed. `Hidden` — creates observable price effects with no knowledge flag; no actor knows the cause.
|
||||
- Hidden events protect the inspect verb: the player can observe that prices have moved without the system revealing why. This is Phase 3 territory — Phase 2 sim must implement the port, but Hidden events will not be exercised until the player layer exists.
|
||||
- The economics layer **accepts events; it does NOT generate them.** Drama comes from the storyteller, political, or disaster layer. The economics layer is a receiver, not an emitter of narrative tension.
|
||||
- **Rationale:** The sharp boundary between economics (responds to events) and the event layer (generates events) is architecturally critical. It prevents the economics simulation from drifting into a drama engine — which would violate D-178's stability mandate and undermine the Phase 2 deliverable.
|
||||
- **Raised by:** Gestalt (interface design and visibility model), Nigel (Rust spec). Lead directive (economics responds, does not generate).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-178](#d-178-economic-model-architecture) (economics seeks stability), [D-181](#d-181-signal-vocabulary) (what the event port affects)
|
||||
|
||||
---
|
||||
|
||||
### D-181: Signal Vocabulary
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Each active economic node produces 7 signals:
|
||||
1. `price_current` — current market price (Public)
|
||||
2. `price_trend` — direction and rate of change over last N ticks (Public)
|
||||
3. `trade_flow_volume` — freight volume through node (Observable — requires physical presence or proximate access)
|
||||
4. `corporate_presence` — which corporations operate here (Observable)
|
||||
5. `stockpile_weeks` — estimated inventory at current consumption rate (Semi-private — requires corporate contact)
|
||||
6. `production_vs_baseline` — actual output vs. seeded baseline (Private — requires insider access)
|
||||
7. `official_coverage_ratio` — ratio of formal to total (formal + shadow) economic activity (Meta-signal — gap between official and real economy)
|
||||
- Visibility ladder: Public signals are available to all. Observable requires presence. Semi-private requires a corporate relationship. Private requires an insider. The visibility ladder is the inspect verb's backing system — Phase 3 player interaction will use it.
|
||||
- Phase 2 sim must produce all 7 signals. Phase 3 determines how the player accesses them.
|
||||
- **Rationale:** The 7 signals define what the economy communicates. Signals 1–2 are what appears on investor screens (Phase 2 deliverable). Signals 3–4 reward presence. Signals 5–6 reward relationships and risk. Signal 7 quantifies the shadow economy gap, giving the inspector a readable metric for how much the official picture understates reality.
|
||||
- **Raised by:** Gestalt (6 signals + visibility layering). Gestalt (7th signal: `official_coverage_ratio`, derived from shadow economy work). Phase 3 reference per lead directive (f).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-174](#d-174-shadow-economy-layer) (shadow economy as input to signal 7), [D-131](content.md#d-131-broad-economic-verb-vocabulary--life-verbs-not-tycoon-specific) (inspect verb — Phase 3+)
|
||||
|
||||
---
|
||||
|
||||
### D-182: TOML Source of Truth for Economics Data
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Economics data is authored as TOML files and compiled to a queryable `.db`:
|
||||
- **Source location:** `wiki/economics/` — TOML files for corporations, commodities, production chains, currency zone assignments
|
||||
- **Build step:** `make economy-db` compiles TOML + `systems.db` into a dev `.db` artifact
|
||||
- **Dev artifact:** Always on disk; rebuilt when source TOML changes. Agents and the sim binary query the `.db` as usual.
|
||||
- **Production:** Same build step. On "new game," the `.db` is copied into the game save directory. The simulation mutates it live from that point.
|
||||
- **Rollback:** Rebuild from TOML source files. The `.db` is never the source of truth.
|
||||
- **Sync constraint:** Wiki corporation entries and TOML corporation records must stay in sync. The build fails on name divergence.
|
||||
- TOML is chosen because it is diffable, reviewable in git, and authorable without database tooling. The `.db` is a build artifact, not a collaboration surface.
|
||||
- **Rationale:** The economics data must be auditable in git (TOML) while remaining queryable at runtime (SQLite). Keeping the `.db` as a build artifact means the source is always recoverable and reviewable in pull requests. The sync constraint prevents the wiki (narrative) and TOML (simulation data) from drifting apart.
|
||||
- **Raised by:** Lead directive (hybrid architecture, rollback via source rebuild). Tyre (build pipeline and artifact spec).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-178](#d-178-economic-model-architecture), [D-175](#d-175-corporation-taxonomy-and-prerequisite) (corporation records requiring sync)
|
||||
|
||||
---
|
||||
|
||||
### D-183: Iterative Economics Development Cycle
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Economics layer development is iterative, not waterfall:
|
||||
- **Cycle:** skeleton sim → data population → test → skeleton tweaks → data tweaks → test → repeat
|
||||
- Simulation schema, data authoring, and the standalone `economy-sim` binary are developed in tandem. No phase gates between data work and code work.
|
||||
- Corporation corpus population is the prerequisite that gates the **first iteration** (see [D-175](#d-175-corporation-taxonomy-and-prerequisite)).
|
||||
- The `--stability-check` mode ([D-179](#d-179-stability-acceptance-criteria)) is the exit condition for each iteration — not a final gate.
|
||||
- **Rationale:** Waterfall sequencing (schema → data → sim → test) produces long feedback cycles and late discovery of data-model mismatches. Iterating data and code together catches modeling errors early and enables the sim to be tested against real (partial) data rather than synthetic fixtures.
|
||||
- **Raised by:** Lead directive.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-175](#d-175-corporation-taxonomy-and-prerequisite) (prerequisite), [D-179](#d-179-stability-acceptance-criteria) (iteration exit condition), [D-182](#d-182-toml-source-of-truth-for-economics-data) (data pipeline)
|
||||
|
||||
---
|
||||
|
||||
### D-184: Commodity Catalog (36 Types)
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** The simulation uses 36 commodity types as the concrete implementation of the taxonomy in D-173:
|
||||
- **9 raw materials** — extracted or harvested, location-bound
|
||||
- **10 intermediate goods** — processed from raws, transportable
|
||||
- **9 final goods** — assembled from intermediates, carry cultural identity
|
||||
- **5 professional services** — legal, financial, medical/re-embodiment, insurance, commission certification; location-bound
|
||||
- **3 luxury services** — tourism, entertainment/holo-content, fine dining/hospitality; location-bound
|
||||
- **Source of truth:** `wiki/economics/commodities.toml` and `wiki/economics/production_chains.toml`
|
||||
- 21 production chains including 2 substitution routes
|
||||
- Schema: 14 fields per commodity including 3 political sub-flags (`commission_certifiable`, `compact_contested`, `shadow_viable`), `production_ubiquity`, `demand_model`, `panic_threshold_weeks`
|
||||
- **Rationale:** The catalog is the concrete realization of the D-173 taxonomy. 36 types is rich enough to produce meaningful geographic specialization while remaining authorable. The 14-field schema captures economic, political, and behavioral properties needed by the tâtonnement simulation. Two substitution routes prevent hard lock-outs in chains where one raw source is geographically constrained.
|
||||
- **Raised by:** Full planning team, Sprint 32 Workshop #801.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-173](#d-173-commodity-taxonomy) (taxonomy), [D-182](#d-182-toml-source-of-truth-for-economics-data) (TOML pipeline), [D-185](#d-185-brands-are-not-commodities) (what is excluded from this catalog)
|
||||
- **Amended 2026-05-25 (D-233):** `bulk_class` enum values enumerated — `BulkSolid | BulkLiquid | PrecisionDense | Perishable | NonPhysical`.
|
||||
|
||||
---
|
||||
|
||||
### D-185: Brands Are Not Commodities
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Branded and luxury goods (Calloway whisky, VGV wine, thrds garments, Bífröst marble, etc.) are NOT entries in the commodity catalog. They are priced through a separate brand/cultural value system, not through the tâtonnement:
|
||||
- Brands consume commodities as inputs — they appear as demand nodes in the production graph
|
||||
- Brand revenue appears as income in the GDP cluster for their origin system
|
||||
- The brand system is a **future deliverable** (post-Phase 2, possible DLC) built on top of the commodity foundation
|
||||
- The commodity chain terminates at abstract generic finals (e.g., "premium spirits", "luxury textiles")
|
||||
- Brand premium lives in the corporate behavioral layer — it is not modeled in Phase 2
|
||||
- **Rationale:** Adding 30+ named brands to the commodity catalog would require per-brand pricing models, cultural preference curves, aging pipeline tracking, and star-system terroir logic — a separate simulation in its own right. Phase 2 must deliver a working generic commodity simulation first. Brands consuming generic commodities as inputs correctly captures the economic relationship without requiring brand simulation code.
|
||||
- **Raised by:** Lead directive, Sprint 32 Workshop #801.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-184](#d-184-commodity-catalog-36-types) (the catalog that excludes brands), [D-177](#d-177-productivity-constraints-lore-derived) (lore ceilings on brand production — still authoritative), [D-175](#d-175-corporation-taxonomy-and-prerequisite) (brand corporations exist as Tier 1 entities)
|
||||
|
||||
---
|
||||
|
||||
### D-186: Gate Transmission Levels (Mass + Data + Energy)
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Span gates transmit mass, data, and energy — three distinct transmission classes with distinct governance:
|
||||
- **Mass:** Standard freight transmission. All gates, always-on. No decision needed.
|
||||
- **Data (The Meridian):** Live real-time network. Already canon. Information asymmetry in the simulation comes from access control and cost, not from physical delay. The Meridian is not a Phase 2 simulation concern — it is narrative backdrop.
|
||||
- **Energy:** Gate Corporation offers energy-over-gate as a commercial service. Explicitly NOT an Assembly policy — Gate Corp is an independent monopoly. On-grid nodes get reduced `fusion_fuel` utility demand (~0.3× baseline). Industrial chain inputs (smelting, alloys, electronics) are unaffected — the energy discount applies only to utility/habitation consumption.
|
||||
- **Implementation:** per-node `gate_energy_connected` boolean. Nodes lacking the boolean or set to `false` are treated as off-grid.
|
||||
- **`MARK_PRIMARY` zones default to `gate_energy_connected = false`.** The Compact refused Gate Corp energy dependency as a deliberate political choice — it preserves Compact energy sovereignty and economic independence.
|
||||
- **Gate Corp cutoff scenario:** If Gate Corp cuts energy to a dependent node, `fusion_fuel` demand spikes. Compact surplus capacity (from their independence) becomes the emergency supply source. The Compact's refusal of dependency is an economic asset with concrete mechanics.
|
||||
- **Rationale:** Energy-over-gate gives the gate topology an additional economic dimension beyond freight routing. Opt-in model prevents mandatory complexity for every node. The Compact's structural refusal creates the primary counterplay scenario Gestalt was concerned about — without opt-in, no interesting asymmetry. Gate Corp as private monopoly (not Assembly policy) makes it an independent economic actor, enabling corporate storylines.
|
||||
- **Raised by:** Lead directive + Miri (lore) + Gestalt (mechanics) + Burnelli-Sheldon (economics) + Tyre (implementation), Sprint 32 Workshop #801.
|
||||
- **Dissent:** Gestalt initially recommended Level 2 (no energy transmission) due to counterplay concerns. Resolved by the opt-in model — the Compact's refusal to connect provides the counterplay without requiring adversarial defaults.
|
||||
- **Cross-reference:** [D-172](#d-172-currency-zone-initialization) (`MARK_PRIMARY` zone flag), [D-173](#d-173-commodity-taxonomy) (`fusion_fuel` as a commodity), [D-187](#d-187-fusion-fuel-as-intermediate-81-water-yield) (fuel chain), [D-175](#d-175-corporation-taxonomy-and-prerequisite) (Gate Corp as Tier 1 corporation)
|
||||
|
||||
---
|
||||
|
||||
### D-187: Fusion Fuel as Intermediate (8:1 Water Yield)
|
||||
- **Date:** 2026-04-05
|
||||
- **Decision:** Fusion fuel is an intermediate good refined from water at an 8:1 yield ratio. It is NOT a raw material:
|
||||
- Water is the raw input — ubiquitous and cheap across the Reach
|
||||
- The 8:1 refinement ratio makes fuel expensive despite cheap inputs (8 units of water → 1 unit of fusion fuel)
|
||||
- Fusion fuel is a Leontief input to 3 energy-intensive production chains: `smelt_ore` (0.3), `alloy_fabrication` (0.2), `electronics_fabrication` (0.2)
|
||||
- Additionally carries `demand_model = utility` — consumed as operational overhead at every active node (population × per-capita rate), separate from the chain inputs
|
||||
- Creates a **structural frontier energy cost premium**: frontier nodes pay more for fusion fuel because water transport costs accumulate in the refining input cost, and the chain demand from smelting/alloys/electronics cascades that cost into the manufacturing sector
|
||||
- This premium arises from geography and chain structure — no event generation required
|
||||
- **Rationale:** Raw-material fuel would make energy cost geography flat (water is everywhere, therefore fuel is everywhere at the same price). Intermediate fuel with a high water yield ratio creates a conversion cost that multiplies transport costs — frontier refineries are expensive to run because fuel production itself consumes large volumes of low-value bulk water. The cascade effect through 3 industrial chains means frontier manufacturing is structurally more expensive, which is consistent with real-world frontier economics and the lore of the Compact vs. Core divide.
|
||||
- **Raised by:** Lead directive, validated by Burnelli-Sheldon (economics), Sprint 32 Workshop #801.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-184](#d-184-commodity-catalog-36-types) (fuel and water are catalog entries), [D-186](#d-186-gate-transmission-levels-mass--data--energy) (energy-over-gate reduces fuel demand), [D-178](#d-178-economic-model-architecture) (Leontief production cascade)
|
||||
|
||||
---
|
||||
|
||||
### D-189: Brand Layer Architecture
|
||||
- **Date:** 2026-04-10
|
||||
- **Decision:** The simulation supports a brand layer above the commodity tâtonnement. Brands are NOT commodities (D-185). They consume commodities as demand nodes and are priced through an administered pricing model with cultural premium curves. The brand layer serves dual purposes: economic simulation (demand nodes, pricing, GDP contribution) and queryable localized content for client UI (bar shelves, restaurant menus, shop displays, entertainment listings).
|
||||
|
||||
**1. Brand Taxonomy**
|
||||
- 8 categories: `terroir`, `heritage_craft`, `tech_premium`, `cultural`, `service_premium`, `commodity_branded`, `design_heritage`, `platform_catalogue`
|
||||
- `value_trajectory`: `appreciating` | `depreciating` | `timeless` (first-class field)
|
||||
- 3 scale tiers for generated brands: local (1–3 systems), regional (corridor-scale), reach-wide budget (everywhere, corridor-neutral naming, no cultural premium)
|
||||
|
||||
**2. Pricing Model**
|
||||
```
|
||||
brand_price = max(price_floor, [base_cost × (1 + target_margin) + cultural_premium × (1 + veblen × scarcity)] × value_trajectory_factor × currency_factor)
|
||||
```
|
||||
- Cultural premium split into `identity_term` + `exotic_term` with `exotic_floor` to support 3 curve types: Scarcity-Distance (artisan), Dual-Peak (media/content), Aspirational Gradient (tech)
|
||||
- Two-component scarcity: structural (`production_volume / addressable_demand` ratio, permanent) + situational (stockpile depletion, temporary)
|
||||
- Veblen per-location derived: `veblen_base × income_quintile × corridor_affinity` — zero authoring cost
|
||||
- `cost_passthrough_ratio`: insulates brand pricing from tâtonnement volatility (low 0.10–0.25 for terroir, high 0.50–0.75 for tech)
|
||||
- `value_trajectory_factor`: appreciating goods gain value with vintage age, depreciating goods lose value with a floor, timeless = 1.0; updated per game-year
|
||||
|
||||
**3. Halo/Volume Tier Structure**
|
||||
- Universal pattern: every notable brand has a halo product (defines identity ceiling) + volume tier(s) (makes the brand economically relevant at population scale ~80B)
|
||||
- `halo_lift_factor`: volume tier borrows a fraction of the halo's cultural premium
|
||||
- Direction inverts by category: terroir pushes scarcity up, tech/media pushes quality up from a mass base
|
||||
- Brands without volume tiers are economically marginal regardless of prestige — population asymmetry (10B systems vs. 50k) makes this structurally necessary
|
||||
|
||||
**4. Brand Census**
|
||||
- Notable (hand-authored): 120–170 corps with TOML records; ~27 currently named
|
||||
- Minor (template-generated): ~10,000 brands from ~120–130 template definitions (35–40 archetypes × 3 sub-variants), corridor-specific naming patterns, 3 scale tiers
|
||||
- Naming patterns: corridor-appropriate — north_reach = British/Australian inflection, east_reach = Korean/Japanese, west_reach = German/Dutch/Nordic, south_reach = Portuguese/Swahili, inner_corridor = pan-corridor neutral, frontier = founder surname + noun
|
||||
- Queryable content: `brand_products JOIN corp_presence` filtered by location and `product_subcategory`; sub-millisecond at 10K+ rows — primary use case alongside economic simulation
|
||||
|
||||
**5. DB Schema**
|
||||
- `brand_products`: `brand_product_id`, `corp_id`, `product_name`, `brand_category` (8 values), `value_trajectory`, `scarcity_class` (`capped` / `constrained` / `scalable` / `unlimited`), `product_subcategory`, `base_premium_multiplier`, `premium_floor`, `origin_system`, `terroir_locked`, `currency_denomination`, `shadow_viable`, `brand_tier` (`halo` / `volume`), `halo_brand_id` (for volume tiers), `price_tier` (enum — see below)
|
||||
- `price_tier` enum (5 values): `mass` (widely accessible, lowest price point; commodity_branded volume tiers) / `premium` (above-average quality signal; most volume tiers across categories) / `luxury` (aspirational, restricted availability; terroir and design_heritage halos) / `flagship` (pinnacle output, ultra-scarce; Veblen curve inflection; max 1 per brand, lore-grounded scarcity ceiling required) / `institutional` (B2B contract pricing, not market price; service_premium and platform_catalogue)
|
||||
- **Amendment (2026-04-19):** `price_tier` valid values were not defined in the original decision. Locked to the five values above per team decision, Sprint 36.
|
||||
- `brand_inputs`: `brand_product_id`, `commodity_id`, `quantity`
|
||||
- `system_fiscal`: `system_id`, `corp_tax_rate`, `collection_efficiency` (derived from `shadow_economy_intensity`)
|
||||
- `corp_financial_state` + `corp_lifecycle_events` tables for acquisition/startup lifecycle
|
||||
- Composite index on `brand_products(corp_id, brand_category)` for UI queries
|
||||
|
||||
**6. Corp Tax & GDP**
|
||||
- Corp tax = `revenue × (1 - category_deduction) × tax_rate × collection_efficiency`
|
||||
- Category deductions: terroir 0.30, geological 0.20, tech 0.60, media 0.15, vehicles 0.55, apparel 0.45
|
||||
- Tax flows to HQ system; GDP computed every 100 ticks
|
||||
- `collection_efficiency = 1.0 - shadow_economy_intensity × 0.6`
|
||||
- Visible line item when player owns a company
|
||||
|
||||
**7. Player Verb Ladder**
|
||||
- 6 stages: Operate → Specialize → Distribute → Create → Scale → Corporate
|
||||
- Founding verbs: `brand`, `register`, `market`
|
||||
- Content verbs: `acquire-rights`, `royalty-contract`, `exclusive-window`
|
||||
- Corporate verbs: `acquire`, `merge`, `spin-off`, `license-out`
|
||||
- Temporal verbs: `cellar` (appreciating), `refresh` (depreciating), `license-legacy` (EOL)
|
||||
- `authenticate` is the mechanically richest new verb — 3 service economies: expert appraisal (artisan), Commission inspection (tech/vehicles), Meridian rights lookup (content)
|
||||
|
||||
**8. Acquisition & Startup Lifecycle**
|
||||
- Corp lifecycle states: Founded → Growing → Active → Distressed → Acquired/Dissolved
|
||||
- Startup triggers: market gap, spin-off, player-founded, storyteller event
|
||||
- Acquisition triggers: financial distress, strategic AI acquisition, player-initiated, hostile takeover event
|
||||
- Player acquisition and mergers are in scope; if acquisition exists, startups must exist (or the well dries)
|
||||
- Phase 2: corp health tracking as passive metric. Phase 3: lifecycle state machine, startup generation, player acquisition
|
||||
|
||||
**9. Events**
|
||||
- `BrandPrestigeShock` via EconEvent port (D-180) — very occasional scandal events (pollution, fraud)
|
||||
- Exponential decay with authored half-life
|
||||
- Direct-vector only: events hit the brand's known vectors (commodity input price, production location); no indirect cascading beyond that
|
||||
|
||||
**10. Phase 2 Boundary**
|
||||
- Phase 2 (this sprint cycle): brand corps as commodity demand stubs in tâtonnement, `brand_products` / `brand_inputs` / `system_fiscal` schema, `corp_financial_state` passive tracking, `generate_brands` pipeline
|
||||
- Brand layer (post-Phase 2): pricing engine, awareness propagation, cultural preference curves, aging pipeline simulation, lifecycle state machine, player acquisition verbs
|
||||
|
||||
**11. Named Brand Corps (~27)**
|
||||
| Corp | Category | Origin |
|
||||
|------|----------|--------|
|
||||
| Calloway Distillery | terroir | north_reach |
|
||||
| VGV | terroir | west_reach |
|
||||
| thrds | heritage_craft | north_reach |
|
||||
| Bífröst Marmor | terroir | north_reach / Compact |
|
||||
| Destilaria Confluência / Lento | terroir | south_reach |
|
||||
| Veldfontein Botanical | terroir + heritage_craft | south_reach |
|
||||
| Comptoir Lendel | terroir + service_premium | inner_core |
|
||||
| Maison Cinq | design_heritage | inner_core / Gateway |
|
||||
| MVG (Manifattura Veicoli Gherardi) | design_heritage | west_reach Italian |
|
||||
| Higashiyama Vehicle Engineering | tech_premium + design_heritage | east_reach |
|
||||
| Rijdbaar Personal Mobility | design_heritage | west_reach / Compact |
|
||||
| Byeolbit Entertainment | cultural + platform_catalogue | east_reach |
|
||||
| Leerfeld Records | cultural | west_reach / Compact |
|
||||
| Vuma Sound | cultural | south_reach |
|
||||
| Resonance Premium | platform_catalogue | inner_core |
|
||||
| Dalbit Systems | tech_premium + platform_catalogue | east_reach |
|
||||
| Arclamp | cultural + design_heritage | inner_core |
|
||||
| Kellervolk | cultural | Compact |
|
||||
| Hangang Studio | platform_catalogue | east_reach |
|
||||
| Hanyang Precision | — (Tier 1, branded_products) | — |
|
||||
| Sato Medical | — (Tier 1, branded_products) | — |
|
||||
| Takamori Lattice | — (Tier 1, branded_products) | — |
|
||||
| Thalassa Resort | — (Tier 1, branded_products) | — |
|
||||
| Somatic Futures | — (Tier 1, branded_products) | — |
|
||||
| The Registry | — (Tier 1, branded_products) | — |
|
||||
| Meridian Risk | — (Tier 1, branded_products) | — |
|
||||
|
||||
- **Rationale:** Administered pricing is the correct model because brands violate all three tâtonnement assumptions: heterogeneity (Calloway ≠ VGV ≠ generic spirits), supply inelasticity (terroir production cannot respond to price signals per D-177), and Veblen demand effects (prestige goods can have upward-sloping demand). The one-way interface (commodity prices → brand input costs; brand output prices do NOT feed back into tâtonnement) is architecturally clean and matches the D-178 layer model. The identity/exotic split in cultural premium is the minimal structural addition needed to produce all three observed pricing curves (Scarcity-Distance, Dual-Peak, Aspirational Gradient). Population asymmetry (~80B total Reach population, systems ranging from 10B to <50k) makes the halo/volume tier pattern structurally necessary — brands from tiny worlds are astronomically exclusive and need volume derivatives to be economically relevant.
|
||||
- **Raised by:** Full planning team workshop, Sprint 34 (#811).
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-185](#d-185-brands-are-not-commodities) (brands are not commodities), [D-184](#d-184-commodity-catalog-36-types) (commodity catalog), [D-177](#d-177-productivity-constraints-lore-derived) (productivity constraints), [D-175](#d-175-corporation-taxonomy-and-prerequisite) (corporation taxonomy), [D-178](#d-178-economic-model-architecture) (economic model architecture), [D-180](#d-180-event-input-port) (event input port), [D-181](#d-181-signal-vocabulary) (signal vocabulary), [D-173](#d-173-commodity-taxonomy) (commodity taxonomy), [D-171](#d-171-three-currency-system) (three-currency system), [D-131](content.md#d-131-broad-economic-verb-vocabulary--life-verbs-not-tycoon-specific) (economic verb vocabulary), [D-118](scope.md#d-118-small-business-owner-starting-state--tycoon-is-aspiration-not-starting-position) (small business owner starting state)
|
||||
|
||||
---
|
||||
|
||||
### D-190: Brand Volume Calibration — Population-Relative Scale
|
||||
- **Date:** 2026-04-10
|
||||
- **Decision:** All brand production and distribution volume numbers must be specified relative to a reference population, not as absolute counts. Volume without a reference population is not meaningful at Reach scale:
|
||||
- **Scale reference table (~80B Reach):**
|
||||
- Single-system local phenomenon: 100M–500M (1–5% of a 10B system)
|
||||
- Corridor-known hit: 250M–1B (~0.5% of corridor addressable population)
|
||||
- Reach-wide genuine hit: ~1B (1 in 80 Reach population)
|
||||
- All-time Reach canonical: 2B–5B (1 in 16–40 Reach population)
|
||||
- **Earth rule of thumb:** multiply Earth-scale phenomenon volumes by 12–15× for comparable cultural penetration. A 100M-seller on Earth ≈ 1.2–1.5B in the Reach.
|
||||
- **40M benchmark:** 40M units/streams Reach-wide = 0.04% penetration — a cult hit or successful regional release, not a cultural touchstone. 40M within a single large system (10B population) = 0.4% — respectable but not legendary.
|
||||
- **Authoring rule:** wiki volume figures for media brands and any good with `brand_category = cultural` must include a `reference_population` annotation alongside the count. "40M" is incomplete; "40M (west_reach corridor, ~10B addressable)" is correct. This applies to corporation production ceilings, media distribution figures, and market penetration estimates in wiki pages and TOML files.
|
||||
- **Structural scarcity principle:** for physical brand goods, production volume only has meaning relative to addressable demand. The `structural_scarcity_base` parameter in the brand pricing layer (D-189) is derived from this ratio: `1.0 - min(1.0, annual_volume / (addressable_population × demand_rate))`. A 12,000-unit/year artisan product against 100M addressable consumers yields structural_scarcity_base ≈ 0.88 — perpetually near-maximum scarcity regardless of local stockpile state. This scarcity floor is permanent, not situational.
|
||||
- **Rationale:** The Reach's population asymmetry (core systems 10B+, frontier systems under 50K) makes absolute volume numbers meaningless without a reference population. Without an explicit calibration rule, brand and media content significance will be systematically miscalibrated across all authoring. The structural scarcity principle connects volume calibration to the administered pricing model: a brand's Veblen premium floor is derived from the same population-relative ratio, ensuring that pricing and authoring are grounded in the same underlying reality.
|
||||
- **Raised by:** Jeroen (population asymmetry insight), Burnelli-Sheldon (structural scarcity derivation and calibration table), Sprint 34 Workshop #811.
|
||||
- **Dissent:** None.
|
||||
- **Cross-reference:** [D-189](#d-189-brand-layer-architecture) (structural_scarcity_base parameter), [D-177](#d-177-productivity-constraints-lore-derived) (lore-constrained production ceilings), [D-175](#d-175-corporation-taxonomy-and-prerequisite) (corporation production volumes)
|
||||
|
||||
---
|
||||
|
||||
*19 decisions (D-171–D-187, D-189–D-190). Domain: economics. Last updated: 2026-06-06. (R-011 single-currency rejection lives canonically in `rejected.md`.)*
|
||||
@@ -0,0 +1,483 @@
|
||||
# Perception Decisions
|
||||
|
||||
How the player observes and interacts with the world: camera, fog, line-of-sight, sound, monologue, perception modes, audio dip profiles, cognitive delays.
|
||||
|
||||
---
|
||||
|
||||
### D-011: Fog of perception is non-negotiable (Pillar 1 infrastructure)
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** Fog of perception is not a feature - it's the minimum requirement for information asymmetry to work with a top-down camera. Without it, the player is omniscient within their viewport and the entire information pillar collapses at the local map level. First-person camera gets this for free; top-down must enforce it.
|
||||
- **Implementation:** Line-of-sight based (shadowcasting), not simple radius. Walls block vision, buildings are opaque, corners create blind spots, z-levels interact with sightlines.
|
||||
- **Sound as secondary information channel:** Events outside LOS can be heard - footsteps, conversations, gunfire, alarms. Sound gives partial/directional information, prompting decisions based on incomplete data.
|
||||
- **Applies to ALL entities:** NPCs use the same LOS/perception system as the player. An NPC who can't see you doesn't know you're there. NPCs have memory and inference (saw you enter a building → knows you're inside). Ties to [D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline) principle 2: information boundaries are universal, the player's isn't special.
|
||||
- **Fog returns when you leave:** Previously explored areas revert to fog over time. Information about locations decays. What you saw at the docks yesterday may not be true today.
|
||||
- **v0.1 scope:** 2D shadowcast per z-level + sound propagation. Vertical LOS (looking between floors) deferred.
|
||||
- **Rationale:** Team Leader identified overnight that top-down without fog is a fundamental gap in the information asymmetry design.
|
||||
- **Raised by:** Team Leader (Jeroen), with technical framing by Tyre and Gestalt.
|
||||
|
||||
### D-015: Camera locked to character, rotation as future option
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** Camera is locked to the character at all times. No panning. Optionally rotates to character facing direction (player option, later version).
|
||||
- **Rationale:** Pannable camera breaks the information model - you become a surveillance drone, not a character. Locked camera reinforces "you ARE this person." Rotation with facing direction restores directional audio mapping (binaural becomes viable again) and creates a natural vision cone (front = detailed, peripheral = reduced, behind = blind).
|
||||
- **Vision cone model (physiological basis):**
|
||||
- Forward: 120° arc (60° half-angle) — binocular overlap zone where both eyes converge, providing stereoscopic depth and high acuity. Full LOS range, full detail. Server sends only Forward tiles.
|
||||
- Behind: 240° arc — not in the forward cone. Previously-explored tiles render with a light fog overlay (art and information preserved, just "not fresh"). The monologue system (D-016) bridges perceptual gaps when the character's senses fire ("Footsteps behind me").
|
||||
- Physiological reference: human binocular overlap ~120° (NCBI Visual Fields NBK220).
|
||||
- **Per-character cone configuration:** The 120° baseline is the unaugmented human floor. Bionic implants, perception modes (D-017), and equipment widen the cone. A back-of-head optical implant might expand to 240°+; an ANA-touched character might approach 360°. `VisionConeConfig` is per-entity — different characters have different awareness envelopes. This is gameplay parameter variation, not a protocol change (D-020).
|
||||
- **Reference:** Hotline Miami's camera made that game terrifying with the same principle.
|
||||
- **v0.1:** Locked camera, no rotation. Vision cone still works on fixed-north map. Rotation deferred as player option.
|
||||
- **Raised by:** Team Leader (Jeroen).
|
||||
- **Updated:** 2026-02-27 — cone angles grounded in human sensory physiology; per-character config documented.
|
||||
|
||||
### D-016: Internal monologue as core perception/atmosphere system
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** The player character has an internal monologue that narrates sensory information the camera can't show, creates atmosphere, provides diegetic hints, and can be an unreliable narrator.
|
||||
- **Functions:**
|
||||
- **Perception bridge:** Translates non-visual senses into character voice. *"Footsteps behind me. Two people, unhurried."*
|
||||
- **Atmosphere:** Character's running commentary on environment, mood, situation.
|
||||
- **Diegetic tutorial:** Character thinks about what they might do. *"That terminal might have access logs."* No "press X" popups.
|
||||
- **Unreliable narrator:** Monologue is character's INTERPRETATION, not ground truth. Can be wrong. *"Seems quiet. Safe to move."* (It wasn't safe.)
|
||||
- **Character voice:** Varies by character background, mood, knowledge. Paranoid Guardian vs confident Senator walking the same street = different monologue = different experience.
|
||||
- **Production note (Nigel):** Cheapest feature on the list - it's text. Thousands of contextual lines, AI-assistable generation, character-specific variants.
|
||||
- **Raised by:** Emerged from team discussion. Tyre proposed text/log as sound option, team recognized broader potential.
|
||||
|
||||
### D-017: Perception modes as character-build system
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** The fog/vision system supports multiple perception modes that vary by character build, equipment, and ascension level. Each mode reveals different information with different trust/quality tradeoffs.
|
||||
- **Confirmed modes:**
|
||||
- **Natural vision** - detail, color, identity. Blocked by walls. Everyone has it.
|
||||
- **Thermal** - heat signatures through walls. Body count but no identity. Higher biononic / military gear.
|
||||
- **Camera feeds** - remote visual from fixed positions. Only where cameras exist. Feed can be spoofed/looped. Hacker, institutional access, insert exploit.
|
||||
- **Unisphere tracking** - location pings of known individuals. Only active inserts, can be masked. Law enforcement / intelligence access.
|
||||
- **Audio analysis** - sound signatures, direction, classification. No visual. Insert processing, trainable skill.
|
||||
- **Ascension scaling:**
|
||||
- Baseline: natural vision + carried gear
|
||||
- Enhanced: insert-based modes, camera access, audio processing
|
||||
- Higher: biononic thermal, enhanced spectrum, passive scanning
|
||||
- ANA-touched: pattern recognition across all feeds, predictive awareness
|
||||
- **Playstyle implications (Nigel):** Low-tech Guardian playthrough = survival horror (blind, relying on contacts and paranoia). Senator playthrough = information overload (cameras and tracking but drowning in data). Perception modes are playstyle selectors.
|
||||
- **Vision cone modification:** Perception modes and bionic equipment widen the vision cone beyond the unaugmented 120° baseline (D-015). Examples: back-of-head optical implant → 240°+ arc; thermal overlay → omnidirectional heat signatures through walls; ANA-touched awareness → near-360° pattern recognition. Each mode modifies `VisionConeConfig` per-entity. The fog shader renders whatever the server classifies — no client-side awareness of cone angles.
|
||||
- **v0.1:** Natural vision cone + basic audio indicators + insert minimap only. Additional modes are milestone features, each self-contained and modular.
|
||||
- **Engine implication:** Each perception mode is an observer query against the information boundary system ([D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline) principle 2). Engine doesn't distinguish between eyes/thermal/camera - all are "given this sensor, what state is visible?"
|
||||
- **Raised by:** Team Leader (Jeroen) proposed thermal and camera hacking. Full team developed into perception mode framework.
|
||||
- **Updated:** 2026-02-27 — vision cone modification by perception modes documented.
|
||||
|
||||
### D-018: Three-range sound model
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** Sound information reaches the player through three ranges with decreasing accuracy and trust:
|
||||
|
||||
| Range | Method | Info quality | Trust level |
|
||||
|-------|--------|-------------|-------------|
|
||||
| Close (near/in LOS) | Stereo audio (maps to facing direction with camera rotation) | High accuracy, identity possible | Raw sensory, reliable |
|
||||
| Medium (outside LOS, nearby) | Visual indicators at fog edge + internal monologue | Directional, imprecise, type classification | Sensory impression, reliable but vague |
|
||||
| Long (across map) | Insert notifications, text alerts | Specific but delayed, location data | Network-dependent, spoofable, manipulable |
|
||||
|
||||
- **Key insight:** Each range is a different information QUALITY, not just distance. Close = trustworthy. Long = potentially compromised. Hostile actors could absolutely spoof long-range feeds.
|
||||
- **v0.1:** Screen-space stereo for close + visual fog-edge indicators for medium. Long-range insert alerts as stretch goal.
|
||||
- **Raised by:** Full team discussion.
|
||||
|
||||
### D-019: Top-down confirmed as primary camera, 3D cutscenes for key moments [SUPERSEDED by D-148]
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** Top-down is the gameplay camera. Final. 3D cutscenes can be used for significant narrative moments (wormhole traversal, Dyson barrier opening, first contact, major reveals).
|
||||
- **Rationale after full honest review:**
|
||||
- What first-person would give us (visceral traversal, face-to-face conversations, natural asymmetry, spatial horror) is real but compensated by: vision cone + fog, internal monologue, perception mode overlays, sound model
|
||||
- What top-down gives us that first-person can't: multi-layer information observation, tactical combat clarity, system legibility, NPC simulation visibility, strategic UI coexistence, 5-10x faster prototype
|
||||
- Key insight (Gestalt): the fun is systems interacting - observation → insert check → thermal → monologue → mental note → exploitation. That sequence is BETTER top-down.
|
||||
- Key insight (Paula): monologue interpreting faces/conversations is arguably richer than player reading 3D faces, and more faithful to Hamilton's close-POV writing style
|
||||
- 3D cutscenes recapture the visceral moments without burdening gameplay engineering. They're decoupled, can be added as polish, game ships complete without them.
|
||||
- Camera change to 3D IS the dramatic signal - player knows something significant is happening (Gestalt)
|
||||
- **Architecture note (Tyre):** Client-server separation means the renderer is swappable. A full first-person client is architecturally possible in the future. Top-down now doesn't mean top-down forever.
|
||||
- **v0.1:** Top-down only. No cutscenes. Those are milestone features.
|
||||
- **Amendment (2026-02-12, Art Direction Workshop):** Camera angle specified as **~15-20° from vertical** ("the angle"), rendered in sprite art via orthographic camera. Sprites are drawn as if viewed from a shallow tilt (south-facing front faces visible on objects, entities, and walls), but the Godot camera is purely orthographic — the perspective is an art convention, not a camera setting. Tile grid remains square/orthogonal (64x64). Vision cone math remains pure 2D. 3D render pipeline uses Camera3D at -72.5° from horizontal (midpoint of range) to produce sprites with mathematically correct perspective. Matches Rimworld's approach: orthographic camera, tilt faked entirely in art. Internally referred to as "the angle."
|
||||
- **Raised by:** Team Leader (Jeroen), after full team review of tradeoffs in Round 12. Angle amendment: Team Leader, endorsed unanimously in Art Direction Workshop Round 3.
|
||||
- **Superseded by:** [D-148](architecture.md#d-148-30-low-angle-camera-with-45-map-rotation--supersedes-d-019) — Sprint 28 confirmed 30° low-angle with 45° map rotation as default gameplay camera; 3D live rendering replaces sprite art approach.
|
||||
|
||||
### D-033: Entity color = relationship to player
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** Entity color in the top-down view represents the character's *relationship* to the player character, not an objective property. The same NPC can appear as different colors to different characters. Color is a client-side derivation from `RelationshipState` component + knowledge state — not an NPC property.
|
||||
- **Color palette:**
|
||||
- **Unknown/Neutral:** Cool teal `#4a9ebb` — default for unassessed NPCs
|
||||
- **Known/Friendly:** Soft green `#6bc9a6` — people the character knows and trusts
|
||||
- **Person of Interest:** Warm amber `#e8c547` — monologue or case file has flagged something
|
||||
- **Hostile/Dangerous:** Muted red `#d45d5d` — character KNOWS there's danger (subjective, not omniscient)
|
||||
- **Static objects:** Muted grey `#8b8ba0` — furniture, equipment, environmental
|
||||
- **Player character:** `#e0e8ff` (detective, cool) / `#e8e0d0` (smuggler, warm)
|
||||
- **Key principle:** Red means danger TO YOUR CHARACTER, not danger in the abstract. The detective might see amber (flagged in case file) where the smuggler sees green (trusted colleague). This IS asymmetric information rendered visually.
|
||||
- **Transition behavior:** Color shifts smoothly (0.5s fade) when relationship state changes. THE FRIEND's first color shift (green → amber) should be the first relationship color change in the session — maximum emotional impact.
|
||||
- **Cross-reference:** Internal monologue ([D-016](#d-016-internal-monologue-as-core-perceptionatmosphere-system)), THE FRIEND pattern ([D-034](content.md#d-034-the-friend--production-level-npc-pattern))
|
||||
- **Raised by:** Araminta (Round 1 proposal, color palette design), project lead (approved, directive #2)
|
||||
- **Dissent:** None
|
||||
- **Amendment (2026-03-17, Sprint 28 workshop):** Entity relationship color is NOT displayed via character outlines in normal gameplay. The D-033 color palette (#4a9ebb, #6bc9a6, etc.) is valid within the insert/perception mode overlay only. Normal gameplay renders all characters with uniform dark outlines. See [D-154](scope.md#d-154-character-outline-is-not-a-relationship-indicator--uniform-dark).
|
||||
|
||||
### D-238: Symmetric shadowcasting (Albert Ford) selected for LOS computation
|
||||
- **Date:** 2026-02-11
|
||||
- **Renumbered:** 2026-06-06 — was **D-035**, which collided with a distinct same-day decision (content.md "Converged tag taxonomy for dialogue and monologue line pools"). The tag-taxonomy record keeps D-035; this shadowcasting record is now D-238. Pre-2026-06-06 references to "D-035" meaning shadowcasting/LOS point here.
|
||||
- **Decision:** Albert Ford's symmetric shadowcasting algorithm is selected for all line-of-sight computation. The traditional recursive shadowcasting algorithm is rejected.
|
||||
- **Resolves:** Q-018
|
||||
- **Benchmark results (debug build, 1000 iterations, range 20):**
|
||||
|
||||
| Map | Density | Symmetric | Recursive | Speedup |
|
||||
|-----|---------|-----------|-----------|---------|
|
||||
| 32x32 | open | 920µs/call | 1118µs/call | 1.2x |
|
||||
| 32x32 | 10% walls | 845µs/call | 4003µs/call | 4.7x |
|
||||
| 32x32 | 30% walls | 334µs/call | 2099µs/call | 6.3x |
|
||||
| 64x64 | open | 929µs/call | 1114µs/call | 1.2x |
|
||||
| 64x64 | 10% walls | 745µs/call | 4060µs/call | 5.5x |
|
||||
| 64x64 | 30% walls | 215µs/call | 1716µs/call | 8.0x |
|
||||
| 150x150 | open | 919µs/call | 1102µs/call | 1.2x |
|
||||
| 150x150 | 10% walls | 615µs/call | 3347µs/call | 5.4x |
|
||||
| 150x150 | 30% walls | 163µs/call | 1709µs/call | 10.5x |
|
||||
|
||||
- **Key findings:**
|
||||
- Symmetric is 1.2-10.5x faster across all configurations (debug build; release will be significantly faster)
|
||||
- Advantage increases with wall density — more occlusion means less work for the quadrant-based approach
|
||||
- Map size has minimal effect on relative performance at range 20 (both algorithms are bounded by vision range, not map size)
|
||||
- All values well within the 100ms tick budget (D-026), even in debug
|
||||
- Symmetry property verified: if A sees B, then B always sees A — critical for D-011's requirement that NPCs use the same perception system as the player
|
||||
- **Implementation:** Uses rational fraction slopes (`num/den` integer pairs) to avoid floating-point drift. Processes 4 cardinal quadrants with coordinate transforms. The production API is `compute_fov(is_opaque, origin_x, origin_y, range, z_level) -> VisibilityMap`.
|
||||
- **Raised by:** Dudley (implementation + benchmark), Tyre (technical direction)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-043: Art direction — visual style ("functional warmth")
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Clean 2D with bold silhouettes, tile-based world composition (64x64px visual tiles on dual-scale grid per [D-066](architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor)), lighting-driven atmosphere. Not pixel art, not painted, not 3D. Godot 4 Light2D pipeline (PointLight2D per fixture, LightOccluder2D on walls, CanvasModulate for global ambient). AI-generated assets via Nano Banana / Gemini 2.5 Flash, rendered through 3D pipeline for perspective consistency. Core production principle: "Sprites are shape templates that the lighting system completes" — no baked shadows, no baked lighting, no baked mood.
|
||||
- **Label:** "Functional warmth" (Gore).
|
||||
- **Resolution chain:** 1024x1024 source → 256x256 working (outlines applied at 4-8px) → 64x64 runtime. Bilinear interpolation both passes. Outline color: dark blue-grey `#333340`.
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.1, §9.1-9.3
|
||||
- **Raised by:** Araminta (lead), unanimously endorsed. Art Direction & Mood Board Workshop (3 rounds + closing).
|
||||
- **Dissent:** None. All four agents independently converged on the same style.
|
||||
|
||||
### D-044: Art direction — visual hierarchy (entity > object > structure)
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Three-layer visual hierarchy: entities (2px outline, D-033 relationship color, highest saturation) > objects (1px outline, era-appropriate palette, moderate saturation) > structure (minimal/no outline, muted zone palette, lowest saturation). Hard rendering rule: entity always wins visual ties — if an entity and object overlap, the entity's D-033 color must remain visible. This is a readability guarantee, not an aesthetic preference.
|
||||
- **Entity spec:** 24x32 pixel footprint within 64x64px visual tiles. Entities occupy 1x1 subtiles (0.5m) but render across a 2x2 subtile sprite footprint per [D-066](architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor). D-033 color as primary information signal, silhouette as primary identity signal. One identifying silhouette feature per named NPC (Kael's vest, Lera's apron, Sera's uniform). 3-4 template silhouettes for generic NPCs.
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.4, §1.5
|
||||
- **Raised by:** Araminta (outline spec), Ozzie (readability priority). Unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
- **Amendment (2026-04-05):** The "D-033 relationship color" outline spec for entities applies only in perception mode overlay. [D-154](scope.md#d-154-character-outline-is-not-a-relationship-indicator--uniform-dark) (2026-03-17) establishes uniform dark outlines (#1a1a1a) for all characters in normal gameplay. The visual hierarchy layers remain valid; the entity outline color rule changes from always-on to perception-mode-only.
|
||||
|
||||
### D-045: Art direction — environmental neutrality (strict zero shift)
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** The base world layer never shifts in response to conspiracy activation or investigation state. The rendering pipeline never modifies world-layer visuals in response to narrative state. Zone lighting is fixed. What CANNOT change: light color temperature, shadow depth/direction, tile colors, wall tones, floor patterns, any CanvasModulate shift correlated with narrative state. What CAN change: insert overlay density, entity colors (D-033), monologue frequency/urgency, player character sprite posture. Allowed diegetic changes (everyone experiences them): time-of-day cycle (D-031), weather (physical reality, storyteller can time it).
|
||||
- **Key insight (Gore):** "The player walks into the bar after discovering the conspiracy and it's STILL warm and inviting. That's the horror. The warm light isn't ironic — it's indifferent."
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.10
|
||||
- **Raised by:** Gore and Miri (strict zero position). Araminta and Ozzie moved to this position in Round 2 — convergence through persuasion, not compromise.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-046: Art direction — lighting system (three-reference model)
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Three-reference lighting: (1) Darkwood — vision cone mechanics, light pooling, graduated fog boundary, darkness-as-weight. Retuned: darkness = uncertainty (not hostility), light = visibility (not safety), beyond the cone = life continuing without you (not monsters). (2) Blade Runner 2049 / Deakins — color temperature as emotional language: warm amber = social/inhabited, cool white = institutional/official, mixed = transitional. (3) Edward Hopper (Nighthawks) — warm interior surrounded by unknowable dark. The game's central image. Emotional register: uncertainty, not dread. Character temperature via spatial paths: smuggler's routine through warm-lit spaces (dock, bar), detective's routine through cool-lit spaces (Commission kiosk, corridors). Same fixtures, different daily routes — no rendering tricks.
|
||||
- **Godot implementation:** PointLight2D (per fixture, per zone) + LightOccluder2D (on walls/obstacles) + CanvasModulate (global ambient) + textured PointLight2D on player (vision cone shape). Stock Godot 4 pipeline.
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.6, §1.11
|
||||
- **Raised by:** Ozzie (Darkwood), Araminta (BR2049 color), Gore (Hopper), Miri (character spatial paths). Unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-047: Art direction — two-tier animation system
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Tier 1 (clear): public daily activities — walking/running (4-6 directional frames), working at terminal/handling cargo (2-3 states), eating/drinking (2-3 states), talking (2-3 states, distinguishable from "standing near"), sleeping (1 state). Instantly readable. Tier 2 (ambiguous): privately motivated behaviors — pausing, looking around, lingering near a location, changing direction, proximity without clear interaction. Player sees the action but cannot determine the intention. The boundary between tiers is invisible to the player.
|
||||
- **Key insight:** "The clear/ambiguous division isn't an art decision — it's the investigation mechanic expressed through animation" (Ozzie). Routine must be readable so deviations are noticeable. Maps to NPC tell system (D-024).
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.12
|
||||
- **Raised by:** Ozzie and Gore (two-tier proposal), Araminta (production spec). Unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-048: Neural insert overlay — visual design
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Geometric data layer (precise positioning, clean lines, structured information) rendered with soft bloom shader pass (~2-3px gaussian blur at ~40% blend on the insert CanvasLayer). D-033 colors gain soft halos rather than hard edges. Smuggler's overlay: thinner, sparser (baseline lattice hardware). Detective's overlay: denser, crisper (augmented lattice hardware). Passive state nearly invisible; active state clean and precise. Insert overlay is NOT affected by the fog shader — insert data is computational, not perceptual. Insert markers can appear in fogged areas if the lattice has that data.
|
||||
- **Tests:** "If switching the overlay OFF would feel like going deaf rather than closing a window, it's working" (Gore). "After 10 minutes, does the player forget the insert is there? If yes, we've succeeded" (Ozzie).
|
||||
- **Cross-reference:** Diegetic insert ([D-013](scope.md#d-013-diegetic-insertpoi-navigation-system)), perception modes ([D-017](#d-017-perception-modes-as-character-build-system))
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.9
|
||||
- **Raised by:** Araminta (geometric spec), Gore (organic requirement). Resolves Round 1 divergence — both survive in synthesis.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-049: Z-level rendering stack (8 layers)
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** 8-layer z-stack: (0) Floor tiles — zone identity, movement surface. (1) Floor objects — cosmetic detail, walked over. (2) Furniture/placed objects — y-sorted with entities, visual complexity center. (3) Entity sprites — y-sorted with Layer 2, D-033 colored. (4) Overhead/wall tops — pipes, ducts, lighting fixtures, signage; semi-transparent partial occlusion. (5) Fog of perception — vision cone mask, fog shader; affects layers 0-4. (6) Insert overlay — lattice HUD elements, bloom-rendered, NOT affected by fog. (7) Monologue/UI — top of stack, always visible. Wall rendering: Option B (visible top + face) for structural walls, Option A (boundary lines) for interior partitions. Sprite stacking out of scope.
|
||||
- **Key insight (Gore):** Overhead occlusion is thematically significant — entities passing behind shelving/under overhangs create local information gaps within otherwise known spaces.
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.14
|
||||
- **Raised by:** Araminta (8-layer spec), Gore (overhead as thematic tool). Unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-052: Character favorite colors — object-layer identification
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Each NPC has a favorite color expressed through personal objects (bedding, cushions, mugs, personal items), NOT on entity sprites. Muted register: dusty blue, warm terracotta, faded olive — personal, not faction. Creates secondary identification system: D-033 = relationship to player (entity layer), favorite color = person's identity in space (object layer). Investigation mechanic: recognizing whose stuff is where. Saturation constraint: favorite color saturation must stay below D-033 entity color saturation to preserve visual hierarchy. Godot implementation: mask shader + material duplication per unique color (~0.5-1ms at 50-100 objects). Build for v0.1.2+.
|
||||
- **Cross-reference:** Visual hierarchy ([D-044](#d-044-art-direction--visual-hierarchy-entity--object--structure)), design principle ([D-051](scope.md#d-051-settling-is-placement--design-principle))
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §7 (D-051 candidate)
|
||||
- **Raised by:** Team Leader (Jeroen), unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-056: Cursor states — insert-styled geometric
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Four cursor states using the neural insert's geometric visual language:
|
||||
- **Default:** Four thin inward-pointing ticks with bloom. White-blue #c8d0e0. Barely visible — the insert's own cursor.
|
||||
- **Entity hover:** Ticks expand outward (150ms). Corner brackets frame entity. Color shifts to D-033 relationship color. Verb tooltip in insert styling. Bloom pulse ~10% brighter on entity outline.
|
||||
- **Object hover:** Ticks rotate 45° to X-shape. Muted grey #8b8ba0 (amber #e8c547 if flagged). Simpler frame than entity.
|
||||
- **Weapon aim:** Hard transition. Ticks extend, center gap widens, lines thicken 1→2px. Warm white #f0e8d8. NO bloom. Entity in sights tints to D-033 color — aiming at a friend (green tint) should feel wrong.
|
||||
- All transitions 150ms linear. z-layer 7. Never changes by zone or narrative state ([D-045](#d-045-art-direction--environmental-neutrality-strict-zero-shift)).
|
||||
- Cursor changes on LOS, not just proximity. Click interaction range: ~2 subtiles (= 1m per [D-066](architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor)). Weapon-selected mode suppresses interaction prompts unless Shift held ("combat intent trumps social intent").
|
||||
- **Diegetic test (Stig):** Interaction labels render on z-layer 6 (insert overlay). If the insert is off, labels disappear. Passes the "is this information from the character's implant?" test.
|
||||
- **Rationale:** Diegetic — cursor is the insert's own interface element. Consistent with [D-048](#d-048-neural-insert-overlay--visual-design). Entity in weapon sights tinting to D-033 creates moral friction.
|
||||
- **Cross-reference:** Insert overlay ([D-048](#d-048-neural-insert-overlay--visual-design)), entity color ([D-033](#d-033-entity-color--relationship-to-player)), z-stack ([D-049](#d-049-z-level-rendering-stack-8-layers))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Araminta (visual spec), Stig (UX rules + diegetic test), Ozzie (weapon suppression)
|
||||
- **Dissent:** None.
|
||||
- **OQ-07 resolution (2026-02-19, #522):** Insert-off behavior is **option (a): cursor shape still changes, verb labels suppressed.**
|
||||
- Cursor state machine fires normally (entity hover → bracket shape, object hover → X-shape) — the character's body physically orients toward targets as a subconscious/spatial response.
|
||||
- Insert does not process targets into actionable data: `should_show_interactions()` returns false when `insert_active == false`, and interaction labels (z-layer 6) are hidden via `set_insert_active(false)` on `InteractionList` and `InteractionPrompt`.
|
||||
- `GameState.insert_active` is the source of truth (defaults true in v0.1; wired from snapshot field `insert_active`).
|
||||
- Rationale: diegetically consistent — the body reacts to proximity; the insert reacts to commands.
|
||||
|
||||
### D-057: Entity interaction — vertical list, insert-styled [PARTIALLY SUPERSEDED — archetype portion deferred to Phase 6]
|
||||
- **Date:** 2026-02-13
|
||||
- **Supersession note (2026-04-21 / amended 2026-04-22, Sprint 37, #878, PR #137):** The character-archetype verb variation portion of this decision is retired pending a Phase 6 character-model design — not deferred in place with a stub. Per the development cascade (CLAUDE.md), archetype-driven verb relabeling is Phase 6 detail-coloring and has been stripped from the server. Vertical-list structure, Phase 1/Phase 2 split, POI priority flips, and contradiction markers remain live. Relabeling (Open→"Move"/"Stash" vs "Scan"/"Flag") is deleted; container verb labels are now identical across all player states, and uniform labeling is the intended pre-Phase-6 end state, not a regression. Reintroduction gate: a confirmed Phase 6 character-model design is a prerequisite. See `docs/architecture/sprint-37-878-audit.md` (lead override section) for the cascade rationale.
|
||||
- **Decision:** Entity interactions use a compact vertical list (not radial). 2-4 options max, anchored to entity position. Insert-styled with Araminta's geometric aesthetic. New options unlocked by knowledge changes are highlighted with a gradient glow background. Radial menu reserved for world menu only ([D-058](#d-058-world-menu--radial-4-spokes)). Max 3 visible response options in dialogue context.
|
||||
- **Server architecture:** Two-phase verb computation. Phase 1 (simulation, no KG): compute maximum possible verb set from ObjectType component (Readable, Container, Terminal, Door, Pickup, Furniture — each with specific verb sets). Phase 2 (observer, reads KG): filter by character's knowledge (Confront requires KnowsDetails+ per [D-041](architecture.md#d-041-knowledge-graph-data-model)), apply POI priority flips, add contradiction markers. ~~Character-archetype verb variation implemented as Phase 2 observer filter rules (same crate: smuggler sees "Move/Stash", detective sees "Scan/Flag").~~ *[Removed Sprint 37 — archetype verb relabeling deleted; see supersession note above.]*
|
||||
- **Diegetic test:** Labels render on z-layer 6. If insert is off, labels disappear.
|
||||
- **Rationale:** Variable-length text options (e.g., confrontation lines in character voice) break radial spatial memory. List handles 1-4 options cleanly. New-item glow signals "something changed" without UX hazard of geometry transforming under cursor. Two-phase computation enables character differentiation without separate verb systems.
|
||||
- **References:** Disco Elysium (world-embedded indicators), Darkwood (minimal cursor), Rimworld (right-click context list).
|
||||
- **Cross-reference:** Cursor states ([D-056](#d-056-cursor-states--insert-styled-geometric)), knowledge graph ([D-041](architecture.md#d-041-knowledge-graph-data-model)), z-stack ([D-049](#d-049-z-level-rendering-stack-8-layers))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Stig (vertical list structure + diegetic test), Araminta (insert aesthetic), Dudley (two-phase verb computation), Nigel (character-archetype verb sets). Lead resolved: Stig's structure, Araminta's styling.
|
||||
- **Dissent:** Araminta argued for spoke radial (geometry transformation signals qualitative knowledge change — new spoke growing). Lead rejected: items moving under cursor when knowledge changes is a moving goalpost (bad UX while aiming at an option).
|
||||
- **OQ-07 resolution (2026-02-19, #522):**
|
||||
- When `insert_active == false`, the interaction list hides completely (`set_insert_active(false)` → `_hide()`).
|
||||
- Cursor shape changes still occur per D-056 OQ-07 — list suppression is independent of cursor state.
|
||||
- `GameState.insert_active` drives this at runtime, wired via `main.gd` on each snapshot.
|
||||
|
||||
### D-058: World menu — radial, 4 spokes
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Right-click opens a radial world menu. Four spokes: Observe (eye icon), Insert (phone icon), Comms (signal icon), Wait (clock icon). Insert-styled: geometric lines, thin spokes with icons, nearly transparent. Renders on z-layer 6. Drag-release for power users (high-speed drag-to-select), click-click for newcomers. v0.1: 2 spokes only (Observe + Insert), scale to 5-6 later.
|
||||
- **Rationale:** Radial works for world menu because items are fixed categories that don't vary by knowledge state (unlike entity verbs). Spatial memory builds quickly (~10 minutes). Drag-to-select makes the radial feel fast and fluid for experienced players.
|
||||
- **Cross-reference:** Entity interaction ([D-057](#d-057-entity-interaction--vertical-list-insert-styled)), insert overlay ([D-048](#d-048-neural-insert-overlay--visual-design)), z-stack ([D-049](#d-049-z-level-rendering-stack-8-layers))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Stig (structure + implementation), Araminta (insert aesthetic)
|
||||
- **Dissent:** None.
|
||||
|
||||
### D-059: Fog — shader-based, five layers, knowledge-graph-driven
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Fog is a shader-driven system (not particles) with five distinct layers:
|
||||
1. **Clear (vision cone):** Soft gradient edge over 6-8 subtiles (= 3-4 visual tiles per [D-066](architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor)), no hard line. Darkwood approach.
|
||||
2. **Light fog (peripheral):** Desaturated 40-50%, brightness -30%. Animated Perlin noise overlay (8-10s cycle). Entity [D-033](#d-033-entity-color--relationship-to-player) colors visible but reduced.
|
||||
3. **Deep fog (previously explored):** Near-monochrome with ~10% "zone temperature" tint (bar=warm dark, hub=cool dark, corridor=neutral dark). More pronounced noise (15-20s cycle). Fog breathes.
|
||||
4. **Unexplored + maps app:** Geometric wireframe outlines #333340. Insert data aesthetic.
|
||||
5. **Unexplored, no maps:** Solid near-black #12141a. Information zero.
|
||||
- **Fog entities:**
|
||||
- Sound pings: 2-3 thin concentric expanding rings (sonar-style) from source direction, insert white-blue. Loud = 3 rings bright fast. Quiet = 1 ring faint slow. Fade over 1.5s.
|
||||
- Recognized entity: [D-033](#d-033-entity-color--relationship-to-player) color glow + faint identifying silhouette feature (e.g., "Kael's vest") + 0.8s breathing pulse + ±0.5 tile position drift (approximate, not exact).
|
||||
- Unrecognized entity: neutral grey #555566 blob. No silhouette. No identifying features.
|
||||
- Recognition transition governed by cognitive delay ([D-060](#d-060-cognitive-delay-for-fog-recognition)).
|
||||
- **Knowledge-graph-driven:** Same fog shows different information per character based on their KG. Smuggler recognizes dock workers = green icons. Detective sees same entities = grey blobs. "Fog is not darkness — it's the absence of your attention."
|
||||
- **Soft perception degradation:** At high overlay load, diegetic scan-line interference (insert under strain). No hard cap on simultaneous perception modes — soft visual warning instead.
|
||||
- **Performance:** <1ms/frame total. Vision cone = PointLight2D. Fog = natural darkness + noise shader on CanvasGroup (Layer 5). Sound pings = 0-5 sprites. Entity ghosts = 0-10 sprites typical.
|
||||
- **Cross-reference:** Fog of perception ([D-011](#d-011-fog-of-perception-is-non-negotiable-pillar-1-infrastructure)), sound model ([D-018](#d-018-three-range-sound-model)), perception modes ([D-017](#d-017-perception-modes-as-character-build-system)), entity color ([D-033](#d-033-entity-color--relationship-to-player)), z-stack ([D-049](#d-049-z-level-rendering-stack-8-layers)), knowledge graph ([D-041](architecture.md#d-041-knowledge-graph-data-model))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Araminta (full visual spec + "fog is not darkness"), Tyre (performance validation), Nigel (replayability case — fog as primary divergence mechanism), Gestalt (signal/answer framework + soft cap rejection), Ozzie (false-positive shapes proposal)
|
||||
- **Dissent:** Gestalt proposed hard cap of 2 active perception modes. Lead rejected — replaced with Araminta's diegetic soft degradation.
|
||||
|
||||
### D-060: Cognitive delay for fog recognition
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** When the player recognizes a heard/sensed entity in fog, recognition is NOT instant. Single cognitive delay system: 0.6s base, 0.3s when observe_anomaly triggers (urgent context). Values are tunable via playtesting. Monologue fires DURING the delay ("Those footsteps... that's Kael's walk"), not after — the monologue IS the recognition. Visual transition: grey blob → [D-033](#d-033-entity-color--relationship-to-player) color + silhouette feature over ~0.3s within the cognitive delay window. Natural recognition (organic resolve) feels different from sensor recognition (digital snap with biometric ID — different monologue voice too).
|
||||
- **Rationale:** Recognition should feel like a cognitive event, not a UI update. The delay creates a moment where the player's brain and the character's brain are working together. Context-sensitive urgency (0.3s for anomalies) prevents the delay from feeling sluggish in tense situations.
|
||||
- **Cross-reference:** Fog layers ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven)), monologue ([D-016](#d-016-internal-monologue-as-core-perceptionatmosphere-system)), sound model ([D-018](#d-018-three-range-sound-model))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Ozzie (timing values + urgency split, adopted), Araminta (visual transition spec), Gestalt (longer values not adopted, but playtesting may adjust)
|
||||
- **Dissent:** Gestalt proposed 0.8-1.2s (longer, more contemplative). Lead chose Ozzie's shorter values as starting point.
|
||||
|
||||
### D-061: Dialogue box — unified conversation log, bottom screen, max 20% height, no portraits
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Dialogue occupies the bottom of the screen, max 20% height, max-width 1200px ([D-076](#d-076-dialogue-box-max-width--1200px-oq-29-resolution)). NO portraits — the NPC is on screen, a portrait is redundant. Monologue floats ABOVE the dialogue box on z-layer 7 — spatial separation allows monologue to contradict dialogue visually (character thinks one thing while NPC says another). Walk-away via WASD, dialogue fades over 300ms, no close button ([D-064](content.md#d-064-walk-away--three-phase-consequences)). Auto-pause in single-player when implant UI is open; overlay design for multiplayer readiness.
|
||||
- **Unified conversation log (Sprint 14, #535):** The dialogue box is a single chronological log for player-NPC conversations. Each entry shows `Speaker → Target: text` with per-character name colours (hash-indexed from configurable palette in `data/dialogue-theme.yaml`). Player response options render below the log; max 3 visible. Locked options invisible ([D-062](content.md#d-062-invisible-locked-dialogue-options)).
|
||||
- **Entry lifecycle:** All entries share the same timeout (15s + 3s fade, configurable via theme YAML). Walk-away clears response options but preserves log entries — earned information is fair game. Panel auto-hides when all entries expire and no active conversation is in progress.
|
||||
- **Passive overheard lines:** D-078 (overheard NPC conversations) was scrapped per R-012. Passive dialogue display will be redesigned after Phase 5 walkable environment.
|
||||
- **Rationale:** Game world stays live above the dialogue box — player sees NPC body language while talking. Monologue above + dialogue below = the character can think one thing while saying another. Max 3 options + invisible locks = player never knows what they're missing. No portrait because the NPC IS on screen. A single unified log avoids a separate UI element for overheard content and makes the flow of conversation feel natural — active and passive dialogue interleave chronologically.
|
||||
- **Cross-reference:** Invisible locks ([D-062](content.md#d-062-invisible-locked-dialogue-options)), confrontation ([D-063](content.md#d-063-confrontation--same-box-different-weight)), walk-away ([D-064](content.md#d-064-walk-away--three-phase-consequences)), z-stack ([D-049](#d-049-z-level-rendering-stack-8-layers)), max-width ([D-076](#d-076-dialogue-box-max-width--1200px-oq-29-resolution)), overheard NPC conversation ([D-078](#d-078-overheard-npc-conversation--passive-dialogue-panel-with-occlusion-filter))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13). Amended Sprint 14 (#535): unified log architecture.
|
||||
- **Raised by:** Stig (UI spec + no portraits), Lead (20% height constraint + max-width directive). Sprint 14 unified log: Stig (implementation).
|
||||
- **Dissent:** Stig initially proposed 25% height and 50% width centered. Lead constrained to 20% height and max-width.
|
||||
|
||||
### D-067: Recognition chime fires at onset of cognitive delay
|
||||
- **Date:** 2026-02-16
|
||||
- **Decision:** The monologue recognition chime ([D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open) assets 7-8) fires at the ONSET of the cognitive delay ([D-060](#d-060-cognitive-delay-for-fog-recognition)), not at its completion. Chime duration 300-400ms, overlapping with the start of the delay. The chime is "unresolved" — it opens a question, doesn't answer one. Full sequence when recognizing an entity in fog: (1) hear/sense something → (2) chime plays → (3) 0.6s cognitive delay begins (concurrent with chime tail) → (4) monologue text appears during delay ("Those footsteps... that's Kael's walk") → (5) blob transitions to [D-033](#d-033-entity-color--relationship-to-player) color + silhouette feature → (6) recognition complete.
|
||||
- **Rationale:** The chime marks the character's attention shifting, not the recognition completing. It creates an "unresolved" sensation — something is happening in the character's mind. Monologue text provides the resolution. This prevents the chime from feeling like a UI notification and instead makes it part of the character's cognitive process.
|
||||
- **Resolves:** Q-014
|
||||
- **Cross-reference:** Audio assets ([D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open)), cognitive delay ([D-060](#d-060-cognitive-delay-for-fog-recognition)), fog recognition ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven)), monologue ([D-016](#d-016-internal-monologue-as-core-perceptionatmosphere-system))
|
||||
- **Raised by:** Gestalt (proposal), confirmed by Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-069: Audio dip profiles for dialogue and confrontation
|
||||
- **Date:** 2026-02-16
|
||||
- **Decision:** Three audio dip profiles modify bus volumes during player focus states, all relative to player slider settings (proportional, not absolute):
|
||||
- **Dialogue dip:** Ambient -6 to -8dB, World SFX 0dB, Player Actions 0dB, UI 0dB. 300ms ease-in, 500ms ease-out. Reduces environmental noise to foreground conversation without muting world events.
|
||||
- **Confrontation dip:** Ambient -10 to -12dB + low-pass filter (20kHz → 800Hz), World SFX -4 to -6dB (graduated — loud events like sprinting footsteps break through, quiet sneaking doesn't), Player Actions 0dB, UI 0dB. 500ms ease-in, 1000ms ease-out with filter sweep. Creates emotional/cognitive muffling per [D-070](#d-070-confrontation-as-cognitive-vulnerability).
|
||||
- **ListeningFocus boost:** World SFX +2 to +3dB when player is stationary for 30+ ticks (eavesdrop bonus, per [D-071](#d-071-no-ambient-dip-for-eavesdropping--listeningfocus-boost)). Expresses heightened attention as audio gain.
|
||||
- **Key behaviors:**
|
||||
- All dB values are proportional to player slider setting, not absolute. If player sets World SFX to 50%, the -6dB dip applies to that 50% base.
|
||||
- Dips are interruptible — walk-away or stance change kills current tween, starts new tween to neutral.
|
||||
- Graduated World SFX dip during confrontation: loud, urgent events (sprinting, doors slamming, alarms) break through at reduced volume. Quiet, careful movement may not be noticed.
|
||||
- **Rationale:** Dips model finite attention. Dialogue suppresses ambient noise (focus on conversation). Confrontation suppresses both ambient and peripheral sounds (emotional tunnel vision per [D-070](#d-070-confrontation-as-cognitive-vulnerability)). ListeningFocus boost rewards deliberate eavesdropping. All effects proportional to user volume settings respects player accessibility choices.
|
||||
- **Cross-reference:** Audio architecture ([D-068](architecture.md#d-068-5-bus-audio-architecture)), confrontation vulnerability ([D-070](#d-070-confrontation-as-cognitive-vulnerability)), eavesdropping ([D-071](#d-071-no-ambient-dip-for-eavesdropping--listeningfocus-boost)), audio aesthetic ([D-074](content.md#d-074-audio-aesthetic-identity--insert-tech-vs-organic))
|
||||
- **Raised by:** Inigo (initial spec), Gestalt (graduated approach + ListeningFocus boost), Tyre (implementation details), Ozzie (proportional dip to respect player settings)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-070: Confrontation as cognitive vulnerability
|
||||
- **Date:** 2026-02-16
|
||||
- **Decision:** Confrontation creates perceptual vulnerability through reduced ambient awareness. Design principle: "Emotional focus creates perceptual vulnerability." Player actions requiring cognitive focus (confrontation dialogue, future: deep terminal reading, complex insert queries) mechanically reduce ambient perception via audio dip ([D-069](#d-069-audio-dip-profiles-for-dialogue-and-confrontation)) and may suppress peripheral monologue triggers. This is NOT a punishment — it's a realistic consequence of finite attention. The player mitigates risk by choosing WHERE and WHEN to confront (safe location vs exposed corridor, early shift vs busy period).
|
||||
- **Mechanical expression:**
|
||||
- During confrontation: ambient sounds muffled, quiet NPC movement may go undetected (graduated World SFX dip means careful footsteps suppressed, sprinting footsteps still audible).
|
||||
- Post-confrontation: delayed monologue may fire for missed events ("Wait — did someone just pass by?").
|
||||
- World continues per [D-045](#d-045-art-direction--environmental-neutrality-strict-zero-shift) environmental indifference — no scripted ambushes, but NPCs on routine may coincidentally pass while player is focused.
|
||||
- Vulnerability is probabilistic and emergent, not scripted.
|
||||
- **Consistency principle:** Connects to [D-053](scope.md#d-053-movement-as-stance-toggle-system) sprint suppressing monologue (physical focus limits interpretation). Confrontation suppresses ambient perception (emotional focus limits peripheral awareness). High-focus activities suppress peripheral cognition — this is the shared rule.
|
||||
- **Must feel "felt, not computed" (Paula):** Muffling is psychological tunnel vision, not a debuff tooltip. No UI indicator. Player realizes in retrospect: "I was so focused on Sera I didn't hear Kael walk past."
|
||||
- **Rationale:** Makes WHERE and WHEN to confront meaningful decisions. Confronting in a private corner = safer. Confronting in a busy corridor during shift change = riskier. Player agency through spatial and temporal choice, not RNG.
|
||||
- **Cross-reference:** Audio dip ([D-069](#d-069-audio-dip-profiles-for-dialogue-and-confrontation)), confrontation UI ([D-063](content.md#d-063-confrontation--same-box-different-weight)), environmental indifference ([D-045](#d-045-art-direction--environmental-neutrality-strict-zero-shift)), stance system ([D-053](scope.md#d-053-movement-as-stance-toggle-system)), monologue ([D-016](#d-016-internal-monologue-as-core-perceptionatmosphere-system))
|
||||
- **Raised by:** Gestalt (vulnerability principle), Ozzie (graduated dip approach), Paula ("felt not computed" framing)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-071: No ambient dip for eavesdropping — ListeningFocus boost
|
||||
- **Date:** 2026-02-16
|
||||
- **Decision:** Overheard conversation (eavesdropping) does NOT apply dialogue dip ([D-069](#d-069-audio-dip-profiles-for-dialogue-and-confrontation)). Cognitive state is opposite of direct conversation: extracting signal from noise requires MORE ambient awareness, not less. Instead, eavesdrop quality improves via ListeningFocus boost (+2 to +3dB World SFX when stationary 30+ ticks). Eavesdrop information quality is: distance-dependent, stance-modified ([D-053](scope.md#d-053-movement-as-stance-toggle-system) Careful stance grants "tell notice bonus"), ListeningFocus-boosted, and ambient-noise-penalized.
|
||||
- **Ambient zone affects eavesdrop difficulty:**
|
||||
- Bar (high ambient) = conversations hidden in murmur, requires proximity + ListeningFocus.
|
||||
- Workplace (moderate ambient) = conversations semi-conspicuous, distance-dependent.
|
||||
- Corridor (low ambient) = conversations conspicuous, easy to overhear from distance.
|
||||
- **Information confidence:** Overheard information enters knowledge graph at lower confidence (KnowsOf, not KnowsDetails per [D-041](architecture.md#d-041-knowledge-graph-data-model)) unless ListeningFocus + proximity allows high-quality capture.
|
||||
- **Rationale:** Direct conversation = character focuses, ambient dips. Overheard conversation = character strains to hear, ambient stays or boosts. Opposite cognitive states produce opposite audio profiles. Creates meaningful difference between talking TO someone vs listening IN on someone.
|
||||
- **Cross-reference:** Audio dip ([D-069](#d-069-audio-dip-profiles-for-dialogue-and-confrontation)), stance system ([D-053](scope.md#d-053-movement-as-stance-toggle-system)), knowledge graph ([D-041](architecture.md#d-041-knowledge-graph-data-model)), zone audio ([D-072](#d-072-universal-event-driven-conversation-murmur))
|
||||
- **Raised by:** Gestalt (cognitive state framing), Paula (zone-conspicuousness model), unanimously endorsed
|
||||
- **Dissent:** None
|
||||
|
||||
### D-072: Universal event-driven conversation murmur
|
||||
- **Date:** 2026-02-16
|
||||
- **Decision:** NPC-to-NPC conversations use a single universal murmur sound asset, not zone-specific variants. Zone ambient determines conspicuousness: bar ambient (high murmur density) hides conversations, corridor ambient (low background) makes conversations conspicuous. Maps to [D-047](#d-047-art-direction--two-tier-animation-system) two-tier behavior visibility: bar conversations are Tier 1 (clearly happening, content obscured), corridor conversations are Tier 2 (ambiguous — are they talking or just standing near each other?).
|
||||
- **Asset split:**
|
||||
- Bar ambient murmur: baked into `amb_bar_layer.ogg` (continuous background per [D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open)).
|
||||
- NPC proximity murmur: separate event-driven asset, deferred to future sprint (not in Sprint 7 scope). When implemented, same asset plays everywhere; zone ambient determines audibility.
|
||||
- **Rationale:** One murmur asset + zone-dependent conspicuousness creates the signal/noise dynamic naturally. Bar = high noise floor, conversations blend in. Corridor = low noise floor, conversations stand out. Simpler content production, richer emergent behavior.
|
||||
- **Cross-reference:** Audio assets ([D-038](scope.md#d-038-audio-in-v01-scope--8-files-via-stable-audio-open)), two-tier animation ([D-047](#d-047-art-direction--two-tier-animation-system)), eavesdropping ([D-071](#d-071-no-ambient-dip-for-eavesdropping--listeningfocus-boost))
|
||||
- **Raised by:** Paula (zone-conspicuousness model), Inigo (scoping to future sprint)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-076: Dialogue box max-width — 1200px (OQ-29 resolution)
|
||||
- **Date:** 2026-02-19
|
||||
- **Decision:** `DIALOGUE_MAX_WIDTH = 1200px`. Dialogue box is max 1200px wide, centered on screen. Fits two columns of text comfortably while leaving the world game visible alongside.
|
||||
- **Derivation:** ~62% of target 1920px viewport width. Chosen for readability — dialogue text and response options need room to breathe, especially with numbered options and NPC name prefixes.
|
||||
- **Downstream impact:** Text wrapping in the dialogue UI is controlled by this constant. Box is centered; the game world remains visible left and right.
|
||||
- **Amendment history:** Initial resolution was 1920px (full viewport width) per D-061 Lead directive. Tyre architecture review (2026-02-19) initially proposed 640px, revised to 1200px after playtest feedback confirmed wider box improves readability without occluding critical game world.
|
||||
- **Implementation:** `Constants.DIALOGUE_MAX_WIDTH` in `client/scripts/constants.gd`.
|
||||
- **Cross-reference:** Dialogue box ([D-061](#d-061-dialogue-box--bottom-screen-max-20-height-no-portraits)), dual-scale grid ([D-066](architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor))
|
||||
- **Amends:** [D-061](#d-061-dialogue-box--bottom-screen-max-20-height-no-portraits) (adds pixel value for max-width)
|
||||
- **Raised by:** Stig (OQ-29), revised per Tyre architecture review and playtest feedback
|
||||
|
||||
### D-077: Zone temperature memory — server-tracked zone_id (OQ-09 resolution)
|
||||
- **Date:** 2026-02-19
|
||||
- **Decision:** Zone temperature memory is **server-tracked** via `zone_id: Option<u16>` on `VisibleTile` in `ObserverSnapshot`. The server assigns a zone ID to each tile based on the `ZoneMap` resource (spatial zone assignment). The client maps `zone_id` to temperature tint from a local lookup table for deep fog rendering ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven) layer 3: ~10% zone temperature tint — bar=warm dark, hub=cool dark, corridor=neutral dark).
|
||||
- **Resolves:** OQ-09
|
||||
- **Rationale:** D-073 already mandates `zone_id` per tile in `ObserverSnapshot` for audio zone crossfade. With `zone_id` already on the wire for crossfade, zone temperature memory is essentially free — no additional protocol field needed, no additional server computation beyond the zone lookup. Client-only tracking was rejected because: (1) the server is the authoritative source of zone geometry, (2) client heuristics (remembering last-visited zone) would diverge from server truth at zone boundaries, and (3) the data is already crossing the wire for D-073.
|
||||
- **Implementation:**
|
||||
- `VisibleTile.zone_id: Option<u16>` — `None` for tiles outside any defined zone (corridors, transition spaces). Uses `#[serde(default, skip_serializing_if)]` for backwards compatibility with v10 clients.
|
||||
- `ZoneMap` resource (`simulation/zone.rs`): `BTreeMap<(i32, i32, i32), u16>` mapping tile coordinates to zone IDs. BTreeMap per [D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline) principle 4 (deterministic iteration). Populated by map builders at setup time.
|
||||
- Zone enrichment runs in `compute_observer_snapshot` — the observer pipeline's final assembly stage. `PerceptionQuery` trait remains zone-unaware (zone assignment is map data, not perception geometry).
|
||||
- Protocol version bumped to 11.
|
||||
- **Client contract:** Client maintains a `zone_id → { name, temperature_tint, ambient_layer }` lookup table. Deep fog shader (layer 3) reads `zone_id` from the last-seen `VisibleTile` data to apply the ~10% temperature tint. AudioManager reads `zone_id` to trigger crossfade between ambient layers ([D-073](architecture.md#d-073-zone-crossfade-approach--hard-boundary-soft-audio-transition)).
|
||||
- **Cross-reference:** Fog layers ([D-059](#d-059-fog--shader-based-five-layers-knowledge-graph-driven)), zone crossfade ([D-073](architecture.md#d-073-zone-crossfade-approach--hard-boundary-soft-audio-transition)), ObserverSnapshot ([D-020](architecture.md#d-020-engine-and-architecture-selection--godot-client--rust-simulation-via-subprocessipc)), deterministic simulation ([D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline))
|
||||
- **Raised by:** Tyre (architecture review, #523)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-078: ~~Overheard NPC conversation — passive dialogue panel with occlusion filter~~ SCRAPPED (R-012)
|
||||
- **Date:** 2026-02-19
|
||||
- **Superseded:** 2026-04-10. The entire NPC ambient interaction model is scrapped and will be rebuilt from scratch after a walkable environment exists (Phase 5+). See [R-012](../rejected/perception.md#r-012-overheard-npc-conversation-system-d-078--scrapped).
|
||||
- **Original decision:** NPC-to-NPC conversations overheard by the player are displayed in the **dialogue panel in passive mode** (read-only, no response options). An **occlusion filter** degrades displayed text based on distance, ambient noise, and player effort (ListeningFocus stance). Monologue remains a separate channel — it reacts to overheard content via the `witness_interaction` trigger but does not carry conversation text itself.
|
||||
- **Passive panel behavior:**
|
||||
- Same D-061 dialogue box, but read-only — no response options rendered.
|
||||
- Shows speaker name and intended target (e.g. "Kael → Mira").
|
||||
- Visually distinguished from interactive dialogue (dimmed border or header treatment — exact style TBD by Araminta).
|
||||
- Walking out of earshot dismisses the panel naturally.
|
||||
- **Occlusion filter — server-authoritative:**
|
||||
- Occlusion is computed **on the server**. The server rolls per-word visibility based on distance, ambient noise, and ListeningFocus stance, then sends pre-occluded text to the client with `...` replacing dropped words. The client renders exactly what it receives — no client-side probability logic.
|
||||
- Per-word visibility is a **probability**, not a deterministic cutoff. Each word is independently rolled — same distance, same conversation can yield different fragments across playthroughs.
|
||||
- **Close / clear:** High probability per word — most or all text arrives intact, speaker names shown.
|
||||
- **Moderate distance / some noise:** Medium probability — words arrive as `...`, speaker names visible. The player may or may not catch the crucial word.
|
||||
- **Far / noisy zone:** Low probability — speaker indicators only, few or no readable words. Audio murmur still plays per D-072.
|
||||
- **ListeningFocus stance:** Shifts probability curve upward — improves word visibility at current distance.
|
||||
- **Multiplayer-readiness:** Each observer gets their own occluded version computed from their specific distance/noise/stance. Seedable RNG per tick ensures deterministic replay (D-010).
|
||||
- **Design intent:** Stochastic word-drop means the player can never be certain they got the full picture from eavesdropping alone. This pushes them toward direct conversation to confirm — where they must reveal something about what they know. The information asymmetry loop closes on itself.
|
||||
- **Dual-channel principle:** Dialogue panel = what you hear. Monologue = what you think about it. The `witness_interaction` monologue trigger fires after overheard content is displayed, producing the character's internal reaction ("She's lying to him", "So they do know about the cargo"). These are separate UI elements with separate content pipelines.
|
||||
- **Content pipeline:** Copy team authors NPC-to-NPC dialogue lines once at full fidelity. The server applies occlusion degradation before sending to the client. No need to author multiple fidelity versions.
|
||||
- **Rationale:** Keeps monologue as a clean internal response system — thoughts only, never quoted speech. The dialogue panel already exists for player-NPC interaction; reusing it in passive mode for overheard conversation avoids a new UI element. The occlusion filter makes proximity and attention mechanically meaningful without gating content behind binary thresholds.
|
||||
- **Cross-reference:** Dialogue box ([D-061](#d-061-dialogue-box--bottom-screen-max-20-height-no-portraits)), eavesdropping ([D-071](#d-071-no-ambient-dip-for-eavesdropping--listeningfocus-boost)), conversation murmur ([D-072](#d-072-universal-event-driven-conversation-murmur)), monologue system ([D-016](#d-016-internal-monologue-as-core-perceptionatmosphere-system)), knowledge confidence ([D-041](architecture.md#d-041-knowledge-graph-data-model))
|
||||
- **Raised by:** Lead (passive panel directive, occlusion filter, monologue separation)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-079: Knowledge Grant Architecture
|
||||
- **Date:** 2026-02-24
|
||||
- **Decision:** All knowledge input (dialogue testimony, physical evidence, POI discovery, NPC-authored initial knowledge) flows through a single `KnowledgeEventType::KnowledgeGranted` event type. No separate event types for different grant sources. The `KnowledgeGrant` YAML schema is extended to an untagged enum supporting `Fact { fact_id, confidence }` and `Entity { entity_ref, attributes, confidence }` variants. The source field (`KnowledgeSource`) distinguishes provenance: `ToldBy { source_id: StableId, tick }` for NPC testimony, `DirectObservation { tick }` for physical evidence, `Heard { tick, range }` for overheard conversations. Grants fire at line selection time in `process_talk_interaction`, server-side, pushed to `KnowledgeEventQueue` and processed on the same tick. A `ContentEntityRegistry` resource (`BTreeMap<String, StableId>`, populated at NPC spawn time) resolves `entity_ref` strings to `StableId`s at grant processing time. Content-load validation enforces: confidence strings parse to valid `KnowledgeConfidence` variants; fact_ids conform to `"category.topic"` format; entity_refs resolve to registered StableIds. Runtime guardrail: if the granting NPC's KG does not contain the fact being granted, the grant is dropped with `tracing::warn!`.
|
||||
- **Scope note — `Compound` grant variant:** `Compound { grants: Vec<KnowledgeGrant> }` (multiple grants from a single line) deferred to Sprint 18. Sprint 17 ships `Fact` and `Entity` variants only. Sprint 18 `EntityGrant { attributes: BTreeMap }` full variant is committed scope, not aspirational (Paula condition, 2026-02-24).
|
||||
- **Rationale:** Unified event type keeps the knowledge system composable. Grant timing at line selection (not client display) ensures D-010 determinism — tick-stamped and server-authoritative. Entity grants are required for contradiction detection: testimony must create `EntityKnowledge` with `ToldBy` source so that a subsequent `DirectObservation` can detect a discrepancy. Physical evidence uses the same mechanism with `DirectObservation` source, which is treated as higher-confidence and cannot be contradicted by the NPC-denial path.
|
||||
- **Raised by:** Knowledge Flow & NPC Information Boundaries Workshop — unanimous on grant timing and unified event type. Entity grants in Sprint 17 per team lead decision (2026-02-24), overriding Paula's Round 2 acceptance of Dudley's FactId workaround.
|
||||
- **Dissent:** Paula (Round 2) accepted the FactId workaround with 3 binding conditions; team lead overrode in favour of entity grants path championed by Tyre, Gestalt, and Dudley. Paula's conditions honoured where applicable: (1) `ToldBy` source flows through `ContradictionDetected` event payload — satisfied by D-083; (2) Sprint 18 entity grants are committed scope; (3) formal record of this commitment.
|
||||
- **Implements:** Tickets #545 (schema), #546 (event + handler)
|
||||
- **Cross-reference:** [D-041](architecture.md#d-041-knowledge-graph-data-model), [D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline), [D-083](#d-083-contradiction-detection-pipeline)
|
||||
|
||||
### D-080: NPC-to-NPC Knowledge Propagation
|
||||
- **Date:** 2026-02-24
|
||||
- **Decision:** NPC-to-NPC knowledge transfer is implemented via a `transfer_npc_knowledge` Bevy system that runs `after(run_npc_conversations)`. The system uses `kg_query.get_many_mut([entity_a, entity_b])` for dual-mutable KG access. Knowledge transfer occurs once per conversation at conversation start, not per-line. Rate: flat `rng.random_range(1..=3)` facts per conversation, drawn from eligible entries sorted by `last_updated_tick` descending (most recent first). Trust-gated filtering: `RelationshipEdge.trust` value determines eligible entries (None tier < 0: no transfer; Surface 0–3: Active facts at KnowsOf+ only; Real 3–7: facts at any confidence + entity observations; Secret 7–10: all Active entries). Confidence cap: `transferred_confidence = min(source_confidence, KnowledgeConfidence::KnowsOf)`. Facts with `disclosure_blocked: true` are never transferred regardless of trust tier. Source construction: `KnowledgeSource::ToldBy { source_id: speaker_sid, tick: time.tick }`. Player overhearing: when the player is within `VOICE_RANGE_TILES` (8) of a knowledge-transferring NPC pair, the player gains entity-level KG entries at `Suspects` confidence with `KnowledgeSource::Heard { tick, range: Medium }`. Specific overheard fact transfer to player deferred to Sprint 18.
|
||||
- **Rationale:** Reuses `run_npc_conversations` proximity detection, deterministic StableId-sorted pairing, and conversation lifecycle — avoids building a separate propagation system. Confidence capping at `KnowsOf` prevents gossip chains from amplifying information. `ToldBy` source construction is the prerequisite for contradiction detection. The `disclosure_blocked` flag models secrets whose sharing is existentially dangerous regardless of trust (D-034 NPC design requirement).
|
||||
- **Resolves:** Q-024
|
||||
- **Raised by:** Workshop — unanimous
|
||||
- **Dissent:** None
|
||||
- **Implements:** Ticket #548
|
||||
- **Cross-reference:** [D-041](architecture.md#d-041-knowledge-graph-data-model), [D-083](#d-083-contradiction-detection-pipeline), [D-078](#d-078-overheard-npc-conversation--passive-dialogue-panel-with-occlusion-filter) (D-078 scrapped per R-012; `transfer_npc_knowledge` retained for Phase 5 rewire — see Amendment 2026-04-19)
|
||||
- **Amendment (2026-04-19, R-012 / #848):** D-078 was scrapped (R-012) and the `run_npc_conversations` system was deleted in #848. The `transfer_npc_knowledge` system is **retained in-tree for Phase 5 rewire** but no longer fires in production — its `Added<NpcConversation>` trigger is now only inserted by test fixtures. The design (trust-gated transfer, dual-mutable KG access, `KnowsOf` confidence cap, `disclosure_blocked` honoring) is preserved; Phase 5 will wire a new proximity/dialogue trigger in its place. Until then, treat the system as dormant and guard against assuming it runs.
|
||||
|
||||
### D-081: Unprompted Disclosure Design
|
||||
- **Date:** 2026-02-24
|
||||
- **Decision:** Unprompted disclosure is implemented as a filtered KG query producing a `DisclosureCandidates` component, consumed by Layer 4 of the dialogue pipeline. The system runs as `derive_disclosure_candidates` (Active-tier NPCs within player range only; recomputed every 30 ticks via `computed_tick` freshness check). NPCs check their own KG only — no cross-entity KG queries (D-010 principle 2). Candidate selection filters: Active state only; confidence ≥ KnowsOf (Cautious trait raises threshold); not in `per_fact_history` (not already disclosed this cooldown period); `disclosure_blocked != true`. Trait two-stage filter: Stage 1 (what) filters candidate pool by trait-based predicates (Cautious raises confidence floor, Gossipy lowers it, Loyal suppresses facts about protected entities, Talkative overrides witness inhibition). Stage 2 (how) biases line pool scoring in Layer 4. Trigger gates (all must pass): trust tier ≥ Surface toward player; mood not Hostile; contentment ≥ −10; candidates not empty; witness inhibition (no non-trusted NPCs within 5 tiles, OR NPC-player trust = Secret tier, OR Talkative trait override); location privacy (`disclosure_context` tag compatible with current zone type: `private`/`semi_private`/`any`); per-NPC cooldown (300 ticks / 30 game-minutes) not active; global rate limit not exceeded. Global rate limit: 1 disclosure per 10 ticks maximum across all NPCs; when multiple candidates ready in same window, select by ascending StableId (deterministic, D-010). Rate limiting layers: (1) per-fact per-NPC `per_fact_history` — primary; (2) per-NPC 300-tick cooldown — secondary; (3) global 1/10-tick cap — tertiary.
|
||||
- **Rationale:** NPCs checking only their own KG (Option A) is both diegetically correct and mechanically richer: NPCs can say things the player already knows, which creates dramatic irony. Option B (NPC checks player's KG) would collapse this asymmetry at exactly the moments their speech would be most dramatically charged. Separate `DisclosureCandidates` component prevents DerivedTellState serialization bloat. The location privacy gate creates learnable spatial behavior patterns. The per-fact `per_fact_history` is the primary narrative quality gate.
|
||||
- **Raised by:** Workshop — unanimous on architecture; Paula and Gestalt on trigger gates; Tyre and Dudley on implementation structure
|
||||
- **Dissent:** Gestalt (Round 1) opposed global rate limit as creating invisible NPC competition. Resolved in Round 2 via deterministic StableId selection. Included.
|
||||
- **Implements:** Tickets #551, #172, #173
|
||||
- **Cross-reference:** [D-041](architecture.md#d-041-knowledge-graph-data-model), [D-082](#d-082-npc-information-boundaries--mvp-scope), [D-034](content.md#d-034-the-friend-npc-archetype)
|
||||
|
||||
### D-082: NPC Information Boundaries — MVP Scope
|
||||
- **Date:** 2026-02-24
|
||||
- **Decision:** Sprint 17 MVP information boundary scope: (1) `tell_state.rs` reads NPC relationship state from KG for OTHER-entity state (replaces direct `relationships.entries` read for Friendly tell derivation); self-axis components (Secret, Contentment, Tolerance, Mood) continue as ground-truth reads. (2) Unprompted disclosure (D-081) uses KG for candidate selection. No other system retrofits in Sprint 17. `derive_tell_state` adds `Option<&KnowledgeGraph>` to query; `None` falls through to current axis-based behavior (existing tests continue passing). All KG-driven behavior scoped to `With<ActiveSim>` — Background-tier NPCs receive no KG-based boundary changes. Deferred: conversation partner KG-awareness check (Sprint 18 candidate, `kg.knows_entity(&partner_sid)` in pairing loop); routine KG awareness (v0.2+); pathfinding KG integration (not planned — failure mode has no safe recovery). Fallback on missing KG entry: fall through to ground truth with `tracing::debug!` structured logging.
|
||||
- **Rationale:** The minimum viable boundary produces maximum gameplay-visible difference for minimum risk. Pathfinding from KG has an unresolvable failure mode (NPC forgets path nodes = stuck NPCs = undefined movement behavior) and must not be implemented. Self-knowledge always comes from axis components because the NPC is the continuous observer of its own state. The `Option<&KnowledgeGraph>` addition is backward-compatible.
|
||||
- **Raised by:** Workshop — unanimous
|
||||
- **Dissent:** None. Paula adds that `tell_state` should eventually incorporate KG-derived secret-exposure intensity — deferred to a future sprint as enhancement.
|
||||
- **Implements:** Tickets #549 (step 1), #551 (step 2), ticket #142
|
||||
- **Cross-reference:** [D-041](architecture.md#d-041-knowledge-graph-data-model), [D-081](#d-081-unprompted-disclosure-design), [D-026](architecture.md#d-026-npc-simulation-tier-system)
|
||||
|
||||
### D-083: Contradiction Detection Pipeline
|
||||
- **Date:** 2026-02-24
|
||||
- **Decision:** Contradiction detection is event-driven at KG write time — fires inside `observe_entity()` (`server/src/knowledge/graph.rs`) before overwriting an existing entry. Detection algorithm: if the existing entry has `source: ToldBy { tick: told_tick }` AND `last_known_position` differs from incoming position AND `|current_tick - told_tick| < CONTRADICTION_WINDOW_TICKS` (default 600; configurable per contradiction type), then: (1) `entry.state = KnowledgeState::Contradicted`; (2) `entry.contradicted_claim = Some(ContradictionClaim { source: entry.source.clone(), claimed_position: entry.last_known_position, detected_at_tick: current_tick })`; (3) proceed to write new observation. A `ContradictionDetected { observer, entity_sid, source_display_name: Option<String>, subject_display_name: Option<String> }` event is pushed; display names are resolved at detection time via `EntityRegistry + NpcName` so the monologue system is a pure string consumer. `EntityKnowledge` gains one new field: `pub contradicted_claim: Option<ContradictionClaim>` with `#[serde(skip_serializing_if = "Option::is_none")]` and `#[serde(default)]` — backward-compatible, zero migration required. Downstream event chain: `ContradictionDetected` → monologue system (named contradiction line) → relationship shift (`ToldBy` source entity → `PersonOfInterest`) → D-033 amber via existing pipeline → `AnomalyMarker` via `detect_anomalies` (already tested). Both the `ToldBy` entry and the `DirectObservation` entry receive `Contradicted` state (epistemic neutrality). Location contradiction is automatic (Sprint 17). Attribute contradiction uses content-authored YAML pairs (Sprint 18). Fact contradiction uses content-authored `contradicts` field on KnowledgeGrant entries (Sprint 18). `CONTRADICTION_WINDOW_TICKS = 600` (1 game-hour) as default constant, with content-authored override per claim type.
|
||||
- **Rationale:** Event-driven detection avoids per-tick KG scan overhead (99% of ticks have no new information). The `ContradictionClaim` struct (typed) was chosen over string encoding in `known_attributes`: the struct is accessed with direct field reads (no string parsing in the detection hot path); the monologue system needs a typed `KnowledgeSource` to resolve the source entity's name; string encoding in `known_attributes` mixes semantic metadata with internal bookkeeping; one optional struct field is additive (no breaking changes, no migration). Steps 2–5 of the downstream chain (anomaly marker, D-033 color, relationship shift, monologue selection) are already implemented and passing tests. Contradiction detection is the missing link that enables THE FRIEND arc.
|
||||
- **Resolves:** Q-026
|
||||
- **Raised by:** Workshop — unanimous on architecture and downstream chain; Tyre and Gestalt on struct approach; Dudley conceded Option B (string encoding).
|
||||
- **Dissent:** Dudley (Round 1): Option B string encoding as Sprint 17 workaround. Conceded in Round 2. No standing dissent.
|
||||
- **Implements:** Tickets #547 (struct + detection), #550 (monologue + event chain)
|
||||
- **Cross-reference:** [D-034](content.md#d-034-the-friend-npc-archetype), [D-033](perception.md#d-033-entity-color--relationship-to-player), [D-041](architecture.md#d-041-knowledge-graph-data-model), [D-079](#d-079-knowledge-grant-architecture), [D-080](#d-080-npc-to-npc-knowledge-propagation)
|
||||
|
||||
### D-086: Insert icon system — custom SVG, no icon font
|
||||
- **Date:** 2026-02-24
|
||||
- **Decision:** The insert overlay (z-layer 6) uses **custom SVG icons**, not an icon font. The v0.1 icon vocabulary (~12–15 shapes: stance indicators, perception mode icons, inventory item silhouettes, border arrows) is too small and too specific for a font. No available icon font (Material Symbols, Phosphor, Feather, Tabler) matches the insert's geometric/diegetic visual language — they all read as "app UI," not "neural lattice overlay." Custom SVGs authored to the insert's constraint set (clean geometry, minimal anchor points, `#c8d0e0` chrome color, 1px stroke base weight) ensure all insert elements feel generated by the same system.
|
||||
- **Why not an icon font:**
|
||||
- **Vocabulary mismatch:** No font has "hexagonal corridor access token" or "thermal perception mode" in a sci-fi register. Inventory silhouettes are universe-specific — we author them regardless.
|
||||
- **Weight precision:** The spec defines 1px (smuggler/baseline) vs 1–2px (detective/augmented) line weight. Custom SVG `stroke-width` responds to `lattice_profile` parameter directly. Icon fonts can't vary weight per-character in a single rendering pass.
|
||||
- **Visual coherence:** Mixing a generic icon font with the custom geometric primitives (diamond POI markers, 6px dots, 4px evidence squares, commission grid) creates two visual registers on the same UI layer. All insert elements must feel like they came from one design system.
|
||||
- **Godot integration:** Godot 4 handles SVG natively (AtlasTexture, importable SVGs). Runtime color via ShaderMaterial. No font rendering pipeline or bitmap caching needed.
|
||||
- **Icon vocabulary (v0.1):**
|
||||
- Inventory item silhouettes: 3–4 items at 40×40px (manifest, access token, comm log)
|
||||
- Perception mode indicators: 2–3 icons at 20×20px (deferred until #315 specs the modes)
|
||||
- Stance indicators: 4 icons at 20×20px (WALK, CAREFUL, SPRINT, CROUCH) — delivered Sprint 32 alongside text labels. Icons supplement labels; text remains primary affordance.
|
||||
- Interaction prompt icons: 4 icons at 16×16px (talk, observe, follow, examine) — delivered Sprint 32. Supplement interaction verb text per insert HUD wireframe §9.
|
||||
- Border arrows and geometric markers (diamonds, dots, squares): drawn as primitives, not icons
|
||||
- **Authoring constraints:** 1px stroke weight base (scaled to 2px for `lattice_augmented` via parameter), `#c8d0e0` as design reference color (runtime-replaceable), minimal anchor points, no decorative curves.
|
||||
- **Calibration reference:** Phosphor Light (MIT) — not for use, but for evaluating small-size readability of custom shapes during authoring. If a custom icon doesn't read as cleanly as a Phosphor Light equivalent at 16px, simplify it.
|
||||
- **Cross-reference:** Insert overlay ([D-048](#d-048-neural-insert-overlay--visual-design)), insert HUD wireframe (`docs/design/insert-hud-wireframe-v01.md`), visual grammar (`docs/design/visual-grammar-v01.md` §7), cursor states ([D-056](#d-056-cursor-states--insert-styled-geometric))
|
||||
- **Raised by:** Araminta (analysis and recommendation), project lead (confirmed).
|
||||
- **Dissent:** None.
|
||||
- **Amendment (2026-04-05):** "Smuggler only per D-065" scope on inventory item silhouettes is obsolete. [D-117](scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) eliminates the smuggler/detective frame; [D-122](content.md#d-122-all-npcs-generated--no-named-hand-authored-characters) removes named characters. Inventory icons are no longer character-specific. D-065 cross-reference removed.
|
||||
|
||||
---
|
||||
|
||||
*38 decisions. Last updated: 2026-02-24 (D-086: Insert icon system)*
|
||||
@@ -0,0 +1,90 @@
|
||||
# Process Decisions
|
||||
|
||||
How the team works: composition, naming, workflow.
|
||||
|
||||
---
|
||||
|
||||
### D-004: Team composition confirmed
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** Team of 8 agents + Team Leader.
|
||||
|
||||
| Agent | Role |
|
||||
|-------|------|
|
||||
| MIRI | Lore Expert & Canon Guardian |
|
||||
| OZZIE | Player Experience / "Wow Factor" Advocate |
|
||||
| PAULA | Narrative & Political Depth |
|
||||
| GORE | Themes & Endgame Design |
|
||||
| GESTALT | Systems Design & Fun Factor |
|
||||
| NIGEL | Sandbox & Replayability |
|
||||
| TYRE | Technical Architecture & Feasibility |
|
||||
| SCRIBE | Documenter |
|
||||
| Jeroen | Team Leader, final decisions |
|
||||
|
||||
### D-021: Official project title — "The Settled Reach"
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** The official project and game title is **"The Settled Reach"**. The domain settledreach.com has been secured. Individual campaigns or scenarios can have subtitles in the format "The Settled Reach: [Scenario Name]" but the core title remains consistent.
|
||||
- **Rationale:** Following Round 14's worldbuilding confirmation establishing the Settled Reach as the original setting, the Team Leader confirmed this as the official project title. The name reflects the setting's core tension: a civilization that has "settled" across the stars but whose "reach" is ultimately limited by infrastructure it doesn't fully control or understand.
|
||||
- **Repository note:** The repository folder and git history will remain as "commonwealth" for historical continuity and to avoid breaking existing paths. The code name vs official title distinction is acceptable (similar to how game projects often have internal code names).
|
||||
- **Raised by:** Team Leader (Jeroen), following Round 14 worldbuilding discussion.
|
||||
- **Dissent:** None.
|
||||
|
||||
### D-022: Process — Round-based collaboration workflow
|
||||
- **Date:** 2026-02-10
|
||||
- **Decision:** Going forward, discussions are captured directly in round documents at `docs/discussions/round-NN-topic.md` rather than in DISCUSSION.md. DISCUSSION.md has become unwieldy to manage and archive. Qatux must be included in all team interactions (single-agent or multi-agent) to document discussions.
|
||||
- **Rationale:** DISCUSSION.md grew to 26,000+ tokens and became clunky to archive. Direct round document creation is cleaner and more maintainable. Qatux's inclusion ensures no decisions or context are lost.
|
||||
- **New workflow:**
|
||||
1. Create round document at `docs/discussions/round-NN-topic.md`
|
||||
2. Document collaboration within that file
|
||||
3. Extract decisions to appropriate domain file in `decisions/`
|
||||
4. Update discussions README
|
||||
5. Re-index as needed
|
||||
- **Raised by:** Team Leader (Jeroen).
|
||||
- **Dissent:** None.
|
||||
- **Effective:** Immediately (Round 15 onward).
|
||||
|
||||
### D-040: Wiki taxonomy structure — hierarchical with YAML frontmatter
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** The project maintains a wiki at `wiki/` with a hierarchical directory structure, YAML frontmatter metadata on every entry, and template-driven creation. The structure must be established NOW (project lead directive) and scale from v0.1 (1 system, 1 station, 15 NPCs) to full game (hundreds of systems, thousands of NPCs).
|
||||
- **Directory structure:**
|
||||
- `wiki/_templates/` — entry templates (star-system, station, district, location, character, faction, technology, cultural-group, contraband-type, lore-entry, institution, species, event, concept)
|
||||
- `wiki/star-systems/` — spatial hierarchy (system → station → district → location)
|
||||
- `wiki/characters/` — flat structure (characters move between locations)
|
||||
- `wiki/factions/` — political and institutional bodies
|
||||
- `wiki/technology/` — technology categories with tier sub-entries
|
||||
- `wiki/cultural-groups/` — cultures, subcultures, movements
|
||||
- `wiki/contraband/` — illegal/restricted goods
|
||||
- `wiki/lore/` — historical events, concepts, cosmology
|
||||
- `wiki/concepts/` — game-mechanical concepts with lore basis
|
||||
- `wiki/_meta/` — naming conventions, style guide, cross-reference index
|
||||
- **Design principles:** (1) Game-first, not encyclopedia-first — every entry serves the content pipeline. (2) Hierarchical with cross-references via IDs, not file paths. (3) Metadata-rich YAML frontmatter enabling programmatic queries. (4) Template-driven — new entries follow category templates. (5) Every entry has a `status` field: `proposed` → `draft` → `canonical`.
|
||||
- **Governance:** Miri owns wiki structure (new categories, templates, structural decisions). Anyone can create entries within their domain following templates. Qatux maintains the index and cross-references.
|
||||
- **Cross-reference:** Setting ([D-036](content.md#d-036-sova-transit-district--van-maanens-star-system-as-v01-setting))
|
||||
- **Raised by:** Miri (Round 2 proposal with full directory structure and 7 YAML schemas), project lead (non-negotiable, directive #5)
|
||||
- **Dissent:** None
|
||||
|
||||
---
|
||||
|
||||
### D-221: Replace sprint workflow with kanban + milestones
|
||||
- **Date:** 2026-05-03
|
||||
- **Decision:** Sprint-based workflow (38 sprints, Sprint 1–38) replaced by kanban + milestones. Sprint infrastructure deleted from the repo — git history serves as the archive. No rollback provision maintained in the codebase.
|
||||
- **What stays:** Cascade phases (macro direction), agent personalities (divergence engines), D-records, tickets (descriptive not prescriptive), workshops, rules/memory system.
|
||||
- **What changes:**
|
||||
- Sprint boundaries → milestones tied to concrete deliverables (cascade phase, feature gate)
|
||||
- Sprint briefings → live ticket queries (`ticket list --status in_progress` + dependency graph)
|
||||
- Team branches (`sprint-N/team`) → topic branches per logical work unit
|
||||
- File-scope restrictions per team → removed; any agent can touch any file
|
||||
- Version `v0.1.{sprint_number}` → `v0.{phase}.{n}` tied to cascade phases
|
||||
- Si (project manager) → Si (refinement manager) + new clerk agent (institutional guardrail)
|
||||
- `/sprint-start` → `/whats-next` (dependency-driven batch selection with parallel Si refinement review)
|
||||
- `/pr-push` → `/pr-process` (author-side review cycle: commit, push, pick up reviewer comments, dispatch fixes)
|
||||
- Milestones are many-to-many with tickets, can run in parallel, can block other milestones
|
||||
- **What dies:** Sprint CLI (`tooling/db/sprint`), sprint skills (`/sprint-start`, `/sprint-plan`, `/sprint-status`), sprint briefing files, sprint close/kickoff ceremonies, team-scoped file restrictions.
|
||||
- **Rationale:** Structural failure modes across Sprints 37–38: ticket-as-contract (agents execute the letter instead of reading the code), artificial delay (ready work parked for "next sprint"), role theater (file-scope restrictions blocking one-liner fixes), order rigidity (stale briefings), locking on bad design (ticket authority overriding code reality), self-review collapse (coding + reviewing in same context window). See Q-096 for full analysis.
|
||||
- **Test plan:** First milestone is Tier 0+1 planet-down-cascade work (6 schema tables + 6 Python importers). Measurement: did work flow or stall? Did removing file-scope restrictions cause chaos? Did tickets-as-description work?
|
||||
- **Source:** Q-096 (raised 2026-04-20, expanded 2026-05-01)
|
||||
- **Raised by:** Jeroen
|
||||
- **Dissent:** None
|
||||
|
||||
---
|
||||
|
||||
*5 decisions. Last updated: 2026-05-03*
|
||||
@@ -0,0 +1,388 @@
|
||||
# Scope Decisions
|
||||
|
||||
What we're building: game concept, design pillars, prototype definition, map specs, POI system.
|
||||
|
||||
---
|
||||
|
||||
### D-001: Build a custom game, not a mod
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** We are building a standalone game, not a Stellaris mod.
|
||||
- **Rationale:** No existing game provides the right combination of character-driven dynasty play, wormhole-centric space map, and deep internal politics that the Settled Reach universe demands. Stellaris gets the map right but characters wrong. CK3 gets characters right but the map wrong. Neither supports wormhole-as-infrastructure as a core mechanic.
|
||||
- **Raised by:** Team Leader (Jeroen), after team debate across Rounds 1-3.
|
||||
- **Dissent:** None. Team unanimously supports after discussion.
|
||||
|
||||
### D-003: The Settled Reach is the first campaign, not the only possible one
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** Build a character-driven space grand strategy *framework/engine*, with the Settled Reach as the first campaign/scenario.
|
||||
- **Rationale:** Avoids locking into one IP. The framework has broader value. The Settled Reach provides a rich, opinionated first use case that forces good design decisions.
|
||||
- **Raised by:** Gore (Transhumanist Fan), endorsed by team.
|
||||
|
||||
### D-005: Core concept - single character, first-person, story-generator
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** The game is a first-person, single-character experience. You select a character at game start and play from their perspective. The world is a rich simulation experienced through one person's keyhole view.
|
||||
- **Supersedes:** D-002 (dynasty grand strategy concept)
|
||||
- **Elevator pitch:** "Pick a character. Step into the Settled Reach. Figure it out."
|
||||
- **Key pillars:**
|
||||
- **Single character selection** - who you pick determines where you start, what you know, what you can do, and what you care about
|
||||
- **Asymmetric information as core mechanic** - you only know what your character knows. Others lie, withhold, reveal. The same world-state looks completely different from different characters
|
||||
- **Rimworld-style story generator** - an AI storyteller paces events for dramatic tension. Structural randomness (who's compromised, where evidence is) set at game start. Dramatic randomness (when things happen) driven by pacing
|
||||
- **Wormhole network** as traversable infrastructure - you physically move through wormholes between locations
|
||||
- **Crisis events emerge from simulation** - not timers, not scripted, but consequences
|
||||
- **Replayability through perspective** - same conspiracy, different character, completely different game
|
||||
- **Design references:** Rimworld (storyteller/systems), Disco Elysium (character-driven investigation), Sunless Skies (atmosphere/travel), King of Dragon Pass (event-driven decisions)
|
||||
- **Raised by:** Team Leader (Jeroen), evolved through Rounds 4-6 with full team input.
|
||||
- **Dissent:** None. Team unanimously energized by the pivot.
|
||||
|
||||
### D-002: Dynasty grand strategy concept [SUPERSEDED]
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** Original concept was a dynasty-based grand strategy game where the player controls a family/faction across generations.
|
||||
- **Superseded by:** [D-005](#d-005-core-concept---single-character-first-person-story-generator) (single character, first-person concept)
|
||||
- **Rationale for change:** The dynasty model spread the player's attention across multiple characters, diluting the information asymmetry mechanic. Single-character perspective makes "what you know" the central gameplay tension.
|
||||
|
||||
### D-006: Prototype scenario — Institute/Armstrong/Guardians [SUPERSEDED]
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** The first playable prototype focuses on the Starflyer conspiracy arc, scoped to the investigative/political hub: the Institute, Armstrong City, and the Guardians of Selfhood. This tests the core mechanic (asymmetric information in a conspiracy) with controllable scope.
|
||||
- **Rationale:** The conspiracy arc IS asymmetric information. If it's not compelling at this scale, a galaxy won't fix it. If it works, everything else is expansion.
|
||||
- **Raised by:** Team Leader (Jeroen).
|
||||
- **Superseded by:** [D-027](#d-027-vertical-slice--smuggler--detective-two-character-proof) (smuggler + detective vertical slice, 2026-02-10)
|
||||
|
||||
### D-007: Five pillars of game design
|
||||
- **Date:** 2026-02-08
|
||||
- **Decision:** The game rests on five core design pillars. All systems must serve at least one.
|
||||
- **Pillars:**
|
||||
1. **Characters & Information** - who you are, what you know, who you know. Asymmetric information is the master mechanic.
|
||||
2. **The Wormhole Network** - where you go, how you move through the world. Physical traversal of infrastructure.
|
||||
3. **Society & Factions** - the political landscape you navigate from inside, not above.
|
||||
4. **Crisis & Storyteller** - what the world throws at you and when. Rimworld-style AI pacing with structural + dramatic randomness.
|
||||
5. **Action & Spectacle** - what happens when it all goes loud. The punctuation, not the sentence.
|
||||
- **Raised by:** Gestalt (pillars 1-4), Team Leader (pillar 5, citing Rimworld's shooter pedigree).
|
||||
|
||||
### D-013: Diegetic insert/POI navigation system
|
||||
- **Date:** 2026-02-09
|
||||
- **Decision:** The player's map interface is diegetic - it IS the character's neural insert (Settled Reach technology). Not a game UI bolted on, but the character literally checking their implant's navigation overlay. Points of interest appear on the map only when learned through gameplay.
|
||||
- **How POIs are learned:**
|
||||
- Character background (starting knowledge based on who you are)
|
||||
- NPC interactions (contacts send locations, tips, "meet me here" pins)
|
||||
- Research (unisphere searches, case files, institutional databases)
|
||||
- Physical discovery (finding something while exploring)
|
||||
- **Different characters see different maps:** A cop sees flagged locations from case files. A Guardian sees safehouses and dead drops. A Senator sees political venues. Same city, different POI layer.
|
||||
- **POIs can be manipulated:** Tips can be traps. Locations can be outdated. Information channels through the insert system carry the same trust/deception dynamics as verbal information.
|
||||
- **Anti-Ubisoft:** No "climb tower to reveal icons." Map fills at the pace of investigation. Early game: sparse, frightening. Late game: dense, and you realize how much you missed.
|
||||
- **Cross-reference:** Perception mode overlay in [D-017](perception.md#d-017-perception-modes-as-character-build-system). Time display on insert in [D-031](architecture.md#d-031-time-system--game-clock-and-day-phases).
|
||||
- **Raised by:** Team Leader (Jeroen) proposed borderless + anchoring concept. Miri confirmed canon basis. Full team contributed mechanics.
|
||||
|
||||
### D-014: v0.1 map specification [SUPERSEDED]
|
||||
- **Date:** 2026-02-09
|
||||
- **Superseded by:** [D-114](#d-114-v02-proof-of-life--generator--graphics-not-hand-built-slice) (generator-first proof-of-life replaces hand-built map spec; auto-generated locations at scale replace the hand-crafted tile map approach)
|
||||
- **Decision:** First playable tech demo map spec:
|
||||
|
||||
| Layer | Spec |
|
||||
|-------|------|
|
||||
| World map | 3 worlds (Hub/Capital/Fringe), node graph with wormhole connections |
|
||||
| Local maps | 1 per world, ~150x150 tiles, 2-3 z-levels, chunk-based |
|
||||
| Key locations | 5-8 hand-crafted buildings/rooms per world embedded in procedural space |
|
||||
| Ambient fill | Procedural from templates (district types vary per world) |
|
||||
| Wormhole gates | Physical locations on local map, observable/traversable, social chokepoints |
|
||||
| Fog | LOS-based shadowcasting with vision cone (forward/peripheral/blind), fog returns on departure |
|
||||
| Sound | Stereo close-range + visual fog-edge indicators for medium range |
|
||||
| Navigation | Diegetic insert minimap - dots when close, border arrows for known distant POIs |
|
||||
| Camera | Locked to character, no panning, no rotation in v0.1 |
|
||||
| Monologue | Internal character voice for non-visual perception, atmosphere, diegetic hints |
|
||||
| Perception | Natural vision + basic audio only. Thermal/cameras/tracking deferred to milestones |
|
||||
| NPCs | ~15 total across all worlds, on schedules, moving between locations |
|
||||
| Art | Functional boxes with labels. Atmosphere carried by monologue and interaction models. |
|
||||
|
||||
- **Raised by:** Full team across Rounds 8-10.
|
||||
|
||||
### D-027: Vertical slice — smuggler + detective, two-character proof [SUPERSEDED]
|
||||
- **Date:** 2026-02-10
|
||||
- **Superseded by:** [D-114](#d-114-v02-proof-of-life--generator--graphics-not-hand-built-slice) (generator-first proof-of-life) and [D-117](#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) (tycoon bookmark replaces smuggler + detective; zero investigation content for v0.2)
|
||||
- **Decision:** The proof-of-concept vertical slice is one station district containing: 1 workplace social site, 1 social venue (bar), 1 smuggling ring template, shared NPCs. Two playable characters: smuggler (logistics worker, insider access to criminal templates, social camouflage) and detective (institutional investigator, authority access, analytical). Success criteria: (1) 30 minutes of daily-life breathing room before contamination activates, (2) both playthroughs feel like fundamentally different games, (3) after each playthrough player names an NPC they felt conflicted about, (4) the observe→notice→follow→discover sequence emerges from systems not scripts.
|
||||
- **Supersedes:** [D-006](#d-006-prototype-scenario--institutearmstrongguardians-superseded)
|
||||
- **Rationale:** Smuggler + detective creates adversarial divergence — the detective's target IS the smuggler's daily life. Same templates, same NPCs, inverted relationships. Proves character-as-lens, contamination, life-sim attachment, and replayability simultaneously. Tyre confirms: ~20% more effort than single-character, no new architecture.
|
||||
- **Raised by:** Team Leader (smuggler+detective choice), Nigel (two-character requirement), Ozzie (30-min runway), Gore (emotional criterion), Gestalt (systems criterion)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-038: Audio in v0.1 scope — 8 files via Stable Audio Open
|
||||
- **Date:** 2026-02-11
|
||||
- **Decision:** Audio is included in v0.1 scope. Minimum viable set: 8 AI-generated audio files, produced using Stable Audio Open (self-hosted, free commercial use under $1M revenue). Audio is additive — the game works through text + visuals without it, but audio multiplies atmosphere.
|
||||
- **Audio asset list:**
|
||||
1. `amb_station_base.ogg` — station hum, span gate vibration, ventilation (60-90s loop, global ambient)
|
||||
2. `amb_workplace_layer.ogg` — cargo machinery, scanner pings, distant voices (45-60s, logistics hub overlay)
|
||||
3. `amb_bar_layer.ogg` — conversation murmur, glass sounds, low Meridian music (45-60s, bar overlay)
|
||||
4. `amb_corridor_layer.ogg` — echoing footsteps, ventilation whistle, louder gate hum (45-60s, corridor overlay)
|
||||
5. `sfx_footstep_metal.ogg` — single footstep on metal grating (0.3-0.5s, walk trigger)
|
||||
6. `sfx_footstep_metal_run.ogg` — faster footstep (0.2-0.3s, run trigger)
|
||||
7. `sfx_monologue_chime.ogg` — soft crystalline tone, "neural lattice firing" feel (0.5-1.0s, monologue appearance)
|
||||
8. `sfx_monologue_chime_urgent.ogg` — sharper variant for contradiction/anomaly observations (0.5-1.0s)
|
||||
- **Architecture:** Event-driven with asset registry + visual fallback. Simulation emits typed sound events; client renders as audio (if asset exists) or visual indicator + monologue trigger (if not). Ambient loops managed separately from event-driven sounds. Monologue chime is a UI sound, not a simulation sound.
|
||||
- **Amendment (2026-02-16, Audio Pipeline Kickoff):**
|
||||
- **Hybrid audio generation approach:** Stable Audio Open (SAO) for sounds >200ms with organic character (footsteps, ambient layers). Manual synthesis for sounds <200ms with precise/digital character (UI clicks, scanner beeps). SAO ceiling ~47s; accept 45s loops with crossfade for ambient layers. The insert-tech/organic split ([D-074](content.md#d-074-audio-aesthetic-identity--insert-tech-vs-organic)) maps to synthesis/generation split.
|
||||
- **Sprint 7 scope expansion:** Ticket #440 expanded from 6 to 8 assets, adding monologue chimes (assets 7-8) as deliberate placeholders with Sprint 8 redo mandate. Chimes are critical for [D-067](perception.md#d-067-recognition-chime-fires-at-onset-of-cognitive-delay) cognitive delay feel but acknowledged as difficult to generate correctly — manual synthesis required for production quality.
|
||||
- **Cross-reference:** Three-range sound model ([D-018](perception.md#d-018-three-range-sound-model)), sound event architecture (Gestalt R2 section 6), audio aesthetic ([D-074](content.md#d-074-audio-aesthetic-identity--insert-tech-vs-organic)), recognition chime ([D-067](perception.md#d-067-recognition-chime-fires-at-onset-of-cognitive-delay))
|
||||
- **Raised by:** Ozzie (Round 1 minimum viable proposal, Round 2 full spec), project lead (confirmed, directives #3 and #9). Amendment raised by Inigo (hybrid approach), endorsed by Tyre.
|
||||
- **Dissent:** Mellanie and Araminta both proposed deferring audio; project lead overruled. Visual sound indicators remain complementary to audio (not replacement).
|
||||
|
||||
### D-039: v0.1 wow moment scope — all 6 moments [SUPERSEDED]
|
||||
- **Date:** 2026-02-11
|
||||
- **Superseded by:** [D-127](content.md#d-127-player-choices-are-the-content--rimworld-model-job-as-rails) (emergent life-sim replaces detective-specific authored wow moments) and [D-136](architecture.md#d-136-first-settled-reach-moment-auto-generated-apartment--insert-activation) (new first moment: apartment + insert activation). The 6 wow moments were designed for the detective/smuggler frame. No detective-specific wow moments in v0.2.
|
||||
- **Decision:** All 6 wow moments identified by Ozzie are in v0.1 scope. The original 4 "essential" moments are promoted to must-have. The 2 "nice-to-have" moments are also promoted to must-have (project lead directive).
|
||||
- **The 6 wow moments (chronological in a 30-minute session):**
|
||||
1. **Arrival** (minute 0-1): Station hum playing, NPCs already moving, first monologue chime. "Where am I? This feels real." Content: opening monologue, station ambient, pre-populated routines.
|
||||
2. **The Character's Eye** (minute 5-15): Monologue flags something the player didn't notice. Urgent chime. "My character is smarter than me." Content: observation monologue + NPC routine deviation.
|
||||
3. **THE FRIEND's Contradiction** (minute 20-25): THE FRIEND in the wrong place, urgent chime, deflection when asked. "I trusted you. What are you doing?" Content: full FRIEND content package + spatial staging.
|
||||
4. **The Divergence Reveal** (second playthrough, minute 5-10): Same room, different colors, different names, different monologue. "I was only seeing HALF of this." Content: all dual-lens content for first location.
|
||||
5. **The News Ticker Gut-Punch**: Same ticker, opposite monologue reactions per character. "The asymmetry in three words." Content: ticker + dual monologue reactions.
|
||||
6. **The Quiet Moment**: Idle in a corridor, unprompted reflective monologue. "I care about this person." Content: 2 monologue lines + time_idle trigger.
|
||||
- **Cross-reference:** Vertical slice criteria ([D-027](#d-027-vertical-slice--smuggler--detective-two-character-proof)), THE FRIEND ([D-034](content.md#d-034-the-friend--production-level-npc-pattern))
|
||||
- **Raised by:** Ozzie (Round 1 identification, Round 2 budget), project lead (all 6 promoted, directive #8)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-051: "Settling is placement" — design principle
|
||||
- **Date:** 2026-02-12
|
||||
- **Decision:** Object density in a space correlates with how settled it is. The bar is full because Lera made it home. Empty corridors are unsettled. Investigation reads placement as intention — every placed tile is someone's decision. The tile-based world (D-043, 64x64px visual tiles on dual-scale grid per [D-066](architecture.md#d-066-dual-scale-grid--05m-simulation-1m-visual-2x-retina-factor)) is thematically load-bearing: stations are literally built from prefab modular construction, so the tile grid IS the construction grid.
|
||||
- **Corollary — "Investigation is archaeology of intention" (Gore):** Reading the tile world is reading decisions. A cargo crate in the wrong place. A personal item in a maintenance corridor. The mundane environment IS the evidence.
|
||||
- **Cross-reference:** Favorite colors ([D-052](perception.md#d-052-character-favorite-colors--object-layer-identification))
|
||||
- **Canonical reference:** `docs/workshops/art-direction-mood-board/workshop-outcomes.md` §1.3, §7
|
||||
- **Raised by:** Gore (both principles), unanimously endorsed.
|
||||
- **Dissent:** None
|
||||
|
||||
### D-053: Movement as stance toggle system
|
||||
- **Date:** 2026-02-13
|
||||
- **Decision:** Movement uses a stance toggle ladder: Sprint / Walk / Careful / Crouch / (Prone future). Toggle-based, not hold-to-activate. Each archetype has a default stance via MovementProfile component (e.g., smuggler defaults to Walk, detective defaults to Walk). All characters have access to all stances. Prone: toggle out only in normal play (must explicitly stand up); future combat allows "hit the deck" quick-entry.
|
||||
- **Stance values (server — ticks per move):**
|
||||
- Sprint: 1 tile/1 tick. Monologue at 40% rate (urgent only). Loud footsteps. Interaction buffer cleared ([D-055](architecture.md#d-055-sprint-explicitly-suppresses-interaction-buffer)).
|
||||
- Walk: 1 tile/2 ticks. Monologue at 100% rate. Normal footsteps. Default stance.
|
||||
- Careful: 1 tile/3 ticks. Monologue at 150% rate + "tell notice bonus." Quiet footsteps. Enhanced eavesdropping via ListeningFocus (stationary_ticks accumulation).
|
||||
- Crouch: 1 tile/4 ticks. Very quiet footsteps. Uses Prone/Seated occupancy layer ([D-054](architecture.md#d-054-tile-based-movement-with-same-tile-occupancy)).
|
||||
- Prone: Future. Minimal noise. Toggle-out only.
|
||||
- **Client throttle (ms between commands):** Sprint=200ms (5/s), Walk=400ms (2.5/s), Careful=600ms (~1.7/s), Crouch=800ms (1.25/s). Prevents input flooding; server cooldown remains authoritative. Tuned via playtesting: 5 tiles/sec feels like a flat-out sprint, 2.5/sec is a comfortable walk.
|
||||
- **Input model:** Hold-to-move (polled each frame), discrete actions on press. Composite diagonals via simultaneous keys (W+D → northeast). See `client/scripts/autoloads/input_mapper.gd`.
|
||||
- **Perception coupling:** Sprint suppresses interpretation (monologue), not data (overlays still render). Careful enhances observation. Composable via multiplicative formula: `movement_modifier * perception_load_modifier`. All stances: NO vision cone change — perception change is cognitive, not sensory.
|
||||
- **Emergent tactics:** Sprint ahead to get position → Careful to wait and observe → Walk when target passes. Speed modes compose into surveillance patterns.
|
||||
- **v0.1:** Sprint, Walk, Careful, Crouch. Prone deferred.
|
||||
- **Cross-reference:** Tile-based movement ([D-054](architecture.md#d-054-tile-based-movement-with-same-tile-occupancy)), sprint suppression ([D-055](architecture.md#d-055-sprint-explicitly-suppresses-interaction-buffer)), sound model ([D-018](perception.md#d-018-three-range-sound-model))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Lead (stance toggle, final call), Gestalt (Walk/Sprint/Careful triad + perception coupling), Dudley (MovementProfile + tick values), Ozzie (perception gradient), Nigel (character-defining speed)
|
||||
- **Dissent:** None after lead call.
|
||||
|
||||
### D-065: Smuggler inventory — knowledge-primary with physical evidence [SUPERSEDED]
|
||||
- **Date:** 2026-02-13
|
||||
- **Superseded by:** [D-117](#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) (no smuggler character in v0.2). The knowledge-primary inventory concept and physical evidence design survive as patterns for future character implementation.
|
||||
- **Decision:** Knowledge is the primary "inventory" for all characters (you SAW the manifest, not you HAVE it). The smuggler additionally gets a minimal physical inventory for v0.1: 3 specific items (manifest copy, corridor access token, personal comm log). Capacity per archetype: smuggler 3-4 slots, detective 2 slots. Carried items are PRIVATE — they exist behind the information boundary ([D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline) principle 2) and are not visible to other entities unless revealed via search, scan, or confrontation. Server implementation: world entities with CarriedBy component. Verbs: Take, Place.
|
||||
- **Evidence presentation differs by archetype:** Detective sees case-file-style entries (structured: what/where/when/source/confidence, insert suggests links). Smuggler sees personal notebook (organized by person, informal voice, no contradiction flags). Same underlying knowledge graph, different presentation layer.
|
||||
- **v0.1 items (Paula):**
|
||||
1. Manifest copy — proves cargo discrepancy. Leverage proof (smuggler's word doesn't carry institutional weight).
|
||||
2. Corridor access token — proves ring membership. Physical proof of social network position.
|
||||
3. Personal comm log — bridge between KG knowledge and provable leverage. Recorded conversations.
|
||||
- **UI:** Pocket icons, bottom-right of screen, 40x40px. No empty slots displayed — icons appear only when items are carried.
|
||||
- **Rationale:** Smuggler's word doesn't carry institutional weight — they need tangible proof for leverage. Detective's word IS evidence (institutional authority), so they're mostly KG-only. Three items demonstrate the risk/reward concept and differentiate the smuggler's gameplay loop. Contraband carried on person can be detected if scanned by security.
|
||||
- **Cross-reference:** Knowledge graph ([D-041](architecture.md#d-041-knowledge-graph-data-model)), information boundaries ([D-010](architecture.md#d-010-multiplayer-ready-architectural-baseline)), vertical slice ([D-027](#d-027-vertical-slice--smuggler--detective-two-character-proof)), contraband ([D-037](content.md#d-037-contraband-specification))
|
||||
- **Source:** Control & Interaction Workshop (2026-02-13)
|
||||
- **Raised by:** Lead (smuggler needs inventory), Paula (three items + presentation split), Gestalt (knowledge-primary framework), Tyre (minimal implementation: SmallVec<3>), Dudley (server model: BTreeMap + info boundary)
|
||||
- **Dissent:** Tyre initially argued zero physical items in v0.1 (saves 3-4 sprints). Adapted with minimal implementation after lead directive.
|
||||
|
||||
### D-087: v0.1 triangle configuration — 3 active forks, 2 passive tensions [SUPERSEDED]
|
||||
- **Date:** 2026-02-12
|
||||
- **Superseded by:** [D-122](content.md#d-122-all-npcs-generated--no-named-hand-authored-characters) (all NPCs generated; no named triangles with hand-authored characters) and [D-117](#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) (no investigation-specific triangle configuration for v0.2). Triangle generation follows the generator-first model (D-114).
|
||||
- **Decision:** v0.1 vertical slice uses 5 relationship triangles. Three are active forks (T1: Kael-Smuggler-Ring, T2: Sera-Detective-Commission, T4: Drin-System-Ring) with branching outcomes driven by player observation. Two are passive tensions (T3: Naia-Kael-Hael, T5: Worried Partner background) that provide atmosphere and secondary discovery paths. Active forks require authored content per branch. Passive tensions are system-driven.
|
||||
- **Rationale:** Three active forks are within v0.1 content authoring capacity. Passive tensions require no branching content — they enrich discovery space without multiplying authored lines.
|
||||
- **Raised by:** Gestalt, Paula
|
||||
- **Dissent:** None
|
||||
- **Source:** v0.1 Content Scoping Workshop, Round 2 synthesis
|
||||
- **Cross-reference:** D-027 (vertical slice), D-034 (THE FRIEND pattern)
|
||||
|
||||
### D-089: Self-contained triangle forks for v0.1, no cross-triangle cascade [SUPERSEDED]
|
||||
- **Date:** 2026-02-12
|
||||
- **Superseded by:** [D-117](#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) and [D-122](content.md#d-122-all-npcs-generated--no-named-hand-authored-characters). No hand-authored triangle forks in v0.2; triangle generation follows the generator-first model. Cross-triangle cascade design is preserved as a future consideration once the generator proves relationships are readable.
|
||||
- **Decision:** In v0.1, each triangle fork resolves independently. No triangle outcome triggers escalation in another triangle. Cross-triangle cascade (storyteller-managed, where resolving T1 affects T2 pressure) is deferred to v0.2+. This keeps v0.1 content authoring manageable — each triangle is a self-contained narrative unit.
|
||||
- **Rationale:** Cross-triangle cascade requires the storyteller to track inter-triangle state and authors to write contingent branches. Both are out of scope for v0.1. Self-contained triangles can be authored, tested, and validated independently.
|
||||
- **Raised by:** Paula, Gestalt
|
||||
- **Dissent:** None
|
||||
- **Source:** v0.1 Content Scoping Workshop, Round 2 synthesis
|
||||
- **Cross-reference:** D-087 (triangle configuration), D-027 (vertical slice)
|
||||
|
||||
### D-091: Complicity as named thematic core [SUPERSEDED]
|
||||
- **Date:** 2026-02-12
|
||||
- **Superseded by:** [D-132](content.md#d-132-dual-scale-consequence-model--rimworld-sharp-events-and-df-slow-accumulation) (consequence replaces complicity as the primary experiential frame — Gore's reframe, Where's the Fun? Workshop convergence). The detective/smuggler frame that gave "complicity" its specific meaning has been replaced by the life-sim frame (D-117). All careers produce consequence at dual scales; complicity was archetype-specific to the detective/smuggler lens.
|
||||
- **Decision:** The game's thematic identity is complicity — not conspiracy, not detection, not information asymmetry (which is the mechanical core per D-007). The player becomes complicit through observation: seeing something means choosing whether to act on it. The smuggler is complicit in the ring's operations. The detective is complicit in the institution's blindness. Both discover they are already entangled before they choose to be. This framing governs narrative design, wow moment emotional targets (D-039), and the Divergence Reveal (D-027 criterion 4).
|
||||
- **Rationale:** "Complicity" names the emotional experience that information asymmetry produces. It distinguishes this game from pure detective games (you uncover truth) and pure action games (you do things). Here: you watch, and the watching implicates you.
|
||||
- **Raised by:** Gore
|
||||
- **Dissent:** None
|
||||
- **Source:** Wiki Review Workshop, Gore Round 2 proposal, confirmed by lead interview
|
||||
- **Cross-reference:** D-007 (five pillars), D-039 (wow moments), D-027 (vertical slice)
|
||||
|
||||
---
|
||||
|
||||
### D-114: v0.2 proof-of-life — generator + graphics, not hand-built slice
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The v0.2 proof-of-life milestone is defined as: the generator producing usable output (auto-generated locations at scale with legible characters) plus better graphics. A hand-built vertical slice is explicitly NOT the proof-of-life. The v0.1 lesson: descoping toward a hand-built approach produced the wrong game. v0.2 must first prove the foundational generator can produce usable output, then build the game on top of that foundation.
|
||||
- **Rationale:** v0.1 was built as a detective puzzle game with hand-placed NPCs and dots for characters. The designer's vision is a single-character life sim. The generator-first approach prevents the same mistake — we prove the generative foundation works before committing to content on top of it.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 1
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Supersedes:** [D-027](#d-027-vertical-slice--smuggler--detective-two-character-proof-superseded) (hand-built vertical slice), [D-014](#d-014-v01-map-specification-superseded) (hand-built map spec)
|
||||
|
||||
### D-115: Character creation scoped to skills + bookmark for v0.2
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** v0.2 character creation is limited to two elements: skills (what the character is good at) and bookmark (which starting scenario/location the character inhabits). Family, culture, and religion are deferred from character creation. Culture is available in the game through the starting location (see [D-128](content.md#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture)), not as a creation slider.
|
||||
- **Rationale:** Skills and bookmark are the minimum needed to differentiate playthroughs. Adding family/culture/religion at creation gates content that is better delivered through gameplay. Religion in particular is NOT a game system (D-116).
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 2
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-128](content.md#d-128-culture-implicit-in-starting-location--van-maanens-star-system-equals-van-maanens-star-culture) (culture implicit in location)
|
||||
|
||||
### D-116: Religion is not a game system
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** Religion is not a game system in The Settled Reach. It was mentioned as a reference point for the cultural richness of CK3, not as a design requirement. Religion is not a character creation axis, not a faction mechanic, not a dialogue filter, and not a storyline driver.
|
||||
- **Rationale:** The reference to religion in workshop discussions came from CK3 influence. The Settled Reach's mechanical identity is economic + social + information asymmetry, not religious politics. Excluding religion from game systems focuses design on the core mechanics.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 3
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-117: Tycoon is the v0.2 bookmark — zero investigation content
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The v0.2 bookmark is the tycoon — a small business owner in Van Maanen's Star. v0.2 ships zero investigation content. The detective and smuggler framing from v0.1 is explicitly abandoned for v0.2. The tycoon naturally blends career models: active management, remote investment via insert (WFH model), and one-off deals (gig model). Investigation content will be revisited when the life-sim foundation is proven stable.
|
||||
- **Rationale:** v0.1's detective/smuggler frame produced the wrong game. The tycoon bookmark is thematically and mechanically richer: economic complicity, life-sim attachment loops, and narrative emergence from everyday decisions. Clean break from investigation content removes the frame that distorted v0.1.
|
||||
- **Source:** Where's the Fun? Workshop, Round 4 Interview, Decision 4
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
- **Supersedes:** [D-027](#d-027-vertical-slice--smuggler--detective-two-character-proof-superseded)
|
||||
|
||||
### D-118: Small business owner starting state — tycoon is aspiration, not starting position
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The tycoon bookmark begins as an existing small business owner, not a mogul. The player starts with a small operation (bar, logistics contract, storage franchise) and grows into a tycoon over time — or sells out and pivots to exploration. The bookmark name "tycoon" describes the aspiration and growth trajectory, not the starting state. A true tycoon starting position would be overpowered and would skip the interesting growth phase.
|
||||
- **Rationale:** Economic complicity and life-sim attachment require a character with something to lose and room to grow. Starting as a mogul eliminates the growth arc and removes economic stakes. The small business owner start grounds the player in a human-scale economic reality before scaling up.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 20
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
### D-119: Generator spike confirmed for Sprint 25 — critical path
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** The Sprint 25 generator spike is the confirmed first deliverable. If the generator cannot produce usable output, nothing else matters. If it can, everything else has a foundation. The generator proof-of-life gates all subsequent v0.2 development. Sprint 25 prerequisites that must exist before or during the spike: zone identity spec (Miri), one culture profile for Van Maanen's Star / Station Sova (Miri), and NpcBlueprint struct design (Tyre). Estimated timeline (Tyre): 7 sprints to proof-of-life playtest (generated location + legible characters + tycoon bookmark from creation to Day 3).
|
||||
- **Rationale:** The v0.1 lesson established that building without a proven generator produces the wrong game. The sprint 25 spike tests whether the generator can produce auto-generated locations at scale with legible characters — the translation risk mitigation before anything else.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 22
|
||||
- **Raised by:** Tyre (proposal), Team Leader (confirmed)
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-114](#d-114-v02-proof-of-life--generator--graphics-not-hand-built-slice) (generator-first proof-of-life)
|
||||
- **Amendment (2026-04-05):** The sequencing described here (Sprint 25 as first deliverable, generator proof-of-life gates all subsequent work) is superseded by [D-166](architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order) (2026-03-24), which establishes a strict 6-phase development cascade. The generator spike falls in Phase 5 (World Generation), not Phase 1. The cascade is the authoritative build order.
|
||||
|
||||
### D-120: No skill ceiling in v0.2 — transhumanist ladder deferred
|
||||
- **Date:** 2026-03-05
|
||||
- **Decision:** Skills have no hard cap in v0.2. The transhumanist ladder (baseline human → Higher → ANA-connected) is a later design layer. v0.2 proves the life-sim loop without skill constraints. The `skill_ceiling` architectural field is preserved in the implementation but not enforced in gameplay until the base game loop is proven.
|
||||
- **Rationale:** Skill ceilings add complexity that is not load-bearing for the v0.2 proof-of-life. The life-sim loop must prove itself first. The transhumanist ladder is a rich design space but belongs in a later iteration when the foundational systems are stable.
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 Interview, Decision 24
|
||||
- **Raised by:** Team Leader (Jeroen)
|
||||
- **Dissent:** None
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
### D-145: Base building DLC — GJ 902 unclaimed moon as player settlement site
|
||||
- **Date:** 2026-03-15
|
||||
- **Decision:** The unsettled system GJ 902 (south_reach, hop 7, K-type dead-end) contains a habitable moon with an iron core orbiting a gas giant. This is deliberately left unclaimed as prep for a future base building DLC where players could claim and settle it. The marginally habitable planet in the same system provides contrast; the moon is the prize.
|
||||
- **Rationale:** Having a genuinely good piece of unclaimed real estate in the star map gives the base building DLC a natural entry point with existing lore context. The dead-end topology and quiet corridor explain why nobody has claimed it yet.
|
||||
- **Source:** Wiki writing session, 2026-03-15
|
||||
- **Raised by:** Jeroen
|
||||
|
||||
---
|
||||
|
||||
### D-146: Character creation preview — tile-scale sprite with heavy zoom
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** The character creation screen shows the player character's game sprite at heavy zoom — the same top-down tile-scale rendering used in gameplay, rendered at high resolution so it holds up when zoomed in. No separate portrait rendering system. Cosmetic choices (hair, clothing, colors) update the zoomed sprite in real time. Rimworld uses this exact approach: the character customisation screen shows the same pawn sprite rendered larger, with clothing/equipment layers visible.
|
||||
- **Rationale:** The tile-scale sprite IS the player's character for the entire game. Showing it zoomed in character creation: (1) sets accurate expectations for in-game appearance, (2) reuses the production sprite/animation pipeline — zero new rendering infrastructure, (3) validates that cosmetic customisation (#619) reads correctly at game scale, (4) keeps #618 as a single client ticket with no visual-team split. A separate portrait system would be a one-off rendering context (different camera, lighting, asset pipeline) that serves no other game feature. "CK3-style" in the bookmark concept refers to the bookmark structure, not the portrait aesthetic. Portraits can be added later as an additive feature if needed.
|
||||
- **Team implication:** Ticket #618 (CK3-style character creation screen) stays as a single `client` team ticket. No split required.
|
||||
- **Source:** Sprint 27 planning pass — Q-WTF-039 resolution
|
||||
- **Raised by:** Tyre (architecture), Paula (narrative), Gestalt (systems), confirmed by project lead
|
||||
- **Dissent:** Ozzie argued for portrait render (emotional attachment). Overruled: tile-scale at heavy zoom provides sufficient character identity without a second rendering pipeline.
|
||||
- **Cross-reference:** [D-115](#d-115-character-creation-scoped-to-skills--bookmark-for-v02) (creation scope), [D-134](architecture.md#d-134-full-character-customisation--hair-clothing-colors-at-tile-scale) (full character customisation), [D-136](architecture.md#d-136-first-settled-reach-moment-auto-generated-apartment--insert-activation) (first game moment), ticket #618 (CK3-style character creation screen)
|
||||
- **Resolves:** Q-WTF-039
|
||||
|
||||
---
|
||||
|
||||
### D-153: Player character not visually distinct from NPCs
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** The player character uses the same 3D models, same body types, same clothing variety, and same uniform outlines as all other characters. The only visual difference between the player character and NPCs comes from what gear the player chose and bought in-game. No protagonist glow, no saturation boost, no special outline color, no distinct tint.
|
||||
- **Rationale:** This is a life-sim, not an action game. The player character is not a hero with a visual aura — they are a person among people. Visual distinctness would undermine the asymmetric information design: the player's privileged knowledge comes from the insert and perception layers, not from being visually flagged in the world. Immersion requires the player to feel like they live in the world, not observe it from above.
|
||||
- **Raised by:** Team Leader (Jeroen) — Sprint 28 Round 1 overrule
|
||||
- **Dissent:** None (Round 1 proposal for protagonist distinction overruled)
|
||||
- **Cross-reference:** [D-154](#d-154-character-outline-is-not-a-relationship-indicator--uniform-dark), [D-149](architecture.md#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites)
|
||||
|
||||
### D-154: Character outline is not a relationship indicator — uniform dark
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** All character outlines are uniform dark gray/black (#1a1a1a) at all times in normal gameplay. The outline is a rendering artifact (inverted hull) — it carries zero semantic information. Relationship information lives on the minimap, name bubbles, and optionally in a dedicated insert/perception mode overlay. The entity relationship color system (D-033) remains valid within the insert/perception mode context but is NOT displayed via the character outline in normal gameplay.
|
||||
- **Rationale:** If outline color encodes relationship, the player must consciously parse color to extract meaning — this competes with the scene's primary readability job (who is where). The insert is the designed channel for relationship and social data. The outline's only job is silhouette separation from the background.
|
||||
- **Amendment note for D-033:** D-033's entity color palette (#4a9ebb, #6bc9a6, etc.) remains valid as an insert/perception mode overlay, not as the default entity rendering. Normal gameplay shows uniform dark outlines only.
|
||||
- **Raised by:** Team Leader (Jeroen) — Sprint 28 Round 1 overrule
|
||||
- **Dissent:** None (Round 1 proposal for relationship-colored outlines overruled)
|
||||
- **Cross-reference:** [D-033](perception.md#d-033-entity-color--relationship-to-player) (amended — perception mode only), [D-150](architecture.md#d-150-character-outline--inverted-hull-method)
|
||||
|
||||
### D-155: Character editor rotation — cardinal directions only, no free-spin
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** The character creation/editor screen allows rotation of the character preview using N/E/S/W cardinal direction buttons only. No free-spin (drag to rotate). The four directions match the four client visual groups from D-151.
|
||||
- **Rationale:** Free-spin would expose intermediate angles that don't correspond to any in-game facing, giving a misleading preview of how the character will actually look during gameplay. Cardinal directions match the visual groups the player will see in-game and build correct expectations. The isometric cognitive model is reinforced, not undermined, by the editor.
|
||||
- **Raised by:** Team Leader (Jeroen) — Sprint 28 Round 1 overrule
|
||||
- **Dissent:** None (free-spin proposal overruled)
|
||||
- **Cross-reference:** [D-151](architecture.md#d-151-direction-count--8-server-side-facings-4-visual-groups-client-sprint-28), [D-146](#d-146-character-creation-preview--tile-scale-sprite-with-heavy-zoom)
|
||||
|
||||
### D-156: Faction colors are narrative, not a visual compositor concern
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** Faction affiliation is not encoded in character rendering by the compositor. A faction may optionally adopt shared clothing colors as an emergent narrative pattern (members choose to dress alike), but this emerges from character choices — the compositor does not pipeline faction data into color overrides. No "faction color slot" in the compositor API.
|
||||
- **Rationale:** The game is a life-sim with emergent narrative, not an RTS with team colors. Visual homogeneity within a faction can emerge naturally from shared cultural tastes and social norms (via D-147, aesthetic taste trait), not from a forced compositor rule. Hard-coded faction colors would undermine per-character identity.
|
||||
- **Raised by:** Team Leader (Jeroen) — Sprint 28 Round 1 overrule
|
||||
- **Dissent:** None
|
||||
- **Cross-reference:** [D-147](content.md#d-147-aesthetic-taste-as-character-personality-trait--shared-root-for-cosmetic-and-environmental-expression) (aesthetic taste as shared root), [D-149](architecture.md#d-149-3d-characters-rendered-live-in-scene--not-pre-rendered-sprites)
|
||||
|
||||
### D-157: Game start sequence — alarm clock fade from black, not camera pull-back
|
||||
- **Date:** 2026-03-17
|
||||
- **Decision:** The game begins with a **fade from black** + alarm clock sound, the player character waking up in their apartment. The character creation screen is a separate prior context that does not transition directly into gameplay via a cinematic. No camera pull-back from the editor into the game world.
|
||||
- **Rationale:** The first game moment (D-136: auto-generated apartment + insert activation) is a designed experience — an alarm clock wake-up reinforces the life-sim context and grounds the player in their character's daily reality. A camera pull-back from a creation screen to a game world is a cinematic convention from RPGs where the player is a hero arriving somewhere. The Settled Reach player is already somewhere.
|
||||
- **Raised by:** Team Leader (Jeroen) — Sprint 28 Round 1 overrule
|
||||
- **Dissent:** None (camera pull-back proposal overruled)
|
||||
- **Cross-reference:** [D-136](architecture.md#d-136-first-settled-reach-moment--auto-generated-apartment--insert-activation) (first game moment), [D-146](#d-146-character-creation-preview--tile-scale-sprite-with-heavy-zoom) (character creation as separate context)
|
||||
|
||||
### D-158: Frontal camera angle is default for character editor / mugshot UI
|
||||
- **Date:** 2026-03-18
|
||||
- **Decision:** The character editor and mugshot UI use a frontal camera angle (-5° tilt, near eye-level) by default. Three confirmed camera presets: frontal (-5°, editor default), dramatic/low-angle (-30°, gameplay default), overhead (-80°, top-down). ~~Isometric (-45°) superseded — not part of the confirmed set.~~
|
||||
- **Rationale:** Frontal view is the natural angle for inspecting a character's face and outfit in an editor context. Identified during the Quaternius aesthetic spike — the frontal preset immediately felt right for close inspection while the tilted angles serve gameplay readability.
|
||||
- **Raised by:** Jeroen, during spike validation.
|
||||
- **Cross-reference:** [D-146](#d-146-character-creation-preview--tile-scale-sprite-with-heavy-zoom) (character creation as separate context), [D-155](#d-155-character-editor-rotation--cardinal-directions-only-no-free-spin) (editor rotation)
|
||||
|
||||
### D-159: Character body type enum: 5 types × 2 genders + 1 child skeleton (11 total)
|
||||
- **Date:** 2026-03-18 (updated 2026-03-19)
|
||||
- **Decision:** The character system supports 5 body types × 2 genders (10 base meshes) plus 1 gender-neutral child skeleton (11 total). The body types are: **Thin** (ectomorph, narrow), **Average** (regular proportions, canonical/default), **Muscular** (broad shoulders, thick limbs), **Heavy** (wide torso, thick midsection), **Teen** (adolescent proportions). Children use a distinct skeleton with correct child proportions (larger head-to-body ratio, shorter limbs) — not a scaled-down adult. Child gender differentiation comes from animation, not mesh. Elderly is an animation/posture layer on adult bodies (slight stoop, different gait), not a separate body type. Quaternius source kit mapping: Teen→teen, Regular→average, Superhero→muscular. Thin, heavy, and child were auto-scaled forks from the spike (flagged for artist review).
|
||||
- **Rationale:** Identified during the Quaternius aesthetic spike — the standard tier only has 3 body types (Superhero/Regular/Tiny) with no heavy/fat variation and clothing locked per body type. A populated life-sim world needs visually distinct people. 5 types (including teen) gives readable silhouette variety at isometric zoom without exploding the clothing authoring burden (clothing authored on Average, batch-generated for others via Blender Surface Deform). All 11 body type segment GLBs were delivered by the visual team in Sprint 28.
|
||||
- **Raised by:** Jeroen, during spike review. Araminta and Tyre confirmed. Updated during wireframe design to include teen (was missing from original count).
|
||||
- **Cross-reference:** [D-153](#d-153-player-character-not-visually-distinct-from-npcs) (same models for player and NPCs), [D-158](#d-158-frontal-camera-angle-is-default-for-character-editor--mugshot-ui) (editor camera)
|
||||
|
||||
### D-165: Character creator color palette: 5x9 muted hues + 1x9 neutral gray
|
||||
- **Date:** 2026-03-19
|
||||
- **Decision:** The character creation color picker uses a fixed 6×9 (54 swatch) palette plus a hex input field with 9 recent custom color slots persisted at game level. The palette rows are computed from HSL with fixed hue and saturation per row, 9 evenly spaced lightness steps (L=18→76% for chromatic rows). Row layout:
|
||||
1. **Reds** H=0° S=35%: `#3d1d1d` `#522727` `#673131` `#7f3d3d` `#974848` `#af5959` `#bc7575` `#c99090` `#d7acac`
|
||||
2. **Greens** H=150° S=28%: `#213a2d` `#2c4e3d` `#37614c` `#43785e` `#508f70` `#62a684` `#7cb599` `#96c4ad` `#b0d2c1`
|
||||
3. **Blues** H=215° S=35%: `#1d2b3d` `#273952` `#314867` `#3d587f` `#486997` `#597daf` `#7593bc` `#90a8c9` `#acbed7`
|
||||
4. **Purples** H=275° S=28%: `#30213a` `#402c4e` `#503761` `#624378` `#75508f` `#8a62a6` `#9d7cb5` `#b196c4` `#c4b0d2`
|
||||
5. **Browns** H=28° S=35%: `#3d2c1d` `#523b27` `#674a31` `#7f5c3d` `#976d48` `#af8159` `#bc9675` `#c9ab90` `#d7c0ac`
|
||||
6. **Neutral grays** R=G=B even steps: `#000000` `#1f1f1f` `#3f3f3f` `#5f5f5f` `#7f7f7f` `#9f9f9f` `#bfbfbf` `#dfdfdf` `#ffffff`
|
||||
- **Rationale:** Art direction reference is Invisible Inc — muted, desaturated, adult. No primary colors. Palette covers practical clothing colors (workwear, jumpsuits, military surplus) without flashy tones. Players who want exact colors use the hex field; recent custom colors persist across character creation sessions at the game (save) level. HSL computation ensures each row stays in its hue family from dark to light with no drift.
|
||||
- **Raised by:** Jeroen, during character creation wireframe design.
|
||||
- **Cross-reference:** [D-155](#d-155-character-editor-rotation--cardinal-directions-only-no-free-spin) (editor rotation), [D-134](architecture.md#d-134-full-character-customisation) (character customisation)
|
||||
|
||||
---
|
||||
|
||||
### D-236: Sol / GJ-0 — player-inaccessible, Atlas highest-level only, deeper Sol is future DLC
|
||||
- **Date:** 2026-05-26
|
||||
- **Decision:** Sol (system `GJ-0`) is permanently **out of player scope.** Three concrete consequences:
|
||||
- **(a) No body-level generation.** All Phase-4+ generation pipelines (founding_age backfill, body skeleton generation, FillChunk, etc.) EXCLUDE Sol bodies entirely. `system_history.settlement_wave = 'origin'` is the gate flag — GJ-0's wiki frontmatter already documents this as a placeholder that flags the system as exceptional, predating the wave taxonomy.
|
||||
- **(b) Atlas highest-level only.** The Atlas renders Sol at its system-level pregenerated map and **nothing more** — no zoom-in, no per-body click-through, no in-world rendering of Sol bodies. The Sol map is a leaf node in the Atlas hierarchy.
|
||||
- **(c) Deeper Sol is a future DLC.** Any treatment that makes Sol *feel like actual Sol* (real Earth/Mars/Luna geography, real history, real political textures) is reserved for a separate, future DLC with its own scope. Explicitly NOT current work.
|
||||
- **Rationale:** Sol carries enormous authorial expectation (real Earth/Mars/Luna geography, real human history). Fudging it would land worse than leaving it sealed. Keeping Sol out of scope keeps the Reach the focus and the realism debt manageable; reserving Sol for a hypothetical DLC keeps the door open without committing to the (massive) job now.
|
||||
- **Implementation:** generation pipelines filter out bodies whose system has `settlement_wave = 'origin'`; the Atlas zoom UI gates Sol at the system map (no body-level navigation panes). Effective immediately on the Phase-4 fill-seam cascade (#1000 founding_age backfill explicitly excludes Sol).
|
||||
- **Raised by:** Jeroen, 2026-05-26 — formalising what was previously implicit in D-223's naming exemption and GJ-0's wiki frontmatter into a single canonical scope rule.
|
||||
- **Cross-reference:** [D-145](#d-145-base-building-dlc--gj-902-unclaimed-moon-as-player-settlement-site) (DLC-scoping precedent), [D-191](architecture.md#d-191-atlas-of-the-reach--phase-3-scope-and-pipeline) (Atlas Phase-3 — this constrains Sol's Atlas treatment), [D-223](architecture.md#d-223) (Sol naming exemption + offline `sol_import.py` geometry — this generalises that scope), [D-171](economics.md#d-171-three-currency-system) / [D-174](economics.md#d-174-shadow-economy-layer) (Sol-as-shadow-currency — orthogonal, unaffected), GJ-0 wiki frontmatter (`settlement_wave: origin`, `political_zone: earth_sphere`).
|
||||
- **Dissent:** None
|
||||
|
||||
---
|
||||
|
||||
*35 decisions (26 active, 9 superseded). Last updated: 2026-05-26 (D-236 added — Sol player-access scope)*
|
||||
@@ -0,0 +1,430 @@
|
||||
# Open Questions — Architecture
|
||||
|
||||
Technical foundation questions: engine, protocols, data structures, performance, save/load.
|
||||
|
||||
---
|
||||
|
||||
### Q-001: Game engine selection
|
||||
- **Status:** Resolved → [D-020](../decisions/architecture.md#d-020-engine-and-architecture-selection--godot-client--rust-simulation-via-subprocessipc)
|
||||
|
||||
### Q-006: Multiplayer or single-player only?
|
||||
- **Status:** Resolved → [D-009](../decisions/architecture.md#d-009-multiplayer---design-for-it-build-single-player-first)
|
||||
|
||||
### Q-009: Time system
|
||||
- **Status:** Resolved → [D-031](../decisions/architecture.md#d-031-time-system--game-clock-and-day-phases)
|
||||
|
||||
### Q-018: Shadowcasting algorithm selection
|
||||
- **Status:** Resolved → [D-238](../decisions/perception.md#d-238-symmetric-shadowcasting-albert-ford-selected-for-los-computation)
|
||||
- **Question:** Which line-of-sight algorithm should be used? Symmetric shadowcasting (Albert Ford) vs recursive shadowcasting. Both are proven but differ in symmetry properties (symmetric: if A sees B, then B sees A) and implementation complexity. Requires benchmarking at 150x150 map scale with 30 entities to validate performance within 100ms tick budget.
|
||||
- **Context:** D-011 mandates LOS shadowcasting for fog of perception. Architecture review identified this as unspecified (audit section 2.2). Critical for Sprint 2 perception pipeline.
|
||||
- **Assigned to:** Tyre, Dudley
|
||||
- **Source:** Architecture Review Audit 2026-02-11
|
||||
|
||||
### Q-019: Entity ID stability strategy
|
||||
- **Status:** Partially resolved → [D-041](../decisions/architecture.md#d-041-knowledge-graph-data-model)
|
||||
- **Resolution:** Server-side: `StableEntityId` component + `EntityRegistry` resource provides bidirectional `StableId(u64) <-> Entity` mapping. StableId assigned once at entity spawn, never changes, persists across save/load. Knowledge graphs reference StableId, not bevy Entity. Client-side mapping (Godot StableId -> scene node lifecycle) remains open.
|
||||
- **Remaining:** Client-side entity lifecycle management, scene node mapping strategy.
|
||||
- **Date partially resolved:** 2026-02-11
|
||||
- **Assigned to:** Tyre, Dudley (client-side portion)
|
||||
- **Source:** Knowledge Graph & Information Boundaries Workshop
|
||||
|
||||
### Q-020: Multi-entity collision resolution
|
||||
- **Status:** Open
|
||||
- **Question:** When two NPCs attempt to move to the same tile on the same tick, what is the resolution policy? Options: first-write-wins (deterministic with system ordering), both fail (conservative), priority-based (e.g., player > NPC, Active tier > Background tier).
|
||||
- **Context:** D-012 defines tile collision. WalkabilityMap exists (server/src/simulation/movement.rs) but handles single-entity validation. Architecture review identified multi-entity collision as unspecified.
|
||||
- **Assigned to:** Gestalt, Dudley
|
||||
- **Source:** Architecture Review Audit 2026-02-11
|
||||
|
||||
### Q-021: Tick budget overflow policy
|
||||
- **Status:** Open
|
||||
- **Question:** When a simulation tick exceeds the 100ms budget, what happens? Options: (1) slow down real-time and preserve determinism (tick completes fully before next), (2) skip ticks and break determinism, (3) cap work per tick and defer to next tick. Must align with D-010 principle 4 (deterministic simulation).
|
||||
- **Context:** D-026 defines 100ms tick budget for Active tier at 10 tps. Architecture review consensus recommendation proposes "slow real-time, don't skip ticks." Needs formal decision.
|
||||
- **Assigned to:** Tyre, Dudley
|
||||
- **Source:** Architecture Review Audit 2026-02-11
|
||||
|
||||
### Q-022: NPC pathfinding cache eviction
|
||||
- **Status:** Open
|
||||
- **Question:** With 80 Active-tier NPCs each caching ~3 pathfinding routes, the cache holds ~240 paths. What is the eviction policy? LRU? Time-based expiration? Fixed size per NPC? How are paths invalidated when walkability changes (doors lock, areas become restricted)?
|
||||
- **Context:** Architecture review identified pathfinding as MEDIUM gap (audit section 2.2). Cache management needs specification regardless of algorithm choice.
|
||||
- **Assigned to:** Tyre, Dudley
|
||||
- **Source:** Architecture Review Audit 2026-02-11
|
||||
|
||||
### Q-023: Debug visualization scope
|
||||
- **Status:** Open
|
||||
- **Question:** What information should the debug overlay display? Candidates: LOS rays, pathfinding waypoints, vision cones, information boundary tags (who knows what), tick timing breakdown, spatial partition grid cells. Dev-only tool, or accessible for mod development?
|
||||
- **Context:** Architecture review (Troblum) identifies debug visualization as missing operational infrastructure. Needed for debugging perception system, information boundaries, and performance issues.
|
||||
- **Assigned to:** Tyre, Stig
|
||||
- **Source:** Architecture Review Audit 2026-02-11
|
||||
|
||||
### Q-029: Save file format design
|
||||
- **Status:** Open
|
||||
- **Question:** What should the long-term save file format look like? Key considerations:
|
||||
1. **Versioning and migration:** How do saves survive across game versions? Schema evolution strategy (field additions, renames, removals). Should saves embed a version number and run migrations on load?
|
||||
2. **Compression:** Raw MessagePack vs compressed (zstd, lz4)? Tradeoff between save/load speed and file size. SaveStateV1 is already MessagePack — does that carry forward?
|
||||
3. **Integrity:** Checksums or signatures to detect corruption? CRC32 header?
|
||||
4. **Metadata header:** Should the file have a readable header (game version, save date, play time, character name) that the loading screen can read without deserializing the full save?
|
||||
5. **Determinism:** D-010 requires deterministic simulation. Can saves capture enough state to resume deterministically, or is approximate resume acceptable?
|
||||
6. **Modding:** Should the format be documented for mod authors? Does it need extension points?
|
||||
7. **Cloud sync:** Any considerations for Steam Cloud or similar? File size limits?
|
||||
- **Context:** Sprint 19 implements a quick-and-dirty save format (D-085 per-game directories, MessagePack serialization from SaveStateV1). This question tracks the thorough design pass for production quality.
|
||||
- **Assigned to:** Tyre, Dudley
|
||||
- **Source:** Team Leader directive (Sprint 19 planning)
|
||||
|
||||
### Q-030: Seed configuration schema
|
||||
- **Status:** Open
|
||||
- **Question:** What artifact records all randomizer decisions at game start? The wiki-review workshop proposed a `seed-state.yaml` capturing: world seed, character selection, pool draws (Tier 1 modules, FRIEND selection, contraband variant), template assignments, NPC trait rolls, triangle configurations, and entanglement pattern. Ticket #394 (seed configuration schema design) exists but the design is open.
|
||||
- **Assigned to:** Tyre, Gestalt
|
||||
- **Source:** Wiki Review Workshop + v0.1 Content Scoping Workshop
|
||||
|
||||
### Q-046: Departure schedule model — departure windows as generator output for docked vessels
|
||||
- **Status:** Resolved → D-108 (MobileChunk Specification)
|
||||
- **Resolution:** `scheduled_departure: Option<SimTick>` in `Docked` state is mandatory generator output. Vessels without departure schedules are an error state. The `Docked` struct must include `docked_since: SimTick` and `scheduled_departure: Option<SimTick>` — these fields must be added at implementation time (absent from Tyre's Round 4 canonical struct).
|
||||
- **Date resolved:** 2026-02-27
|
||||
- **Source:** Generator Architecture Workshop (#562)
|
||||
- **Assigned to:** Tyre + Miri
|
||||
|
||||
### Q-059: PlatformInfo full interface scope
|
||||
- **Status:** Resolved → [D-141](../decisions/architecture.md#d-141-platforminfo--client-side-os-abstraction-autoload)
|
||||
- **Question:** What properties should `PlatformInfo` expose beyond power state, memory, and file paths?
|
||||
- **Resolution:** 23 properties across 7 categories (power, memory, CPU, GPU, platform identity, display, locale), 1 signal (`power_profile_changed`), 2 methods (`refresh_memory`, `get_diagnostics`). Researched Unity SystemInfo, Unreal FPlatformMisc, SDL3. Skip: GPU VRAM (not available in Godot), CPU frequency, audio devices (AudioManager owns that), network connectivity (single-player), VM detection. Add properties only when a ticket needs them — no stubs. `get_diagnostics()` returns flat Dictionary for bug reports.
|
||||
- **Date raised:** 2026-03-13
|
||||
- **Date resolved:** 2026-03-13
|
||||
- **Assigned to:** Tyre
|
||||
- **Source:** Sprint 26 client work (#646, #659)
|
||||
|
||||
### Q-060: Can Surface Deform produce acceptable clothing at extreme body types?
|
||||
- **Status:** OPEN
|
||||
- **Question:** The Surface Deform batch pipeline runs and produces output, but visual quality at extreme body types (heavy, thin) has not been verified at gameplay or mugshot zoom. Does the clothing mesh hold its shape when Surface Deform stretches it to fit a heavy body?
|
||||
- **Date raised:** 2026-03-19
|
||||
- **Source:** Quaternius aesthetic spike — clothing pipeline validation
|
||||
- **Cross-reference:** D-162
|
||||
|
||||
---
|
||||
|
||||
### Q-063: Footstep VFX system (Godot Asset Library #4122)
|
||||
- **Status:** Open
|
||||
- **Question:** Integrate the Footsteps asset (https://godotengine.org/asset-library/asset/4122) into the character visual system. Jeroen wants this in the game. Evaluate: how does it hook into the animation system? Does it work with our toon shader pipeline? Should footstep triggers be animation events or raycast-based?
|
||||
- **Cross-reference:** D-149 (3D characters rendered live), D-160 (body segments)
|
||||
|
||||
---
|
||||
|
||||
### Q-064: 3D planet generator for wiki system screenshots
|
||||
- **Status:** Resolved — answered by #779 (Sprint 32)
|
||||
- **Question:** Evaluate the Godot 3D Planet Generator (https://github.com/remijean/godot-3d-planet-generator) for generating unique planet visuals per star system in the wiki. Each of the 301 systems could get a procedurally generated planet rendered as a screenshot for its wiki page. Key questions: can we get enough visual variety across 301 systems (different biomes, atmospheres, colors, ring configurations)? Can the generator run headlessly for batch rendering? What's the parameter space — how many distinct-looking planets can it produce? Could the planet configs be seeded from system properties (star class, habitable zone, etc.) for consistency across regenerations?
|
||||
- **Resolution:** Pure Python ray-sphere renderer (`spikes/planet-renders/generate_planets.py`) replaces the Godot plugin approach. Answers all evaluation criteria: (1) visual variety via planet_class type × body_id seed = 301 distinct renders, (2) fully headless — no Godot required, ~2s for all 7 types, (3) seeded from system properties for reproducibility. Avoids headless Godot rendering complexity. See `docs/design/planetary-screenshots-spec.md`.
|
||||
- **Cross-reference:** Wiki system pages (docs/wiki/), world generation pipeline
|
||||
|
||||
---
|
||||
|
||||
### Q-065: Shooting mechanics — Deep RayCast 3D vs Ballistic Penetration System vs server-side
|
||||
- **Status:** Open
|
||||
- **Question:** Evaluate approaches for projectile/hitscan combat mechanics. Three options: (a) Deep RayCast 3D (https://godotengine.org/asset-library/asset/4464) — penetrating raycasts through multiple objects, chain hits, laser effects. (b) Ballistic Penetration System (https://godotengine.org/asset-library/asset/4356) — physics-based damage reduction through materials (thickness, hardness, penetration depth). (c) Roll our own server-side in Rust/bevy_ecs since combat is server-authoritative. Key question: should hit detection and damage calculation live on the client (these plugins) or the server (D-010 server authority)? Could the client use these for visual feedback (tracer rendering, impact effects) while the server handles the authoritative hit/damage calculation?
|
||||
- **Cross-reference:** D-010 (server-authoritative simulation), D-012 (client is a view)
|
||||
|
||||
---
|
||||
|
||||
### Q-066: PathMesh3D for procedural environment geometry
|
||||
- **Status:** Open
|
||||
- **Question:** Evaluate PathMesh3D (https://godotengine.org/asset-library/asset/3626) — extrudes 2D profiles along 3D paths at runtime to create meshes. C++ GDExtension, MIT licensed. Potential uses: procedural pipes/cables/wiring in station interiors, rail/track generation, corridor geometry, any environment element that follows a path. Not clear yet where this fits in the pipeline — could be a generator-time tool or a runtime decoration system. Worth investigating when environment procedural generation starts.
|
||||
- **Cross-reference:** Generator architecture, environment asset pipeline
|
||||
|
||||
---
|
||||
|
||||
### Q-067: Vehicle physics for in-world transport
|
||||
- **Status:** Open
|
||||
- **Question:** Evaluate vehicle physics plugins for player/NPC transport between zones. Two candidates: (a) MAdvanced Vehicle System (https://godotengine.org/asset-library/asset/3697) — full car physics with gearbox, AI traffic, traffic management, lights, sounds, steering wheel support. Godot 4.6, MIT, actively updated. (b) Godot Simple Motorcycle Physics (https://godotengine.org/asset-library/asset/4670) — raycast-based motorcycle, simpler scope. Questions: does the game need driveable vehicles or just NPC traffic? Is vehicle movement client-side physics or server-authoritative? The AI traffic and traffic management in MAdvanced could serve NPC vehicle simulation. Scope for v0.2: probably not, but worth tracking for when districts/zones need inter-zone travel.
|
||||
- **Cross-reference:** D-010 (server authority), world generation
|
||||
|
||||
---
|
||||
|
||||
### Q-068: Procedural terrain generation patterns — chunk loading and noise
|
||||
- **Status:** Open (reference/inspiration)
|
||||
- **Question:** Block-based 3D Procedural Map Generation Demo (https://godotengine.org/asset-library/asset/2698) — Perlin noise terrain with chunk-based loading/unloading. Not directly usable (block-based, Godot 4.2) but the patterns are relevant: seed-deterministic generation for consistent worlds across sessions, chunk loading within player proximity for memory/performance, terrain type placement from noise values. Reference for when the world generator produces location terrain and the client needs to stream it. The chunk load/unload pattern maps to our simulation tier system (Active → Background → State-saved).
|
||||
- **Cross-reference:** Generator architecture, D-097 (simulation tiers), D-096 (chunk loading)
|
||||
|
||||
---
|
||||
|
||||
### Q-069: GPU cloth simulation for dynamic clothing
|
||||
- **Status:** Open
|
||||
- **Question:** Evaluate GPU Cloth Simulation (https://godotengine.org/asset-library/asset/4853) — compute shader-based cloth with collisions, turbulence, pinning, inertia. MIT, Godot 4.5. NOT for character clothing (solidify is our look). Best use: environmental dressing — sails on ships, flags, awnings, laundry on lines, market tarps, banners. These are static-anchor cloth meshes that add life to environments without per-body fitting. Evaluate performance cost per cloth instance and max reasonable count per scene.
|
||||
- **Cross-reference:** Character visual system, D-152 (LOD tiers), clothing pipeline
|
||||
|
||||
---
|
||||
|
||||
### Q-070: NobodyWho LLM patterns vs our Rust voice pipeline
|
||||
- **Status:** Open (evaluated, not adopted)
|
||||
- **Question:** NobodyWho (https://docs.nobodywho.ooo/) is a GDExtension providing in-process LLM inference (llama.cpp) with GGUF models. Evaluated against our existing Gemma 2 voice pipeline in server/src/voice/. **Verdict: does not fit D-020** — client-side LLM violates client-as-pure-renderer. Our server-side Rust approach is architecturally correct. **Patterns worth adopting:** (a) tool calling with grammar-enforced structured output — NPC queries game state via typed function calls, guaranteed parseable. (b) Preemptive context shifting for infinite conversations without truncation. (c) GGUF model flexibility (not locked to Gemma 2). These patterns should be evaluated for integration into the Rust voice pipeline, not as a client-side plugin.
|
||||
- **Cross-reference:** D-020 (server authority), server/src/voice/ pipeline, D-010 (determinism)
|
||||
|
||||
---
|
||||
|
||||
### Q-071: Steam integration template for multiplayer lobbies
|
||||
- **Status:** Open (future — Steam/multiplayer stage)
|
||||
- **Question:** Two resources for Steam multiplayer: (a) SteamMultiplayerPeer (https://github.com/expressobits/steam-multiplayer-peer) — the actual networking primitive. Implements Godot's MultiplayerPeer interface over Steam networking (relay, NAT traversal, lobbies). This is the building block we'd use. (b) Steam Template (https://godotengine.org/asset-library/asset/3328) — CC0 template wrapping SteamMultiplayerPeer with menu UI, settings, lobby management. Reference for UI patterns. Key architecture question: our server-authoritative model (D-010, D-020) means the dedicated server runs the simulation. SteamMultiplayerPeer could handle client↔server transport (using Steam relay for NAT traversal) rather than raw TCP/WebSocket. This would give us Steam friend invites, lobby discovery, and relay infrastructure for free. Evaluate when multiplayer work begins.
|
||||
- **Cross-reference:** D-010 (server authority), D-020 (subprocess IPC), Oscar (networking agent)
|
||||
|
||||
---
|
||||
|
||||
### Q-072: BitTorrent for P2P asset/mod/world state distribution
|
||||
- **Status:** Open (future — multiplayer stage)
|
||||
- **Question:** godot-torrent (https://godotengine.org/asset-library/asset/4384) — full BitTorrent protocol as GDExtension, C++ native performance. MIT, Godot 4.5. Potential uses: (a) mod/asset sync between multiplayer clients without central CDN costs — players seed assets to each other. (b) World state distribution — large world snapshots shared P2P rather than server→each-client. (c) DLC/content pack distribution. Key advantage: scales with player count (more players = more seeds = faster). Key risk: NAT traversal, firewall issues, player trust (can you trust torrent-distributed assets?). Would need content verification (hash/signature) to prevent tampering.
|
||||
- **Cross-reference:** Oscar (networking), multiplayer architecture, mod support
|
||||
|
||||
---
|
||||
|
||||
### Q-073: BehaviourToolkit patterns for Rust NPC AI
|
||||
- **Status:** Open (reference — implementation is server-side Rust)
|
||||
- **Question:** BehaviourToolkit (https://github.com/ThePat02/BehaviourToolkit, https://godotengine.org/asset-library/asset/2333) — FSM, Behaviour Trees, Blackboard Resource, nested composition (BT inside FSM and vice versa). MIT. The plugin itself is GDScript/Godot and lives on the wrong side of D-020 for us. But the patterns are directly applicable to the Rust server NPC simulation: (a) Blackboard pattern — shared key-value state between behaviour nodes without coupling, maps to bevy_ecs components. (b) Nested FSM↔BT composition — our NPC state machines (schedule, mood, relationships, job per D-097) could nest behaviour trees for decision-making within each state. (c) Editor interface patterns — how they visualize/debug behaviour trees could inform our server-side tooling. Study the source for architectural patterns, implement in Rust/bevy_ecs.
|
||||
- **Cross-reference:** D-097 (simulation tiers, 4 state machines), Dudley (server developer), NPC behaviour system
|
||||
|
||||
---
|
||||
|
||||
### Q-074: Screenshot manager for in-game captures and bug reports
|
||||
- **Status:** Open
|
||||
- **Question:** Two references for improving the existing F12 bug reporter: (a) ScreenshotManager (https://github.com/ASecondGuy/ScreenshotManager) — better screenshot file management, auto-naming, viewport isolation. (b) BugReporter (https://github.com/ASecondGuy/BugReporter) — patterns for attaching system info, game state snapshots, reproduction steps to bug reports. Both from the same author. Evaluate what patterns we can adopt into our existing bug reporter flow.
|
||||
- **Cross-reference:** `/bug-report` skill, character creator screenshot system
|
||||
|
||||
---
|
||||
|
||||
### Q-075: RichText3D for in-world text rendering
|
||||
- **Status:** Open
|
||||
- **Question:** RichText3D (https://github.com/mszylkowski/rich-text-3d-godot) — renders BBCode to a 3D plane in real time. MIT, performant (renders only on property change, max once per frame). Supports color, bold, italic, images, tables, font size, auto text wrapping. Use cases: in-world signage (shop names, zone labels, directional signs), NPC name/title floating labels, item descriptions on crates/containers, news tickers on station displays, terminal screens. The adjustable resolution (pixels per Godot unit) means text stays readable at our isometric camera angles. Worth evaluating when diegetic UI and in-world text elements are implemented.
|
||||
- **Cross-reference:** Diegetic UI design, in-world interaction system
|
||||
|
||||
---
|
||||
|
||||
### Q-076: DeformableMesh for runtime environment and damage variation
|
||||
- **Status:** Open
|
||||
- **Question:** DeformableMesh (https://github.com/cloudofoz/godot-deformablemesh) — runtime mesh deformation with SphericalDeformer, SimpleDeformer (bend, twist, taper), and DragDeformer nodes. MIT, Godot 4.0+. Use cases: (a) environmental variety from shared meshes — same pipe asset bent differently per instance, twisted metal in damaged zones, wind-bent vegetation/trees. (b) Damage visualization — crushed containers, warped hull plating, dented surfaces. (c) Procedural variation at generator time — deform base assets to create unique instances without authoring each one. The DragDeformer could also serve interactive manipulation (bending objects during gameplay). Low priority but high variety-per-asset value.
|
||||
- **Cross-reference:** Generator architecture, environment asset pipeline, damage system
|
||||
|
||||
---
|
||||
|
||||
### Q-077: World generation architecture → PROMOTED TO WORKSHOP
|
||||
- **Status:** Promoted — see `docs/workshops/world-generation/BRIEF.md`
|
||||
- **Question:** Outgrew Q-record format. All references (CityCrafter3D, Chunk Manager, Retro Terrain, Spatial Gardener, GridMapLayer, PathMesh3D, DeformableMesh, Poly Haven) consolidated into the workshop brief.
|
||||
- **Cross-reference:** `docs/workshops/world-generation/BRIEF.md`
|
||||
|
||||
---
|
||||
|
||||
### Q-078: God rays for atmospheric lighting
|
||||
- **Status:** Open
|
||||
- **Question:** SimplestGodRay3D (https://github.com/AguaMineral/SimplestGodRay3D) — drop-in volumetric light shaft effect. Light streaming through station viewports, between buildings in exterior zones, through tree canopy in rural areas. Low implementation effort, high atmosphere value. Evaluate: does it work with our GL compatibility renderer? Performance cost per instance? Compatible with our toon shader aesthetic or does it look too realistic?
|
||||
- **Cross-reference:** Lighting design, environment atmosphere
|
||||
|
||||
---
|
||||
|
||||
### Q-079: GridMapLayer — 2D tile logic driving 3D grid rendering
|
||||
- **Status:** Open (high relevance)
|
||||
- **Question:** GridMapLayer (https://github.com/Caaz/grid-map-layer) — manages 3D GridMaps through TileMapLayer patterns. MIT, Godot 4.4+. Directly relevant: our server sends 2D tile grid data, the client renders 3D isometric. This plugin bridges that gap — autotiling for 3D tiles using 2D rules, arbitrary subdivisions (2x2+ gridmap tiles per 2D tile), multiple GridTiles per 2D tile (layered grids for collision variation), programmatic tile setting for procedurally generated areas. This could be the rendering layer for server-generated floor plans — the server sends the tile palette + grid, the client uses GridMapLayer with autotiling to render walls, floors, doors with correct 3D tile selection.
|
||||
- **Cross-reference:** D-096 (chunk loading), tile rendering pipeline, server→client tile data
|
||||
|
||||
---
|
||||
|
||||
### Q-080: Mod loader architecture reference
|
||||
- **Status:** Open (reference — future feature)
|
||||
- **Question:** Godot Mod Loader (https://github.com/GodotModding/godot-mod-loader) — community-standard mod loading framework for Godot. Study for architectural patterns: mod discovery and load ordering, dependency resolution between mods, conflict detection, API boundaries (what mods can and can't touch), mod manifest format, hot-reload vs startup-only loading, save compatibility with mods enabled/disabled. We'll roll our own but these patterns are battle-tested across many Godot projects. Key question for our architecture: mods need to work with both the Rust server (gameplay mods, new items, behaviours) AND the Godot client (visual mods, UI mods). The mod loader needs to span both sides of the D-020 boundary.
|
||||
- **Cross-reference:** D-020 (client/server split), mod support, Q-072 (BitTorrent for mod distribution)
|
||||
|
||||
---
|
||||
|
||||
### Q-081: VisionCone3D for client-side fog refinement
|
||||
- **Status:** Open (high priority — solves the 2D→3D fog transition problem)
|
||||
- **Question:** VisionCone3D (https://github.com/Tattomoosa/VisionCone3D) — 3D vision cone raycasting in Godot. MIT, Godot 4.4+. Proposed architecture: (a) Server does authoritative shadowcasting per D-011/D-015, sends visible chunk list in ObserverSnapshot (coarse grid truth). (b) Client uses VisionCone3D to re-trace locally against actual 3D wall geometry within the server-approved visible area. (c) The client's vision cone output drives 3D fog-of-war rendering with smooth, geometry-following edges instead of tile-stepped boundaries. This solves the stepped edge display issue from communicating visibility as grid chunks — the client refines to sub-tile accuracy using real 3D geometry. No information leak: client can only refine within server-approved visible chunks, never see beyond. The cone configuration mirrors the server's D-015 vision cone (forward/peripheral/blind spot zones). Performance tuning options available per the plugin docs.
|
||||
- **Cross-reference:** D-011 (LOS shadowcasting), D-015 (vision cone), D-043–D-049 (fog system), fog_state.gd (current 2D fog implementation)
|
||||
|
||||
---
|
||||
|
||||
### Q-082: VoronoiShatter for destruction effects
|
||||
- **Status:** Open
|
||||
- **Question:** VoronoiShatter (https://github.com/robertvaradan/voronoishatter) — procedural Voronoi fracture of 3D meshes into rigidbody pieces. MIT, Godot 4.4+, native GDScript. Convex and concave mesh support, seamless materials, auto rigidbody generation. Use cases: wall breaches during combat, crate/container destruction, station hull damage, environmental destruction. Pure client-side visual effect — server sends "object destroyed," client shatters the mesh locally. The Voronoi pattern gives natural-looking irregular fractures. Could pre-compute shatter patterns at load time for performance, trigger on damage event.
|
||||
- **Companion:** Particle Scene Compositor (https://github.com/tvenclovas96/particle-scene-compositor) — spawn scene instances as particles. Destruction fragments + sparks/smoke/dust in one effect. Shatter → fragments fly → each fragment emits particles.
|
||||
- **Cross-reference:** Combat system, damage visualization, environment interaction
|
||||
|
||||
---
|
||||
|
||||
### Q-083: ThemeGen for dynamic insert styling and value-level theming
|
||||
- **Status:** Open
|
||||
- **Question:** ThemeGen (https://github.com/Inspiaaa/ThemeGen) — themes-as-GDScript-code with semantic colours, reusable styles, theme variations, and live preview in editor. MIT. Directly relevant to dynamic inserts: (a) Value-level theming — common/uncommon/rare items get different colour palettes from the same base layout. (b) Faction-themed inserts — Frost Compact cold blues, Reach Authority golds, derived programmatically from a base theme. (c) Danger/security level indicators — zone inserts shift colour based on threat level. (d) Player customisation — let players pick an insert accent colour, ThemeGen derives the full palette. The code-based approach means themes can be generated from server data (faction ID → theme variation) without authoring each one.
|
||||
- **Cross-reference:** Diegetic UI / insert system, Stig (UI developer), Araminta (visual design)
|
||||
|
||||
---
|
||||
|
||||
### Q-084: Isometric point-and-click navigation pattern
|
||||
- **Status:** Open
|
||||
- **Question:** Reference: isometric-2d-point-and-click-movement (https://github.com/Domogo/isometric-2d-point-and-click-movement). This is 2D but the interaction pattern applies to our 3D isometric setup: click ground tile → convert screen position to tile coordinate → server pathfinds (A* on tile grid) → client animates character along path. Key problems to solve: (a) mouse→3D isometric tile coordinate conversion (ray from camera through click point to ground plane, accounting for D-148 45° map rotation). (b) Path visualization (preview line showing where character will walk). (c) Click-to-move vs WASD — do we support both? (d) Server roundtrip latency — does the client predict movement or wait for server confirmation? Study for interaction patterns, implement in our 3D stack.
|
||||
- **Design notes:** Character stays center-screen, map scrolls around them (not character moving on static map). Character always faces toward mouse cursor — this creates a natural looking-direction that drives the D-015 vision cone direction. Unresolved: what happens visually when walking one direction while looking backward (walk animation vs facing direction conflict — later solve). Latency: 200ms feels instant in web interactions (Jeroen's rule from web design) — if server roundtrip is under 200ms, click-to-move without client prediction may be acceptable. Needs user testing to verify.
|
||||
- **Cross-reference:** D-148 (camera angle), D-010 (server authority), D-015 (vision cone facing), navigation/pathfinding
|
||||
|
||||
---
|
||||
|
||||
### Q-085: Portal rendering for spatial transitions and viewports
|
||||
- **Status:** Open
|
||||
- **Question:** Portal concept — not the Godot plugin (client doesn't need it — transparency handles adjacent rooms, SubViewport handles remote camera feeds). The SERVER needs portal logic: when the shadowcasting/vision cone hits a door opening, visibility extends through it into the next room. Portals are openings in the tile grid that allow raycasts to pass between rooms/zones. Study the plugin (https://github.com/VojtaStruhar/godot-portals-plugin) for the spatial math patterns, implement in Rust server's visibility system. Key: doors open = portal active = vision extends through. Doors closed = wall = vision blocked.
|
||||
- **Cross-reference:** D-011 (LOS), D-015 (vision cone), z-level system, information boundary design
|
||||
|
||||
---
|
||||
|
||||
### Q-086: Day/night cycle — server time driving client lighting
|
||||
- **Status:** Open
|
||||
- **Question:** Reference: DynamicDayNightCycles (https://github.com/eisclimber/DynamicDayNightCycles). The game time is server-authoritative — server ticks time, sends current time-of-day in ObserverSnapshot. Client renders lighting accordingly. Station interiors: artificial lighting follows schedules (dim at night cycle, full during work shifts). Exterior/rural zones: sun position, sky color, shadow direction from time of day. Station viewports could show star position shifting. NPC schedules already tied to time (D-097 schedule state machine). Key question: how granular is the lighting transition — smooth real-time interpolation or discrete time blocks (morning/afternoon/evening/night)?
|
||||
- **Cross-reference:** D-097 (NPC schedules), environment lighting, server game clock
|
||||
|
||||
---
|
||||
|
||||
### Q-087: Water shader for environment zones
|
||||
- **Status:** Open
|
||||
- **Question:** Godot Realistic Water (https://github.com/godot-extended-libraries/godot-realistic-water) — water rendering with reflections, refraction, waves. May be too realistic for our toon aesthetic — evaluate whether it can be styled down or if a simpler toon water shader is better. Use cases: docking bay water features, hydroponic farms, waste processing, rural rivers/lakes, rain puddles, port zones, fountains. Question: does toon water need reflections or just stylized wave animation + color? The Retro Terrain reference (Q-077) already handles water tile transitions — this adds the surface rendering. Also check if GL compatibility renderer supports the shader features.
|
||||
- **Cross-reference:** Q-077 (world generation / terrain), environment aesthetics, GL compatibility renderer
|
||||
|
||||
---
|
||||
|
||||
### Q-088: Spatial audio for information-aware sound
|
||||
- **Status:** Open
|
||||
- **Question:** spatial_audio_player_3d (https://github.com/Danikakes/spatial_audio_player_3d) — 3D spatial audio with occlusion and environmental awareness. Directly tied to the information system: sound carries information. Footsteps through walls = muffled (you know someone's there but not who). Conversation in the next room = faint/unintelligible (partial information). Gunshot echoes in corridors = direction cues. The server already knows which audio events are in hearing range (part of the ObserverSnapshot). The client needs spatial rendering: distance attenuation, wall occlusion, reverb based on room size/material. Also ties into Inigo's audio design specs. Evaluate whether this plugin handles occlusion raycasting or just basic 3D positioning.
|
||||
- **Cross-reference:** D-011 (LOS — audio equivalent), Inigo (sound designer), information boundary, audio propagation rules
|
||||
|
||||
---
|
||||
|
||||
### Q-089: Procedural star rendering for space viewports and star map
|
||||
- **Status:** Open
|
||||
- **Question:** Godot Starlight (https://github.com/tiffany352/godot-starlight) — procedural starfield rendering. Use cases: (a) Station viewport backgrounds — look out a window, see stars. (b) Star map navigation screen. (c) Docking bay exterior views. (d) Skybox for any exterior/surface zone. Could combine with Q-064 (planet generator) for full space vista — procedural stars + procedural planets visible from station viewports. Seed from system coordinates for consistent views per location.
|
||||
- **Cross-reference:** Q-064 (planet generator), station viewport design, star map UI
|
||||
|
||||
---
|
||||
|
||||
### Q-090: Markov chains for procedural name/text generation in Rust
|
||||
- **Status:** Open
|
||||
- **Question:** Pattern reference: Markov Machine (https://github.com/BirDt/markov-machine) — Markov chain text generation. Need a Rust crate, not the Godot plugin. Candidates to evaluate: `markov` crate, `markov_chain` crate, or hand-roll (Markov chains are ~50 lines of Rust). Use cases: NPC name generation from cultural name pools (train on corridor-specific names, generate plausible new ones), shop/business name generation, procedural signage text, news ticker filler, overheard conversation snippets. Faster and cheaper than LLM for short text that just needs to feel culturally consistent. Could train separate chains per corridor/culture for regional flavor. The existing voice pipeline (Gemma 2) handles dialogue variation — Markov is for the lightweight procedural text that doesn't need semantic coherence.
|
||||
- **Cross-reference:** Generator architecture, name pools, voice pipeline (server/src/voice/)
|
||||
|
||||
---
|
||||
|
||||
### Q-091: Event-driven audio system
|
||||
- **Status:** Open
|
||||
- **Question:** Event Audio (https://github.com/bbbscarter/event-audio-godot) — data-driven event→sound mapping. Game events trigger audio without hardcoded play() calls. Complements Q-088 (spatial audio handles WHERE, this handles WHEN/WHAT). Server sends game events in ObserverSnapshot (door opened, NPC entered, combat started), client maps these to audio via configuration. Inigo's audio design specs define the sound palette — this system is the dispatcher that connects game events to that palette. Evaluate whether we adopt the plugin pattern or build our own event→audio bus.
|
||||
- **Cross-reference:** Q-088 (spatial audio), Q-063 (footsteps), Inigo (sound designer), AudioManager autoload
|
||||
|
||||
---
|
||||
|
||||
### Q-092: Modular settings menu as foundation for #735
|
||||
- **Status:** Open
|
||||
- **Question:** Godot Modular Settings Menu (https://github.com/MarkVelez/godot-modular-settings-menu) — composable settings panels for keybinds, audio, video, accessibility. Evaluate as the foundation for epic #735 (Settings and input system). Instead of building keybind remapper, audio sliders, resolution picker, and controller support from scratch, start from this template and restyle to match our UI aesthetic. Key: the modular approach means we can add/remove panels as features are implemented without restructuring.
|
||||
- **Cross-reference:** Epic #735 (settings/input system), Frame0 wireframe session
|
||||
|
||||
---
|
||||
|
||||
### Q-093: Tile-based exploration map in player insert (Google Maps for the implant)
|
||||
- **Status:** Open (high interest)
|
||||
- **Question:** Reference: MapTileProvider (https://github.com/AngryMeenky/MapTileProvider) — lazy-loading tile map provider. Concept: the player's insert has a map that works like Google Maps — pan, zoom, tile-based rendering. Server generates map tiles from ECS exploration data (what the player has seen). Explored areas show room layouts, corridors, points of interest. Unexplored areas are blank/fogged. Zoom levels: room detail → building → district → zone → station overview. Knowledge-graph-driven overlays: NPC last-known positions (if the player tracked them), quest markers, danger zones, faction territories. Map tiles are server-authoritative (can't see what you haven't explored) and cached on the client. The tile pyramid approach means the map scales to any world size without loading everything at once.
|
||||
- **Cross-reference:** Information boundary (D-011), insert/minimap UI, knowledge graph (D-041), #732 (minimap ticket)
|
||||
|
||||
---
|
||||
|
||||
### Q-094: Chart widgets for economy/market insert UI
|
||||
- **Status:** Resolved — deferred to Phase 3+ (player interaction layer)
|
||||
- **Date resolved:** 2026-04-05
|
||||
- **Resolution:** No player-facing economic UI is in scope for Phase 2. The Phase 2 deliverable is the autonomous simulation ticking on investor screens — no player verbs, no insert UI for market data. Chart widget evaluation (Easy Charts plugin, ThemeGen integration, information boundary application) deferred until Phase 3 when the player interaction layer begins.
|
||||
- **Question:** Easy Charts (https://github.com/fenix-hub/godot-engine.easy-charts) — line charts, bar charts, scatter plots, pie charts in Godot. For the insert UI: (a) commodity price history graphs (X4/EVE-style market view), (b) faction reputation trends over time, (c) supply/demand curves per station, (d) character stat progression, (e) economy health indicators. The diegetic justification: the player's implant has market analytics. Data comes from server via ObserverSnapshot (the player only sees market data they have access to — information boundary applies). Evaluate whether this plugin's visual style can be themed to match our insert aesthetic (ThemeGen Q-083 integration).
|
||||
- **Cross-reference:** Economy system (X4/EVE inspiration), insert UI, Q-083 (ThemeGen), information boundary, [D-181](../decisions/economics.md#d-181-signal-vocabulary) (signal vocabulary — Phase 3 player access)
|
||||
|
||||
---
|
||||
|
||||
### Q-098: Persistence of generated river/city mapping outputs
|
||||
- **Status:** Resolved — D-225 (atlas layer-stream proxy), 2026-05-23
|
||||
- **Resolution:** Resolved against the question's own premise. The viewer does **not** need a durable store under the LRU: the cascade is deterministic and ~45 ms, so eviction → recompute is acceptable. Baking into `systems.db` (option a) is rejected — it bloats the install and makes modded bodies second-class. Decision: **lazy compute on demand**, served by a mod-first **layer-stream proxy** that resolves a body's source files (base + mod dirs) and streams the computed `Layer1Output` over the existing IPC bridge, backed by the D-203 in-memory LRU (miss → background `AnalyzeBody`; eviction → recompute). See [D-225](../decisions/architecture.md#d-225). The mod-content-catalog corner (mods adding *new* body rows / `terrain_reference` to the binary `systems.db`) is spun off to Q-099.
|
||||
- **Question:** The deterministic cascade can recompute river courses (D8 drainage, D-208) and city placements (economic sim + attractor matching, D-211) from seed at any time, so persisting them is a *cost* optimization, not a correctness need. But the compute is expensive — recomputing per session or per atlas view is waste. How are these mapping outputs persisted so they are computed **once per body and kept**? D-203's BodyWorldState cache is an LRU — it *evicts* (volatile). The fork: **(a)** build-time bake into `systems.db` (D-200 build-time tier — precompute all, ship); **(b)** lazy compute + persist at runtime (cache DB / savegame — compute on first visit, keep); **(c)** hybrid. Whatever the answer, the in-memory LRU should sit over a *durable* store so eviction triggers a cheap reload, not a recompute.
|
||||
- **Context:** Raised 2026-05-22 looking ahead from the Phase 4 markers strip (#951). Refines D-200 (three-tier execution) and D-203 (LRU cache). Gates the Atlas layer viewer (#960), which needs persisted mapping to render without recomputing. Determinism (#952) guarantees recompute is always a valid fallback.
|
||||
- **Cross-reference:** [D-200](../decisions/architecture.md#d-200), [D-203](../decisions/architecture.md#d-203), [D-208](../decisions/architecture.md#d-208), [D-211](../decisions/architecture.md#d-211), #952 (determinism harness), #960 (atlas viewer)
|
||||
|
||||
---
|
||||
|
||||
### Q-099: Mod content catalog — body rows / terrain_reference overlay for systems.db
|
||||
- **Status:** Open — spun off from D-225 (2026-05-23)
|
||||
- **Question:** D-225 resolves mod *file* resolution (a mod body's source `heightmap.png` is found by searching mod dirs over the base install). But a mod adding a *new* body also needs that body discoverable: the `bodies` row and its `terrain_reference` live in `systems.db`, which is binary and source-canonical (D-189) — mods cannot append to it. How does a mod register new bodies (and other DB-resident catalog rows)? Options: a mod manifest the server merges into an in-memory catalog overlay at load; a parallel mod catalog DB layered over the `systems.db` reads; or a documented mod build step. Out of scope for #960 (base-install resolution ships the viewer); needed before third-party bodies are first-class.
|
||||
- **Context:** Raised 2026-05-23 from the D-225 mod-first layer-stream proxy design. The proxy makes first-party and mod bodies flow through an identical resolve→compute→stream path *given a resolvable source file*; this question is the remaining gap — getting a mod's new body into the catalog the resolver consults.
|
||||
- **Cross-reference:** [D-225](../decisions/architecture.md#d-225), [D-189](../decisions/architecture.md#d-189) (systems.db source-canonical), #960 (atlas viewer — base-install only for now)
|
||||
|
||||
---
|
||||
|
||||
### Q-100: Biome authority — Python sim vs Rust cascade
|
||||
- **Status:** Resolved in principle (Jeroen, 2026-05-25) — implementation detail open. The baked heightmap + reliefmap are deterministic *inputs* (gameplay never touches them), so the natural world is `f(reliefmap, heightmap, seed)` and the cascade **derives from** the baked artifacts, never independently re-derives. The biome/climate the reliefmap encodes is therefore **baked as data the Rust cascade reads** (option A below); `subbiome::classify`'s independent re-derivation is reconciled away. Open: exactly which data layers to bake + the Rust read path.
|
||||
- **Question:** Two independent biome systems exist. `planet_simulation.py` (build-time) computes biome from a Whittaker table + sim-derived temperature/moisture and colours `reliefmap.png` — the authoritative *visual*. `subbiome::classify` (Rust, runtime, D-210) re-derives `SubBiomeVariant` from proxies (elevation percentile, slope, river-distance moisture, latitude temperature). They diverge — a cold fjord coast reads `CoastalLowland` in Rust, which lacks the temperature field. Which is canonical? (A) Python canonical → bake temperature + moisture as additional atlas layers the Rust cascade reads (richer; more storage/pipeline; mod-friendly per D-225); (B) Rust canonical → re-render reliefmaps from cascade output at bake time (simpler; loses the atmospheric sim; regenerates ~267 reliefmaps); (C) keep split (pragmatic; contradicts the dual-artifact principle, D-226). Related sub-fork: the Python river-carve (colours the reliefmap) and the Rust D8 network (D-208) also diverge — the dual artifact requires reconciling them.
|
||||
- **Context:** Tyre's top integration snag. Blocks the biome axis of D-228 and the dual-artifact reconciliation. Tyre's lean: A long-term, B for Phase 4, with the expansion path designed in.
|
||||
- **Cross-reference:** [D-228](../decisions/architecture.md#d-228), [D-226](../decisions/architecture.md#d-226), [D-210](../decisions/architecture.md#d-210), [D-208](../decisions/architecture.md#d-208), [D-225](../decisions/architecture.md#d-225), `tooling/planet-gen/planet_simulation.py`, `server/src/atlas/subbiome.rs`
|
||||
|
||||
---
|
||||
|
||||
### Q-101: Refinement / derivation contract — coarse hint → fine geometry + morphology algorithm family
|
||||
- **Status:** Open — the atlas-derivation workshop's primary technical output, not yet specified (2026-05-25)
|
||||
- **Question:** How does a coarse, map-scale hint (a ~78 km Layer-1 cell) plus a seed become fine, ~1 m-voxel coherent geometry — deterministically, without squaring — across ~3 scale jumps (78 km cell → ~1 km region → 64 m chunk → 1 m voxel)? Needs: the inter-layer hint+seed→geometry API (Tyre sketched a `RegionHint`); a **context-driven morphology algorithm family** selected by local context (rivers meander in lowlands / incise in mountains; coasts dune / crag / fjord by slope + lithology + glaciation), ≥6 distinct generators (meander, incised gorge, braided delta, dune strand, cliff coast, fjord, mountain pass); integer-only *structural* decisions (D-010), f64 confined to within-voxel interpolation; clean transitions between adjacent morphology families. **Unowned dependency:** the ocean/lake mask — D-223 stripped the markers.json polygons that D-209 `CoastalAccess`/`LakeShore` extraction referenced, so the mask must instead be derived from the heightmap sea-level threshold or a baked water-bodies layer. Lithology is a required input (promoted load-bearing by the volumetric subsurface, D-227). Also in scope: **body-class parameters** (hydrosphere, tectonic activity, atmosphere) must modulate river-network *density* — the effective river threshold — so an arid body and an oceanic body differ in *how many* rivers, not just where they run (today `RIVER_THRESHOLD` is a global constant, Nigel); and **river flow direction** (upstream/downstream — gates effort vs speed, and feeds the seasonal water model) derives from the D8 network at query time.
|
||||
- **Context:** The heart of the atlas→tile derivation; surfaces as the cascade builds the region → chunk → voxel layers.
|
||||
- **Cross-reference:** [D-227](../decisions/architecture.md#d-227), [D-228](../decisions/architecture.md#d-228), [D-208](../decisions/architecture.md#d-208), [D-209](../decisions/architecture.md#d-209), [D-223](../decisions/architecture.md#d-223), [D-010](../decisions/architecture.md#d-010), [D-222](../decisions/architecture.md#d-222)
|
||||
|
||||
---
|
||||
|
||||
### Q-102: Cohesion-matrix algorithm — seam-free continuous variation
|
||||
- **Status:** Open — deferred from D-228 (2026-05-25)
|
||||
- **Question:** D-228 mandates that intra-region material / sub-biome scatter come from a **global, position-keyed continuous noise field** so chunk/region boundaries never read as grid seams, while authored straight lines (roads, plazas) stay crisp. Concretely: the noise basis (value / Perlin / simplex / worley); keying on world position (not chunk index) to stay continuous across boundaries; how material / sub-biome thresholds map onto it; integer-only / determinism (D-010); and how authored linear features composite over the continuous field without bleeding.
|
||||
- **Context:** The anti-squaring principle pushed down to the material layer.
|
||||
- **Cross-reference:** [D-228](../decisions/architecture.md#d-228), [D-227](../decisions/architecture.md#d-227), [D-010](../decisions/architecture.md#d-010)
|
||||
|
||||
---
|
||||
|
||||
### Q-103: Tile-mutator op schema
|
||||
- **Status:** Open — deferred from D-227 (2026-05-25)
|
||||
- **Question:** D-227 makes tile mutators the sole persisted state (save = `seed + mutator log`). What does one mutator record — a full per-voxel override, or typed ops (`Dig`, `Build(FloorMaterial)`, `Place(object)`, `Destroy(object)`, `SetMaterial`)? Typed ops are compact, semantic, replayable, but need a fixed op vocabulary; full overrides are simple but heavier and lose intent. Also: replay ordering / conflict semantics, and confirmation that a position-keyed mutator stays valid across re-derivation (determinism guarantees an identical base — to be pinned).
|
||||
- **Context:** Needed when the save system is built (Phase 5+).
|
||||
- **Cross-reference:** [D-227](../decisions/architecture.md#d-227), [D-010](../decisions/architecture.md#d-010)
|
||||
|
||||
---
|
||||
|
||||
### Q-104: Floor-index ↔ absolute voxel-z coordinate mapping
|
||||
- **Status:** Resolved 2026-05-25 by D-229
|
||||
- **Resolution:** Resolved via `FloorExtent { base_floor, floor_count, FloorHeightProfile::{Uniform|Variable} }` + the pure functions `floor_at_voxel_z` / `voxel_range_for_floor`.
|
||||
- **Question:** D-227 introduces an absolute physical z coordinate (metres, continuous over the voxel grid) alongside D-110's floor-*index* addressing (`base_z: i8`, a story-counting integer). The two coexist but the bridge is undefined: "the floor at `base_z = -2`" → which absolute voxel-z values does it span? With variable-height floors (D-227 — default 3 voxels, a cathedral ~10), the mapping is **non-linear** (a floor's voxel-z depends on the heights of the floors below it). What is the mapping function, and where is it owned (a per-building floor table? a region floor-height index?)? Needed before anything queries both systems (Phase 5 building interiors / vertical movement). Gap, not contradiction — D-227 and D-110 do not conflict.
|
||||
- **Context:** Raised in the atlas-derivation workshop (Tyre, Round 2 review of D-227).
|
||||
- **Cross-reference:** [D-227](../decisions/architecture.md#d-227), [D-110](../decisions/architecture.md#d-110), [D-049](../decisions/architecture.md#d-049), [D-222](../decisions/architecture.md#d-222)
|
||||
|
||||
---
|
||||
|
||||
### Q-105: Region seasonal/clock state — the shared cheap-dynamism source
|
||||
- **Status:** Open — committed in principle (D-228); model details open (2026-05-25)
|
||||
- **Question:** D-228 commits to a deliberately cheap, deterministic, **region-level seasonal/clock state** — computed *once* per region per phase, inherited by its tiles — from which a family of **transient surface conditions** derive — all computed from the region's seasonal + tidal + weather phase, none of it stored: **flooded tiles** (floodplain / tidal-flat / seasonal-river, where the water-height crosses local elevation), **snow & ice cover**, **puddles** (weather / rain), **weather** generally, and the **farmland crop cycle** (sown → growing → ripe → harvested → fallow). The model must stay "nearly free" — simple deterministic functions of the in-game clock + body/region parameters, no per-tile or per-frame simulation. Open: the exact phase functions — a **seasonal** term phased by hemisphere (latitude sign), driven by the year clock; a **tidal** term only when the body has a moon (no satellite → no tide), driven by the lunar/day clock with amplitude from the satellite config; a **weather** term (shorter-term precipitation → puddles + general conditions); how snow/ice depth, puddles, flood extent, weather, and the crop cycle each read the same state; the **snow/ice cover model** — D-228 removed `Snow`/`Ice` from `TerrainMaterial`, so snow/ice are *entirely* this seasonal cover overlay (permanent only where climate never melts them — poles, glaciers), depth rising/falling with the seasonal phase; determinism (state = `f(clock, region)` → reproducible) and its interaction with the cache + the D-226 pause/inspection (a frozen phase for stable inspection); and recompute cadence (per phase-change, not per frame).
|
||||
- **Context:** Grew from the floodplain dependency — "floodplain is only feasible if water heights move" — into a general cheap-dynamism source. Jeroen's constraints: clock + hemisphere bound, moon-gated tides, computed once per region, simple rules; snow / weather / crop cycle ride the same calculation.
|
||||
- **Cross-reference:** [D-228](../decisions/architecture.md#d-228), [D-227](../decisions/architecture.md#d-227), [D-226](../decisions/architecture.md#d-226) (dynamic-state inspection), [D-010](../decisions/architecture.md#d-010)
|
||||
|
||||
---
|
||||
|
||||
### Q-106: Era-band stacking depth for layered architecture-flavor
|
||||
- **Status:** Resolved 2026-05-25 by D-232 (round 3) — the question is dissolved, not answered.
|
||||
- **Question (original):** D-232 (round-2 draft) made flavor a three-layer resolution (body × district × era-band). How many era-bands does a settlement produce as a function of `founding_age_years`? What is the minimum age-gap between bands? How do the flavor slices differ between bands?
|
||||
- **Resolution:** The round-3 rewrite of D-232 **retired the era-band material-progression entirely.** The Reach is post-space-travel throughout — there is no stone→concrete→glass tech ladder, so era is *not* a flavor-stacking axis. A block's construction era (still derived from distance-to-founding-origin, D-229) reads as **maintenance/wear** through the condition layer (D-217/D-198); the occasional out-of-vogue building is handled by D-232's **deviation system** (the "past-vogue holdover" — temporal sibling of the spatial swerve), not by multi-band flavor stacking. So there are no era-bands to count.
|
||||
- **Cross-reference:** [D-232](../decisions/architecture.md#d-232), [D-229](../decisions/architecture.md#d-229), [D-217](../decisions/architecture.md#d-217)/[D-198](../decisions/architecture.md#d-198) (condition — where era's wear lands)
|
||||
|
||||
---
|
||||
|
||||
### Q-107: Wiki → Atlas content-set consolidation
|
||||
- **Status:** Open — raised by Jeroen (2026-05-25)
|
||||
- **Question:** The wiki pages live semi-outside game scope yet are piped into Atlas content screens AND are now a generator input (D-232 architecture-flavor distilled from wiki prose). Where authored per-body content lives (frontmatter vs companion file vs a consolidated tree) should follow a consolidation of ALL wiki content — pages + heightmaps + markers + architecture-flavor — into one first-class, baked Atlas content set (the "move it into a `gamedata/` subtree" instinct), not a per-feature hack. The generator-facing tables (`trait_templates` + `atlas_body_trait_bias`, D-232) are invariant to the source location, so this does not block the fill seam.
|
||||
- **Cross-reference:** [D-232](../decisions/architecture.md#d-232), [D-223](../decisions/architecture.md#d-223), [D-191](../decisions/architecture.md#d-191) (Atlas/settlement), and the development cascade (Phase 1 wiki + Phase 3 Atlas)
|
||||
|
||||
---
|
||||
|
||||
### Q-108: Subterranean / domed / sealed-habitat settlement morphology — does the built-world fill model need a surface-vs-enclosed branch
|
||||
- **Status:** Open — raised 2026-05-31 (system-economic-specialization workshop follow-up, via Vuurkloof / GJ 35)
|
||||
- **Question:** The economic-built-world fill model (D-233, re-amended by [D-237](../decisions/architecture.md#d-237)) is implicitly a **surface** model — it derives a roofed-coverage fraction, an operations-surface remainder, and a concentrate-vs-scatter spread across open ground. But `bodies.settlement_pattern` already carries non-surface morphologies for real bodies: `underground_concentrated` (e.g. Vuurkloof / GJ35c, built into ravine walls), `cave`, `domed`, `underground_complex` (~12+ bodies on `underground_concentrated` alone, more across the others). **Nothing in the current chain reads `settlement_pattern`** — it is not in the [D-199](../decisions/architecture.md#d-199) read-set, not consumed by `city_context_reader`, not branched on in `skeleton_gen` / D-233 fill. The engine *primitives* exist ([D-110](../decisions/architecture.md#d-110) signed `base_z`, the `UndergroundComplex` reservation, [D-106](../decisions/architecture.md#d-106) vertical scale — "a deep mine is an inverted skyscraper"), but no morphology switch connects `settlement_pattern` to them at the built-world layer. So an enclosed-habitat body like Vuurkloof would currently generate as a *surface* geothermal town (conduits and exchange stations spread across open ground), contradicting authored lore (underground-concentrated, ravine-wall construction). Does the fill model need a first-class **surface-vs-enclosed (subterranean / domed / sealed-habitat) morphology branch**, and where does it live — (a) `settlement_pattern` as a hard-gate input to D-233/D-237 fill selecting an enclosed coverage/vocabulary model; (b) a separate morphology layer above D-233 the economic vocabulary plugs into; (c) treat domed/sealed (pressurized surface envelope) as distinct from true subterranean (excavated z-negative)? And how does verticality (D-106/D-110) compose with the coverage model when a settlement is primarily vertical/subsurface, and how does `morphology_zone` (D-228/D-234, terrain-driven street geometry) behave when there is no open street plane?
|
||||
- **Context:** D-237 *inherited* D-233's surface assumption; it did not introduce the gap and does not block on it (surface bodies — the majority — are correct today). But enclosed-habitat bodies are authored lore and will read wrong until resolved. Wants its own debate/workshop with Tyre (z-level architecture), Burnelli (coverage model), Miri (which bodies, what they must read as), Araminta (how enclosed interiors are visually distinct). Tracked by ticket #1018; schedule before the Phase 4 content pass authors built form for enclosed-habitat bodies.
|
||||
- **Cross-reference:** [D-233](../decisions/architecture.md#d-233) (surface coverage model — would be amended), [D-237](../decisions/architecture.md#d-237) (authored specialization layer — inherits the surface assumption), [D-199](../decisions/architecture.md#d-199) (read-set — would need `settlement_pattern`), [D-220](../decisions/architecture.md#d-220) (density / vertical pressure), [D-106](../decisions/architecture.md#d-106) (vertical scale), [D-110](../decisions/architecture.md#d-110) (signed z-levels), [D-228](../decisions/architecture.md#d-228)/[D-234](../decisions/architecture.md#d-234) (morphology zone / street geometry), [D-196](../decisions/architecture.md#d-196) (SettlementClass — orthogonal; this is morphology, not active/ghost)
|
||||
|
||||
---
|
||||
|
||||
### Q-109: Cascade generation-source dispatch — planetary / station / mod-DLC-forked / save-only
|
||||
- **Status:** Open — raised by Jeroen (2026-06-05, during #957 zone-selection authoring)
|
||||
- **Question:** The generation cascade currently has a single implicit path: every body runs the planetary generator (`run_cascade` → Layers 0–5). But a body's `SettingType` (or a sibling `GenerationSource` discriminator) should **dispatch at the cascade entry** to one of several generation sources: (a) **planetary** — the default terrain→quarter→tile cascade (#955/#956/#957…); (b) **station / orbital** — a *separate* cascade that owns the station-only zone types (`residential_station`, `extraction_space`, `port_space`, `rural_orbital`) and its own layout model, rather than branching the planetary code (this is why #957's zone-selection table deliberately excludes those ids — see [D-229](../decisions/architecture.md#d-229) amendment 2026-06-05); (c) **mod / DLC-forked** — a value that routes generation to externally-provided code/templates (a mod or DLC name), so third-party content can supply a body's built form without patching core; (d) **save-only / `player_base`** — disables auto-generation entirely and loads the body's built world from a save file (player-constructed bases must persist, not regenerate). Where does this discriminator live — on `SettingType` itself (it already carries `Station`/`Orbital` variants) or a dedicated `GenerationSource` enum at the `run_cascade` entry? How does the mod/DLC fork resolve to external code (registry? trait object? content-pack manifest?)? And how does save-only compose with the D-203 hot cache and the D-225 compute-on-demand proxy (a `player_base` body must never enqueue an `AnalyzeBody`)?
|
||||
- **Context:** Surfaced while authoring #957's `(ZoningType × economic_role × setting)` zone-selection table: `setting` is the right *tweaker* within the planetary path, but it is also the natural *dispatch* point above it — the two roles are distinct and only the tweaker belongs in #957. The dispatch is a cross-cutting routing seam above any single layer; capturing it here so #957 stays scoped to the planetary path. Not blocking — the planetary path is the only live source today. Wants Tyre (cascade architecture) + a look at modding/DLC strategy and the savegame model (Phase 5+) before it's decided.
|
||||
- **Cross-reference:** [D-200](../decisions/architecture.md#d-200) (runtime cascade), [D-225](../decisions/architecture.md#d-225) (compute-on-demand proxy — save-only must bypass), [D-203](../decisions/architecture.md#d-203) (hot cache), [D-229](../decisions/architecture.md#d-229) (zone-selection — excludes station ids for this reason), D-222 (Quarter/spatial tiers), and the development cascade (Phase 5 player control + savegame)
|
||||
|
||||
---
|
||||
|
||||
*58 questions (11 resolved, 1 partially resolved, 46 open). Last updated: 2026-06-05.*
|
||||
@@ -0,0 +1,252 @@
|
||||
# Open Questions — Content
|
||||
|
||||
Narrative, NPCs, dialogue, templates, setting, worldbuilding, and storyteller mechanics.
|
||||
|
||||
---
|
||||
|
||||
### Q-010: Storyteller AI design
|
||||
- **Status:** Not yet discussed
|
||||
- **Question:** How does the Rimworld-style storyteller work? What are the pacing rules? How much structural randomness vs dramatic randomness?
|
||||
- **Assigned to:** Gestalt, Nigel
|
||||
|
||||
### Q-012: Generation expansion method for dialogue
|
||||
- **Status:** Resolved
|
||||
- **Question:** How does the 4x generation expansion pass work? LLM-based, template-based, or rule-based? Affects how base lines are authored — LLM needs style-strong anchors; rules need substitution patterns.
|
||||
- **Assigned to:** Gestalt, Mellanie
|
||||
- **Source:** Content Gap Analysis Workshop (Mellanie R2)
|
||||
- **Resolution:** LLM-based re-voicing via bundled Gemma 2B Q4. Culture-neutral semantic base text is the LLM seed; culture injectors + trait modifiers + tell-context tone shape the output. Resolved by [D-138](../decisions/content.md#d-138-llm-re-voicing-pipeline-for-npc-voice) (LLM Voice Pipeline Workshop, 2026-03-07).
|
||||
|
||||
### Q-013: Line previewer temporal progression
|
||||
- **Status:** Open
|
||||
- **Question:** How does the line previewer (#193) handle THE FRIEND's multi-visit contradiction arc? Needs sequence mode to simulate interaction progression over multiple encounters.
|
||||
- **Assigned to:** Gestalt, Dudley
|
||||
- **Source:** Content Gap Analysis Workshop (Mellanie R2)
|
||||
|
||||
### Q-015: Generation expansion for THE FRIEND content
|
||||
- **Status:** Resolved — obsolete
|
||||
- **Question:** Does the 4x generation expansion apply to THE FRIEND's custom lines, or are all ~70-100 lines per FRIEND hand-authored? Recommendation: no expansion on FRIEND lines — risk of flattening hand-crafted voice.
|
||||
- **Resolution:** Obsolete. D-122 eliminates hand-authored named NPCs — THE FRIEND is now a generator template pattern (D-034 amendment), not a hand-authored character. All NPC content goes through the LLM voice pipeline (D-138). The question of hand-authored vs expanded lines no longer applies.
|
||||
- **Assigned to:** Mellanie, Gestalt
|
||||
- **Source:** Content Gap Analysis Workshop (Ozzie R2, Gestalt R2)
|
||||
|
||||
### Q-017: Triangle pressure threshold
|
||||
- **Status:** Open
|
||||
- **Question:** Triangles need a numeric pressure value that increases based on events. When it crosses a threshold, `confrontation` situation activates. What events increase pressure? What's the threshold?
|
||||
- **Assigned to:** Gestalt, Paula
|
||||
- **Source:** Content Gap Analysis Workshop (Gestalt R2)
|
||||
|
||||
### Q-028: Collision-resistant line IDs for auto-generated NPCs
|
||||
- **Status:** Resolved → [D-084](../decisions/content.md#d-084-dual-namespace-line-id-scheme--role-pool--instance-override)
|
||||
- **Resolution:** The collision problem is mostly already solved by the role-pool architecture: `dock-worker_d_###` lines are shared content for all instances of the role, not per-instance IDs. A true collision (two distinct authored lines sharing the same ID) cannot occur with one file per role. For the edge case of authored instance-specific content, a role-slug + zero-padded generation counter suffix produces `dock-worker-07_d_001`. Counter is seeded-deterministic. No schema change, no migration. Hand-authored NPCs unchanged.
|
||||
- **Closed by:** Gestalt (Sprint 18, #544). 2026-02-25.
|
||||
- **Ticket:** #544
|
||||
- **Assigned to:** Gestalt, Tyre
|
||||
- **Source:** Sprint 16 PR #59 review discussion (2026-02-23)
|
||||
|
||||
### Q-031: Combined content style guide
|
||||
- **Status:** Open
|
||||
- **Question:** Should the project have a single combined content style guide merging Paula's tier templates, Mellanie's voice conventions, Gestalt's mechanical constraints, and Miri's regional guide? The wiki-review workshop proposed this as a deliverable but it was never authored. What format, who owns it, and does it block content authoring?
|
||||
- **Assigned to:** Mellanie, Paula
|
||||
- **Source:** Wiki Review Workshop R2
|
||||
|
||||
### Q-033: Three-system NPC architecture
|
||||
- **Status:** Partially resolved — reframed by [D-122](../decisions/content.md#d-122-all-npcs-generated--no-named-hand-authored-characters) (all NPCs generated)
|
||||
- **Reframe:** The 9-pattern x 6-motivation composition matrix survives as a generator template taxonomy (the FRIEND pattern explicitly survives as a generator template per D-034 amendment). Both D-024 and this matrix now describe generator output format, not hand-authoring assignments. The NpcBlueprint struct (Sprint 25) encodes patterns and motivations. Full formal adoption of the 9x6 matrix as the canonical generator taxonomy remains open — the composable behavior engine (D-139) may inform how patterns map to behavior primitives.
|
||||
- **Question:** Should NPCs be formally composed from 9 thematic patterns (FRIEND, MIRROR, ANCHOR, GHOST, CATALYST, THRESHOLD, REMNANT, SYSTEM, NOBODY) x 6 functional motivations (HANDLER, WITNESS, TURNCOAT, CIVILIAN, OPERATOR, SKEPTIC)? D-024 defines 10 axes + combat but predates this refined system. The wiki-review workshop produced a full composition matrix with drama ratings and forbidden combinations. Does this supersede D-024 or extend it?
|
||||
- **Assigned to:** Gestalt, Paula
|
||||
- **Source:** Wiki Review Workshop R4
|
||||
|
||||
### Q-040: Gate dual-use topology — freight and commuter on shared span gate infrastructure
|
||||
- **Status:** Resolved → D-093 (gate cluster zone spec), D-095 (span gate dual-use windows)
|
||||
- **Question:** System span gates serve both freight and commuter traffic (one gate per system). How does this work physically? Is it one gate aperture with scheduling (freight window vs. passenger window), or parallel lanes (separate apertures for freight and passenger flows)? What does the gate facility look like from the inside — a single large bay or divided infrastructure?
|
||||
- **Layout implication:** Affects the gate cluster spatial design in the Transit District — the gate cluster must accommodate both freight staging and passenger throughflow, possibly at different times of day.
|
||||
- **Assigned to:** Miri
|
||||
- **Source:** Station District Layout Workshop (#153), Round 2. Surfaced by lead correction to Miri's S-02 (commuter transit ≠ second external gate).
|
||||
- **Cross-reference:** D-036 (Sova setting), Q-036 (district skeleton as generator output)
|
||||
|
||||
### Q-041: Interstellar travel mechanics — horizon stations and gate architecture
|
||||
- **Status:** Resolved → D-095 (horizon stations: alien-built, 4–8 apertures, Oort-cloud, "The Ring"; sequential hop travel)
|
||||
- **Question:** A system needs MORE than one horizon gate for multi-hop connectivity (one gate allows only 1:1 connections). Lead proposal (Round 3): **Horizon stations** — orbital installations at Oort-cloud distance, partially or wholly understood ancient alien technology, self-maintaining (Mass Effect relay/Citadel analog). Each horizon station holds a FIXED number of active and inactive horizon gates. Some systems may only have one hop to an orbital customs station with no direct planet-side span gate access. Remaining questions: How many gates per horizon station? What determines which gates are active vs. inactive? Is the travel instantaneous or traversal-based? What is "The Ring" (the orbital horizon station) like as a physical space?
|
||||
- **Assigned to:** Miri
|
||||
- **Source:** Station District Layout Workshop (#153), Round 2. Lead correction in Round 3: single-gate-per-system model insufficient for multi-hop travel; horizon station model proposed.
|
||||
- **Cross-reference:** D-036 (Sova setting), Q-039 (gate topology generation), Q-040 (gate dual-use topology)
|
||||
|
||||
### Q-042: Intra-system transport networks — passenger vs. freight, vehicles and modes
|
||||
- **Status:** Partially resolved → D-095 (span gates at star/planetary level; horizon stations at Oort distance). Intra-system hab-to-hab transit remains open.
|
||||
- **Question:** How do people and goods move within a star system (between orbital stations, planetary surfaces, and other in-system facilities)? Are there two separate networks (passenger transport and freight transport) or one shared network? What are the vehicle types and transit modes? How does intra-system transit interact with the span gate at the system's hub station?
|
||||
- **Assigned to:** Miri
|
||||
- **Source:** Station District Layout Workshop (#153), Round 2. Flagged by lead as transport lore requiring formal tracking.
|
||||
- **Cross-reference:** D-036 (Sova setting), Q-043 (station internal transit)
|
||||
|
||||
### Q-043: Station internal transit — intra-station transport system between districts
|
||||
- **Status:** Resolved → D-095 (The Loop: 6-district tram, 4-minute Residential Core → Transit District; transit platform is bar-side encounter node)
|
||||
- **Question:** What is the intra-station transport system on Station Sova? How do workers commute between districts (e.g., Residential Core → Transit District)? Is it a train, tram, shuttle, or pressurised corridor? What is the travel time and frequency? Where does the transit stop sit within the Transit District — gate-cluster-adjacent (workers arrive near freight operations) or bar-side-adjacent (workers arrive near their social space)?
|
||||
- **Layout implication for #153:** The Transit District must include an internal transit stop. Its position within the district affects NPC traffic patterns and the district entry topology. This is the active T-03b question for Round 2/3 of the Station District Layout Workshop.
|
||||
- **Assigned to:** Miri
|
||||
- **Source:** Station District Layout Workshop (#153), Round 2. Arose from lead correction: commuter transit = internal station transit, not a second external gate.
|
||||
- **Cross-reference:** D-036 (Sova setting), Q-042 (intra-system transport networks), S-02 revision
|
||||
|
||||
### Q-044: Gate-train integration — do transport vehicles use gates directly or transfer on each side
|
||||
- **Status:** Resolved → D-093/D-095 (gates are pedestrian/cargo-only; passengers transfer via gate concourse → transition corridor → transit platform; no direct gate-to-tram connection)
|
||||
- **Question:** If trains or shuttles are the intra-system or intra-station transit mode, do they use the span gate directly (a train enters the gate and exits at the destination, carriages and all)? Or are the gates pedestrian/cargo-only, requiring passengers and freight to transfer to separate transport on each side? What does this imply for gate terminal design — does it need platforms, or just processing space?
|
||||
- **Assigned to:** Miri
|
||||
- **Source:** Station District Layout Workshop (#153), Round 2. Flagged by lead as transport lore requiring formal tracking.
|
||||
- **Cross-reference:** Q-040 (gate dual-use topology), Q-043 (station internal transit)
|
||||
|
||||
### Q-045: Axis 11 — Network Footprint NPC tag
|
||||
- **Status:** Open
|
||||
- **Priority:** High
|
||||
- **Question:** Should the NPC model (D-024, 10 axes) gain an 11th axis: `network_footprint: Option<NetworkFootprintTag>` for NPCs who are locally insignificant in appearance but carry network-significant information or are relevant to external actors? Default `None` for procedural NPCs. Explicitly set for authored scenario NPCs. This would enable the storyteller to identify locally-invisible but network-critical nodes without breaking the NPC's mundane character.
|
||||
- **Context:** Raised during Generator Architecture Workshop (#562). The Ysabel Vorn litmus test (4.5/5 playstyle hooks, Backwater/Moderate setting) demonstrated that locally-insignificant NPCs can be key network nodes. Without this field, the generator has no mechanism to flag them to the storyteller.
|
||||
- **Source:** Generator Architecture Workshop (#562), Round 4. `docs/workshops/generator-architecture/workshop-outcomes.md` §NPC Model.
|
||||
- **Assigned to:** Miri
|
||||
|
||||
### Q-047: Mobile environment social arc — structural representation of journey timeline
|
||||
- **Status:** Open
|
||||
- **Priority:** Medium
|
||||
- **Question:** How is the social arc of a mobile environment journey (BoundedLinear / BoundedMobile) represented structurally? The journey has a beginning (boarding, strangers), middle (established dynamic), and end (departure, relationship crystallized). What game structures capture this timeline and enable the storyteller to intervene? Does `TransitSocialModifier` need a journey-phase field?
|
||||
- **Context:** Ozzie's player experience requirement from Generator Architecture Workshop (#562): "the journey must have a social arc — not just social presence." The stage+cast framing is correct; the formal structural representation is unspecified.
|
||||
- **Source:** Generator Architecture Workshop (#562), Round 4. `docs/workshops/generator-architecture/workshop-outcomes.md` §Open Questions.
|
||||
- **Assigned to:** Miri + Gestalt
|
||||
|
||||
### Q-048: DramaDensity enum naming — 3-level vs 5-level
|
||||
- **Status:** Open
|
||||
- **Priority:** Low
|
||||
- **Question:** The Round 4 struct uses `Quiescent / Active / Intense` (3 levels). Round 3 proposed `Zero / Low / Medium / High / Flashpoint` (5 levels). Which should be canonical? Nigel's position: `Flashpoint` should be preserved as a distinct peak value — it is the storyteller's maximum-pressure instrument and should not collapse into `Intense`. If 3 levels are chosen for implementation simplicity, `Flashpoint` should still be the distinct peak name, not `Intense`.
|
||||
- **Context:** ComplexityTier → DramaDensity ceiling (established): Full → any intensity; Moderate → Active max; Minimal → Quiescent max; Empty → Zero only. Naming must be consistent with these ceiling values.
|
||||
- **Source:** Generator Architecture Workshop (#562), Rounds 3–4. `docs/workshops/generator-architecture/workshop-outcomes.md` §Open Questions.
|
||||
- **Assigned to:** Tyre + Gestalt
|
||||
|
||||
### Q-049: ObjectTag vocabulary co-maintenance — Miri and Araminta shared dependency
|
||||
- **Status:** Open
|
||||
- **Priority:** Medium
|
||||
- **Question:** The `ObjectTag` vocabulary must be co-maintained between Miri's `HeritageGrammarOverlay` (cultural grammar, Rust struct) and Araminta's asset categorization (visual expression, TOML files). What is the governance model? Who owns the canonical tag list? How are additions and deprecations coordinated? Does the vocabulary live in the Rust struct definition or in a shared data file?
|
||||
- **Context:** If the vocabulary diverges, the generator will reference tags that don't exist in asset categories, or assets will be authored that the grammar never references. This is a silent correctness failure.
|
||||
- **Source:** Generator Architecture Workshop (#562), Round 4. `docs/workshops/generator-architecture/workshop-outcomes.md` §D-READY-9.
|
||||
- **Assigned to:** Miri + Araminta
|
||||
|
||||
### Q-050: Assassination difficulty synthesis — formal spec combining stored baseline with on-demand computation
|
||||
- **Status:** Open
|
||||
- **Priority:** Medium
|
||||
- **Question:** Formal specification needed for the synthesis combining stored cultural baseline (`DerivedDistrictAnalysis` on Phase 1 skeleton) with on-demand runtime computation for player-facing assessment. Key constraint from Miri: **on-demand computation is display-only** — all game logic (tactical triangle instantiation, guarantee audit) uses the Phase 1 `DerivedDistrictAnalysis` value. The on-demand computation is subordinate to the stored baseline, not a replacement.
|
||||
- **Context:** Minor tension between Gestalt's "computed entirely on demand" position and Miri's "stored cultural baseline" position. Synthesis accepted by both participants in Generator Architecture Workshop (#562); formal spec needed for implementation.
|
||||
- **Source:** Generator Architecture Workshop (#562), Round 4. `docs/workshops/generator-architecture/workshop-outcomes.md` §Open Questions.
|
||||
- **Assigned to:** Gestalt + Miri
|
||||
|
||||
### Q-052: Storyteller hint delivery — parallel diegetic channels when player does not act
|
||||
- **Status:** Open (Sprint 22 analysis complete, awaiting implementation scoping)
|
||||
- **Priority:** High
|
||||
- **Question:** When a TriangleActivated event fires and the player does not investigate, what mechanisms create conditions for discovery? How do these scale from v0.1 (1-2 triangles) to the full game (300 worlds, 10+ simultaneous triangles, 8 archetypes)?
|
||||
- **Core design principle:** "The storyteller is not delivering messages — it is creating conditions under which the player's existing relationships, existing investments, and existing world naturally produce signal." Player inaction is a valid outcome, not an error state. Consequences happen; the world moves on.
|
||||
- **Channel inventory (ranked by deniability — least nudge-like first):**
|
||||
1. **Behavioral tell escalation** — activated triangle NPCs exhibit more pronounced tells (D-024 axis 9). Always active, proximity-gated. Feels like the world being alive. Scales infinitely, zero authoring per triangle.
|
||||
2. **Environmental change** — something physically different at the triangle location (locked door, moved cargo, light on at wrong hour). Archetype-agnostic: engineer reads the system fault, diplomat reads the guard rotation, merchant reads the sealed bay. Infinite scale, zero authoring per triangle.
|
||||
3. **Ambient sound cue** — audible change in the triangle zone (hushed conversation, footsteps at unusual time, a door that was open now shut). Uses D-018 three-range system. Proximity-gated.
|
||||
4. **Overheard NPC conversation** — secondary NPCs gossip about the activated NPC's changed behavior. Fires when two NPCs share a scene in a social site. Scales with the social simulation, not with authoring. Constraint: the NPC speaks from their own concerns ("He owes me for last week's haul and now he's not answering"), never from narrative convenience ("I think something is wrong with Kael").
|
||||
5. **Unprompted NPC remark** — a non-job-giver NPC proactively comments when the player approaches. Uses D-028 Layer 4 unprompted disclosure with `situation: [triangle_activated]`.
|
||||
6. **FRIEND message** — the FRIEND NPC (D-034) reaches out. Structurally unique: when the FRIEND IS the triangle anchor (smuggler/Kael), the message is simultaneously the nudge and the tell — its timing, phrasing, and whether it sounds normal are the investigative data. Reserve for the triangle the FRIEND is directly connected to; degrades on overuse (one FRIEND per character = hard limit).
|
||||
7. **Internal monologue** — player character's inner voice notices something. Proximity-gated to triangle NPCs exhibiting tells. Character-specific voice (D-032, D-090).
|
||||
8. **Job-giver app message** — institutional backstop of last resort. Fires only if no other channel has produced player engagement. One per session maximum, for the single highest-engagement triangle only. Job-giver per archetype: smuggler = handler ("Dock 7, pickup, ask for Kael"), detective = Commission superior ("Welfare check, dock-level, concern logged by port authority"), engineer = fault log, diplomat = peer request, merchant = market signal. Three sender types: named NPC (personal), institution (semi-personal), automated system (impersonal).
|
||||
- **Delivery model — parallel channels, not linear funnel:**
|
||||
- All channels activate on TriangleActivated. The player encounters whichever their playstyle naturally intersects first.
|
||||
- Channels have capacity, not triangles: monologue holds 1 thread (highest engagement wins), gossip holds 2-3, tells are unlimited. Lower-engagement triangles naturally get quieter channels — no starvation.
|
||||
- App message has a long fuse; only delivers if no other channel has been "hit" (storyteller detects player engagement via any channel). Prevents the pattern from being predictable across playthroughs.
|
||||
- Diegetic test for all channels: could you explain the output without reference to the activated triangle? If yes, diegetic. If no, quest marker.
|
||||
- **Scaling properties (v0.1 → full game):**
|
||||
- Channel priority inverts at scale. v0.1: authored channels (monologue, job-giver) dominate. Full game: universal channels (environmental, overheard, tells) are the foundation because they scale with the simulation, not with authoring.
|
||||
- Job-giver coherence breaks if overused — handler sending player to 3 activated locations in one session becomes transparent. Backstop for highest-engagement triangle only.
|
||||
- Hint adaptation: storyteller tracks `PlayerHintEngagement` — how often the player engages after each channel tier. Extends fuses and reduces probabilities as player demonstrates skill. Hours 1-5: full hints. Hours 15+: player reads the world by behavioral tells alone. "Not harder combat — a quieter, more trusting world." Resets per new playthrough.
|
||||
- ~15-20 hour meta-awareness cap: beyond that, the game likely needs a complementary active system (case board, network map) the player reads rather than passively receives. Separate design problem, out of scope here.
|
||||
- **Signal pollution gating:**
|
||||
- Monologue: only when player is within proximity of a triangle NPC exhibiting tells.
|
||||
- Gossip: only when the player initiates conversation with a connected secondary NPC. Passive, not pushed.
|
||||
- FRIEND message: only if the FRIEND has a plausible in-world reason to reach out at this moment (established relationship cadence).
|
||||
- Job-giver: once per session, backstop only.
|
||||
- Environmental/tells: always active, no gating needed (they ARE the world).
|
||||
- **Implementation implications:**
|
||||
- Storyteller needs a `ChannelSet` per activated triangle tracking which channels have fired and whether the player has engaged.
|
||||
- Post-activation state machine: `Activated → [channels live] → Resolved (player engages) | Consequences (timeout) | Expired`.
|
||||
- NPC behavioral state changes need to register as conversation topics for social-network propagation (simulation feature, not content feature).
|
||||
- App message content uses D-028 tagged line pools with new `situation: [app_message]` tag and sender-type sub-tag. Rendered in neural insert UI as message thread, not monologue overlay.
|
||||
- **Content pipeline:**
|
||||
- Universal channels (environmental, overheard, tells): zero per-triangle authoring. Build once as simulation features.
|
||||
- Authored channels (monologue, FRIEND, job-giver): per-character/per-archetype investment. Layer on top as richness.
|
||||
- Job-giver treated as authored feature shipping archetype by archetype, not universal system shipping once.
|
||||
- **Context:** Raised during Sprint 22 storyteller scoping (#162). Analysis by Gestalt (systems) and Paula (narrative) across two rounds.
|
||||
- **Cross-reference:** D-023 (storyteller activation), D-016 (monologue system), D-018 (three-range hearing), D-024 (NPC axes — tell system), D-028 (dialogue architecture), D-032 (separate monologue pools), D-034 (THE FRIEND), D-090 (character voice), #162 (storyteller module activation)
|
||||
- **Assigned to:** Gestalt, Paula
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
### Q-056: Zone spec needs location_context field (surface/station/vessel)
|
||||
|
||||
- **Status:** Open
|
||||
- **Raised:** Sprint 25 PR #88 review (Miri)
|
||||
- **Context:** Rural zone spec behaviors reference sky, weather, and diurnal heat — only valid on a planetary surface, not inside a station. The current `ZoneSpec` struct has no field for environment context. Without it, the generator can't distinguish surface-rural from station-rural, and behavior strings may be incoherent for the location.
|
||||
- **Question:** Should `ZoneSpec` include a `location_context` enum (Surface/Station/Vessel) that the generator uses to filter or modify environment-specific behaviors? Or should zone specs be authored per-context (e.g. `rural-surface.ron`, `rural-station.ron`)?
|
||||
- **Implications:** Affects all zone spec authoring going forward. The generator's ability to extrapolate from minimal input depends on knowing whether "rural" means open sky or sealed corridors.
|
||||
- **Cross-reference:** D-012 (chunk-based map), D-036 (Van Maanen's Star/Sova setting), D-104/D-105 (heritage roots), #609 (zone identity spec)
|
||||
- **Assigned to:** Tyre, Miri
|
||||
|
||||
---
|
||||
|
||||
### Q-057: Composable behavior generation — decompose culture × role × context into assembled behaviors
|
||||
|
||||
- **Status:** Resolved — D-139 (Sprint 26, #633)
|
||||
- **Raised:** Sprint 25, ticket #630 review discussion
|
||||
- **Priority:** High (blocks scaling beyond hand-authored content)
|
||||
- **Context:** Current behavior pools are hand-authored per culture×zone×role combination (`typical_behaviors` arrays in zone spec RON files). At ~50 behaviors per role × 4 roles × N zone types × M cultures, this is O(roles × zones × cultures) custom content. Each cell is effectively a unique location — "rural zone spec" is really "Van Maanen's Star rural settlement content" with the name filed off. This doesn't scale to multiple cultures or zone types.
|
||||
- **Question:** Should the generator compose observable behaviors from smaller primitives instead of drawing from pre-written complete sentences? Proposed decomposition: (1) **role action templates** — generic observable stage directions per role, culture-neutral, (2) **culture modifier sets** — culture-specific flavoring (Van Maanen's Star mannerisms, speech patterns, social norms) that overlay role actions, (3) **context tags** — on-shift, off-duty, break-room, social-site-type that filter/weight which behaviors are available. The generator assembles these at runtime.
|
||||
- **Resolution:** Yes. D-139 defines the three-layer composable behavior model: `BehaviorPrimitive` (role actions with context tags), `BehaviorModifier` (culture overlays), and `BehaviorContext` (on-shift/off-duty/social/any filtering). The `assemble_behaviors()` function composes at runtime. Generator spike updated to use assembly when `behavior_primitives` are present, falling back to `typical_behaviors` for backward compatibility. Copy team (#634) authors the decomposed format.
|
||||
- **Cross-reference:** #630 (behavior pool expansion), #633 (server: composition engine), #634 (copy: decomposed content format), D-121 (voice is culture-driven), D-122 (all NPCs generated), D-139 (composable behavior assembly)
|
||||
- **Assigned to:** Tyre, Mellanie, Miri
|
||||
|
||||
---
|
||||
|
||||
### Q-WTF-039: Character creation — portrait render or tile-scale preview?
|
||||
- **Status:** Resolved → [D-146](../decisions/scope.md#d-146-character-creation-preview--tile-scale-sprite-with-heavy-zoom)
|
||||
- **Question:** Does the character creation screen show a portrait render or a tile-scale in-world preview of the player character? Affects #618 (CK3-style character creation screen) team assignment: portrait render is a visual team deliverable; tile-scale preview is client.
|
||||
- **Resolution:** Tile-scale sprite with heavy zoom. The creation screen shows the game sprite rendered at high resolution, zoomed in so cosmetic details are clearly visible. Same approach as Rimworld: one rendering pipeline, no separate portrait system. #618 stays as a single client ticket. Resolved by [D-146](../decisions/scope.md#d-146-character-creation-preview--tile-scale-sprite-with-heavy-zoom).
|
||||
- **Assigned to:** Tyre (architecture), confirmed by project lead
|
||||
- **Source:** Sprint 27 planning pass (2026-03-17)
|
||||
|
||||
### Q-WTF-040: Do creation choices trace into the generated apartment?
|
||||
- **Status:** Resolved → [D-147](../decisions/content.md#d-147-aesthetic-taste-as-character-personality-trait--shared-root-for-cosmetic-and-environmental-expression)
|
||||
- **Question:** If the player picks hair colour and clothing in #619, does the generator use those choices when laying out the starting apartment (furniture style, colour palette)? Affects #617 scope and dependency.
|
||||
- **Resolution:** Not directly. Cosmetic choices do not pipeline into the apartment generator. Instead, characters have an `aesthetic_taste` personality trait that independently informs both appearance choices and living space. Someone who likes teal picks teal clothing AND owns a teal vase — but through shared taste, not data coupling. #619 does NOT block #617. Resolved by [D-147](../decisions/content.md#d-147-aesthetic-taste-as-character-personality-trait--shared-root-for-cosmetic-and-environmental-expression).
|
||||
- **Assigned to:** Gestalt (systems), Paula (narrative), confirmed by project lead
|
||||
- **Source:** Sprint 27 planning pass (2026-03-17)
|
||||
|
||||
### Q-WTF-041: What should the player feel looking at the span gate from their apartment?
|
||||
- **Status:** Open
|
||||
- **Question:** The First Settled Reach moment (D-136) is apartment + insert activation. The player's apartment has a view of the span gate. What emotional register should this view hit? Awe? Routine familiarity? Unease? This shapes the visual design of the apartment scene and the insert's first content.
|
||||
- **Affects:** #626 (setting delivery — both layers). Blocks implementation until the emotional target is defined.
|
||||
- **Needs:** Gore (thematic framing), Ozzie (player experience), Miri (setting grounding), Araminta (visual direction)
|
||||
- **Source:** Where's the Fun? Workshop, Round 5 (2026-03-05)
|
||||
|
||||
---
|
||||
|
||||
### Q-095: Commission formal name — authoritative designation
|
||||
- **Status:** Resolved — see [D-193](../decisions/content.md#d-193-lattice-commission--canonical-long-form-of-the-commission) (2026-04-21)
|
||||
- **Resolution:** Canonical long-form is **"the Lattice Commission"**. Short form "the Commission" remains standard in-prose. "Concord Commission" and "Assembly Commission" drift forms are non-canonical.
|
||||
- **Question:** What is the full formal name of the Concord Assembly's regulatory authority? In-prose use is "the Commission", but several drift forms have appeared in copy reviews ("Concord Commission", "Assembly Commission", "Lattice Commission"). A canonical long-form is needed for formal/legal contexts, institutional signage, and wiki headers.
|
||||
- **Context:** The Commission certifies implant hardware, medical equipment, pharmaceutical production, and safety-critical manufactured goods under tractus-denominated fees. It has no authority in Compact member systems. Current glossary guidance is to use "the Commission" until the full name is resolved, but authors writing institutional POIs and formal documents need a decision.
|
||||
- **Affects:** Wiki content, marker POI naming (e.g. `"Lattice Commission — Sirius Office"`), formal legal text in tractus fee documentation, institutional signage.
|
||||
- **Source:** Sprint 35 copy review (PR #127)
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
### Q-097: Strip "What They Don't Talk About" from corporation pages
|
||||
- **Status:** Open
|
||||
- **Question:** Should we remove "What They Don't Talk About" sections from corporation wiki pages? Currently 116 of 156 corp pages have this section. The argument: cultural silences are a population/system-level phenomenon — people carry them because of where they live, not who employs them. A mining company doesn't develop its own cultural ethos; its workers inherit the system's silences. Corporate secrecy (trade secrets, undisclosed contracts) is just business, not anthropology. Gate Corporation may be an exception as a civilization-scale institution, but Arbour Aggregates and Rush Mining are regional businesses whose people are system-people first.
|
||||
- **Context:** Pattern originated from Gate Corporation (which plausibly operates at civilization scale) and was applied uniformly to all corp pages during bulk authoring. Now reinforcing itself — reviewers flag its *absence* as a defect (Sprint 38 PR #140 round 1). If left in place, every new corp page will copy the pattern. Counter-argument: some corporate silences *are* distinct from system silences (e.g., a pharmaceutical company's certification history vs. the system's general cultural memory). The question is whether that justifies a dedicated section or whether it belongs inline in Operations/Market Position.
|
||||
- **Affects:** 116 wiki/corporations/*.md files, corp page template, reviewer expectations
|
||||
- **Source:** Sprint 38 PR #140 review discussion (2026-05-02)
|
||||
|
||||
---
|
||||
|
||||
*26 questions (11 resolved, 2 partially resolved, 13 open). Last updated: 2026-05-02 (Q-097 corp silences)*
|
||||
@@ -0,0 +1,104 @@
|
||||
# Open Questions — Perception
|
||||
|
||||
Player observation, information systems, UI surfaces, knowledge mechanics, and insert workspace.
|
||||
|
||||
---
|
||||
|
||||
### Q-003: Art direction / presentation style
|
||||
- **Status:** Further resolved for v0.1 via Content Gap Analysis Workshop. Araminta's v0.1 Visual Grammar proposal covers: entity color palette (D-033), zone-specific color palettes (3 zones with hex values), fog rendering (4 states), monologue presentation spec, insert dual-character variants. Long-term art direction beyond v0.1 remains open.
|
||||
- **Remaining:** Long-term art direction, sprite replacement timeline, full visual identity.
|
||||
- **Assigned to:** Araminta (lead)
|
||||
|
||||
### Q-014: Audio timing with monologue chime
|
||||
- **Status:** Resolved → [D-067](../decisions/perception.md#d-067-recognition-chime-fires-at-onset-of-cognitive-delay)
|
||||
- **Resolution:** Chime fires at ONSET of cognitive delay, not completion. 300-400ms duration, overlapping delay start. Chime is "unresolved" — opens a question, doesn't answer one. Sequence: hear/sense → chime plays → 0.6s delay begins → monologue text during delay → blob transitions to D-033 color → recognition complete.
|
||||
- **Date resolved:** 2026-02-16
|
||||
|
||||
### Q-016: Knowledge hierarchy for monologue prerequisites
|
||||
- **Status:** Resolved → [D-041](../decisions/architecture.md#d-041-knowledge-graph-data-model)
|
||||
- **Resolution:** 4-level hierarchy: `Suspects < KnowsOf < KnowsDetails < Direct`. Suspects = "something's off", gates initial investigation and vague monologue. KnowsOf = "X is involved in Y", gates topic-specific dialogue and peer-tier access. KnowsDetails = actionable detail, gates confrontation and secret-tier dialogue. Direct = currently in LOS, provides live position data. Maps to D-028 access tiers and D-035 prerequisite tags.
|
||||
- **Date resolved:** 2026-02-11
|
||||
- **Source:** Knowledge Graph & Information Boundaries Workshop
|
||||
|
||||
### Q-024: Gossip propagation timing
|
||||
- **Status:** Resolved → [D-080](../decisions/perception.md#d-080-npc-to-npc-knowledge-propagation)
|
||||
- **Resolution:** Knowledge transfer occurs via a separate `transfer_npc_knowledge` Bevy system running `after(run_npc_conversations)`. Transfer fires once per conversation at conversation start (immediate during conversation, not queued). Rate: 1–3 facts drawn by recency. Trust-tier gated. See D-080 for full specification.
|
||||
- **Closed by:** Knowledge Flow & NPC Information Boundaries Workshop — unanimous. 2026-02-24.
|
||||
- **Source:** Knowledge Graph & Information Boundaries Workshop (Gestalt Round 1); resolved in Knowledge Flow & NPC Information Boundaries Workshop Round 2.
|
||||
|
||||
### Q-025: Knowledge graph cap and eviction strategy
|
||||
- **Status:** Resolved — no cap or eviction needed for v0.1/v0.2. Re-evaluation trigger: Active NPC count > 200 OR KG memory exceeds 50 MB.
|
||||
- **Question:** At what point does an NPC's knowledge graph need entry eviction? What is the eviction policy?
|
||||
- **Resolution (2026-02-24, confirmed by Knowledge Flow workshop):** Current analysis: ~14 KB per Active NPC KG (50 entities + 20 facts, D-041 budget). 80 Active NPCs = ~1.1 MB. 2,000 Background NPCs at 10 entries = ~5 MB. Total ~6 MB. With gossip propagation shipping in Sprint 17 (D-080, 1–3 facts per conversation): estimated ~12 MB peak at current NPC counts. Neither re-evaluation condition expected before v0.3. The existing decay system (`decay_knowledge` in `knowledge/events.rs`) downgrades confidence and marks entries Stale but does not remove them — correct behavior (preserves "I used to know X" for narrative). If eviction becomes necessary, simplest policy: on each decay pass, if entities.len() > MAX_ENTITIES, remove Stale entries with lowest last_updated_tick. BTreeMap makes this O(N).
|
||||
- **Closed by:** Knowledge Flow & NPC Information Boundaries Workshop — Tyre, Gestalt, Dudley confirmed; Paula non-objection noted. 2026-02-24.
|
||||
- **Source:** Knowledge Graph & Information Boundaries Workshop (Dudley Round 1, section 8.3). Architecture audit 2026-02-23. Workshop confirmation 2026-02-24.
|
||||
|
||||
### Q-026: Contradiction detection algorithm
|
||||
- **Status:** Resolved → [D-083](../decisions/perception.md#d-083-contradiction-detection-pipeline)
|
||||
- **Resolution:** Event-driven detection at KG write time in `observe_entity()`, using `ContradictionClaim` struct. Location contradiction is automatic (Sprint 17): position comparison + time window (CONTRADICTION_WINDOW_TICKS = 600). Attribute and fact contradiction are content-authored (Sprint 18). Both ToldBy and DirectObservation entries receive Contradicted state (epistemic neutrality). `ContradictionDetected` event → monologue with resolved display names → relationship shift → AnomalyMarker via existing pipeline.
|
||||
- **Closed by:** Knowledge Flow & NPC Information Boundaries Workshop — unanimous on architecture. 2026-02-24.
|
||||
- **Source:** Knowledge Graph & Information Boundaries Workshop (Gestalt/Paula Round 1); resolved in Knowledge Flow & NPC Information Boundaries Workshop Round 2.
|
||||
|
||||
### Q-051: Speech bubble indicator over speaking NPCs
|
||||
- **Status:** Open
|
||||
- **Priority:** Low
|
||||
- **Question:** Add a generic speech bubble icon above the head of any NPC that is currently speaking in a conversation. Consider reusing the per-character color coding from the dialogue log so the player can easily map speech bubbles to dialogue entries.
|
||||
- **Context:** When multiple NPCs are nearby and the dialogue log is scrolling, it can be hard to tell who is speaking. A floating speech bubble icon (not the text itself — just the indicator) over the speaker's sprite would anchor dialogue to world position. Color-coding to match the dialogue log's per-character colors reinforces the mapping.
|
||||
- **Assigned to:** Stig + Araminta
|
||||
|
||||
### Q-053: Insert workspace boards — design philosophy and information architecture
|
||||
- **Status:** Open (Sprint 22 analysis complete)
|
||||
- **Priority:** High
|
||||
- **Question:** How do boards function as the player's primary active information surface, and what design principles govern their behaviour across archetypes, game phases, and concurrent use?
|
||||
- **Core design principle:** Boards are a **general-purpose communication layer** to the player, not a mechanic in themselves. The renderer is agnostic — it takes structured data and draws it. What creates a board, what populates it, and what its lifecycle is are decisions owned by the upstream system (quest, journal, navigation, business management, faction tracking, etc.), not the renderer.
|
||||
- **Design principles established:**
|
||||
1. **Epistemology map, not truth map.** "The board maps the player's epistemology, not the game's truth." Nodes appear as the player encounters them. Connections are always the player's work. The board never reveals information the player hasn't acquired through gameplay.
|
||||
2. **Passive nodes, active edges.** Things appear automatically when observed/learned; relationships between them are the player's inference. This makes the board a thinking tool, not a checklist.
|
||||
3. **Multiple concurrent boards.** A character can be on an investigation while running a business while tracking a social network. Boards attach to whatever upstream system creates them — a quest, a business, a journal category, a transit network. The workspace presents them as tabs or equivalent navigation.
|
||||
4. **Archetype-specific readings.** Same diagram data, different professional questions. Detective reads evidence chains, smuggler reads trust networks, engineer reads system diagrams, diplomat reads faction leverage, merchant reads supply lines. The rendering primitive is identical; the upstream system determines what nodes and edges mean.
|
||||
5. **Cross-board convergence as discovery.** When the same node appears on multiple boards, that IS the discovery moment. Consistent visual identity (same icon, same colour) lets player recognition do the work — no automatic highlighting, no "this person appears on another board!" popup. The player connects the dots.
|
||||
6. **Monologue as diagram interaction surface.** When the player focuses a board node, the monologue system can fire character-specific commentary. "He was at both meetings" is monologue, not board UI. This connects the active information system (Q-053) to the passive hint system (Q-052).
|
||||
7. **Board as relationship with an information source.** Every board has a creator — the upstream system that owns the data and pushed it. The creator's framing shapes the initial state: initial nodes are their view of the situation, gaps are what they didn't know, chose not to include, or deliberately withheld. The gap between a board's initial state and its final state is the story the board tells.
|
||||
8. **Confidence signal as information asymmetry.** Nodes need a confidence state: initial nodes from the creator are unconfirmed (faint); player-observed nodes are confirmed (solid). The distinction between "what you were told" and "what you know" is the information asymmetry mechanic expressed at the board level.
|
||||
9. **Boards as entitlement map.** The boards in a player's workspace are a map of their information entitlements — which systems trust them with data, which factions include them in their information flows, which institutions grant them access.
|
||||
- **Transit maps — core navigation mechanic:**
|
||||
- Transit maps are boards whose upstream system is the navigation/transport layer, not the political geography layer. They respond to political geography (route closures, faction control) but their primary function is **how the player gets around**.
|
||||
- Implementation: Network renderer with position-constrained layout mode (nodes pinned to world coordinates). Same rendering primitive as investigation boards (free layout mode), different layout constraint.
|
||||
- Transit maps exist from day one as a live, simulation-fed surface — not a static reference image.
|
||||
- **Archetype overlays are incidental discovery.** The smuggler's inspection-schedule annotation and the detective's jurisdiction boundary are visible through ordinary navigation, not special investigation mode. The player opens the map to travel and notices the secondary reading. Archetype depth surfaces through constant ordinary use. Design constraint: overlays must be subtle enough not to clutter the primary navigation function.
|
||||
- **Highest-frequency convergence surface.** Because the transit map is opened constantly, it is the most likely place for board nodes and navigation context to appear together without the player looking for it. A location that is a node on any active board shows its consistent visual identity on the transit map — same glyph, same colour. Player recognition does the work.
|
||||
- **Change over time is the political layer.** Because the map is used constantly, changes to it are noticed: a gate that was open is now restricted, an inspection checkpoint appeared on a familiar route. Infrastructure changes accumulate into a picture of what is shifting in the world — the conspiracy is visible in the map before it is visible in any individual NPC's behaviour.
|
||||
- **Scaling properties:**
|
||||
- v0.1: one or two board types (investigation + transit map) validate the rendering primitive and workspace navigation.
|
||||
- Full game: boards proliferate naturally as upstream systems ship — business dashboards, faction maps, crew manifests, engineering schematics, social network visualisations, reference material (field guides, legal codes).
|
||||
- Board count is not a design problem — it's a UX problem (workspace navigation, tab management, search/filter). The primitive scales inherently.
|
||||
- **Context:** Raised during Sprint 22 planning. Initial framing included d2 syntax as in-game format; lead directed that d2 remains a dev tool only and is not involved in the in-game system. Analysis by Gestalt (systems) and Paula (narrative) across three rounds with multiple lead corrections.
|
||||
- **Cross-reference:** Q-054 (rendering primitive data contract — the technical "how"), Q-052 (storyteller hint delivery — boards as the complementary active system), D-056/D-057 (insert diegetic conventions)
|
||||
- **Assigned to:** Gestalt, Paula
|
||||
|
||||
### Q-054: Insert workspace board — rendering primitive and data contract
|
||||
- **Status:** Open
|
||||
- **Priority:** High
|
||||
- **Question:** What is the board rendering primitive and its data contract? A board is a **general-purpose structured information surface** rendered inside the insert workspace. The renderer is agnostic to data source — it takes structured data and draws it. Upstream systems (quests, journal, navigation, faction tracking, reference material, business management, or anything with structured data worth visualizing) are responsible for creating boards, populating them, and managing their lifecycle. The renderer does not know or care why a board exists.
|
||||
- **Renderer architecture (Sprint 22 analysis):**
|
||||
- The renderer is a **stateless display service**. It takes `DiagramData` and draws it. It has no opinion on why a board exists, what created it, or what the data means.
|
||||
- Data contract: `DiagramData { id: DiagramId, diagram_type: Network | Flow | Table | Spatial, interaction_schema: InteractionSchema, annotations: Vec<PlayerAnnotation> }` plus type-specific content (nodes/edges, rows/columns, layers).
|
||||
- The renderer fires interaction events when the player clicks/hovers. Upstream systems handle those events.
|
||||
- Player annotations: renderer fires an annotation event upstream → server stores it → next `DiagramData` push includes the annotation. The renderer never holds its own copy of annotations or board state. Stateless rendering keeps save/load trivial.
|
||||
- The server includes the current `DiagramWorkspace` state in the `ObserverSnapshot`. The workspace is a list of `DiagramData` instances the player currently has access to.
|
||||
- Four rendering modes (Network, Flow, Table, Spatial). Two layout strategies for Network (free and position-constrained). A thin interaction event layer. That is the entire scope of the rendering infrastructure.
|
||||
- **Open design questions:**
|
||||
1. **Data contract details:** What node and edge types must the v0.1 contract support? Minimum viable: typed nodes + typed edges + optional metadata (label, confidence, timestamp).
|
||||
2. **Rendering vocabulary:** What visual primitives does the renderer expose — node shapes, edge styles, grouping/clustering, highlight states? What is explicitly out of scope for v0.1?
|
||||
3. **Lifecycle API:** What interface does an upstream system use to create, update, and close a board? Is this an ECS component, an IPC message, a client-side data structure, or some combination?
|
||||
4. **Player agency:** Is the board a read-only surface (upstream system writes, player reads) or can the player annotate — add notes, draw edges, pin nodes? If player writes are allowed, who owns that state? (Sprint 22 analysis: server owns annotation state; renderer is stateless.)
|
||||
5. **Insert integration:** How does the board surface within the insert UI — as a spoke, a workspace tab, a contextual overlay? How does the player navigate between multiple open boards?
|
||||
6. **v0.1 scope:** What is the minimum board implementation that validates the primitive — one upstream consumer, one node type, one edge type — without committing to a full vocabulary prematurely?
|
||||
- **Context:** Q-052 §scaling note flagged "a complementary active system (case board, network map) the player reads rather than passively receives" as out of scope for the hint delivery question. This is that system. Lead direction (Sprint 22): the rendering infrastructure is agnostic to data source; what attaches to a board, what populates it, and what its lifecycle is are decisions owned by the upstream system, not the renderer.
|
||||
- **Source:** Team Lead direction, Sprint 22 planning, 2026-02-28.
|
||||
- **Assigned to:** Gestalt, Paula
|
||||
- **Cross-reference:** Q-053 (board design philosophy — the "what" and "why"), Q-052 (storyteller hint delivery — boards noted as separate design problem), D-056/D-057 (insert diegetic conventions), D-023 (storyteller — one natural upstream consumer), D-024 (NPC axes — node content candidate)
|
||||
|
||||
---
|
||||
|
||||
*9 questions (5 resolved, 1 partially resolved, 3 open). Last updated: 2026-02-28.*
|
||||
@@ -0,0 +1,184 @@
|
||||
# Open Questions — Process
|
||||
|
||||
How the team works: workflow mechanics, cadence, ceremony, release rhythm.
|
||||
|
||||
---
|
||||
|
||||
### Q-096: Replace sprint workflow with kanban + milestones
|
||||
|
||||
- **Status:** Resolved — see D-221
|
||||
- **Date raised:** 2026-04-20
|
||||
- **Last updated:** 2026-05-01 (expanded from "should we?" to concrete proposal with test plan)
|
||||
- **Raised by:** Jeroen
|
||||
- **Assigned to:** Jeroen (final call)
|
||||
|
||||
---
|
||||
|
||||
#### Problem Statement
|
||||
|
||||
Sprints were introduced when the workflow was framed as Scrum-adjacent. Across 38 sprints, the failure modes have sharpened beyond the original "ceremony overhead" concern into structural problems with how agents interpret sprint-shaped work.
|
||||
|
||||
**Original concerns (Sprint 36):**
|
||||
|
||||
| Mechanism | Compensates for | Applies here? |
|
||||
|---|---|---|
|
||||
| Time-box (1-2 weeks) | Humans need deadline pressure to scope | No — Claude scopes on demand |
|
||||
| Retro | Team learning ritual, morale | No — adjustments land as rule/memory edits immediately |
|
||||
| Burndown / velocity | Estimation & planning for multi-person roadmaps | No — solo dev, no external stakeholders |
|
||||
| Demoable increments | External stakeholder cadence | No external stakeholders |
|
||||
| Sprint-kickoff ceremony | Re-energize after context loss | Context loss is per-session, not per-sprint |
|
||||
| Version bump at sprint close | Predictable shippable cadence | `v0.1.{sprint_number}` doesn't reflect feature progress |
|
||||
|
||||
**New failure modes observed (Sprint 37-38):**
|
||||
|
||||
1. **Ticket-as-contract.** Agents execute the letter of the ticket instead of reading the code and doing what's actually right. If the ticket says "implement X using approach Y," the agent implements Y even when the codebase clearly suggests Z. The ticket becomes a shield against thinking.
|
||||
|
||||
2. **Artificial delay.** Work that's ready gets parked because it's "next sprint." Work that's blocked gets thrashed because it's "this sprint." The sprint boundary creates urgency and delay simultaneously.
|
||||
|
||||
3. **Role theater.** Agents treat team-scope restrictions (server team can't touch client files) as hard boundaries when the fix is a one-liner. This models a human org chart, not the reality of one person and a context window.
|
||||
|
||||
4. **Order rigidity.** Agents unwilling to reorder work when dependencies shift, because the briefing prescribed a sequence. Sprint briefings go stale instantly (Sprint 38 server briefing was missing 26 tickets within a day of creation).
|
||||
|
||||
5. **Locking on bad design.** Agents commit to approaches described in tickets even when implementation reveals the design was wrong. The ticket's authority overrides what the code is telling them.
|
||||
|
||||
6. **Self-review collapse.** Coding agents write code, create the PR, review their own PR, approve it, and push — all in one convergent context. The adversarial review pipeline collapses because the reviewer has all the author's context and biases. PR comments aren't posted, review gates are skipped, the entire point of separate reviewer personalities is defeated. Requires constant human intervention to enforce.
|
||||
|
||||
**Compounding factors (May 2026):**
|
||||
|
||||
- Claude Code team-mode harness partially broken (v2.1.123: custom agent types missing SendMessage, shutdown doesn't work, TeamDelete doesn't kill panes). Workaround exists but fragile.
|
||||
- Opus 4.7 prompt quality ("floatiness") makes the problem worse — agents are already less precise, and rigid ticket framing doesn't compensate, it amplifies.
|
||||
|
||||
---
|
||||
|
||||
#### Proposal: Kanban + Milestones + Adversarial Personalities
|
||||
|
||||
**What stays:**
|
||||
|
||||
| Element | Why it stays |
|
||||
|---------|-------------|
|
||||
| Cascade phases | Macro direction — what to build in what order |
|
||||
| Agent personalities + briefings | Adversarial diversity — the real purpose is breaking convergence patterns by seeding different thinking via personality prompts. Not role-play, divergence engines. |
|
||||
| D-records | Decisions are decisions regardless of process |
|
||||
| Tickets | Track what needs doing — but descriptive, not prescriptive |
|
||||
| Workshops | The format where adversarial diversity pays off. Unchanged. |
|
||||
| Rules/memory | Live institutional knowledge, immediate course correction |
|
||||
|
||||
**What changes:**
|
||||
|
||||
| Old | New |
|
||||
|-----|-----|
|
||||
| Sprint numbers, sprint boundaries | Milestones tied to concrete deliverables (cascade phase, feature gate) |
|
||||
| Sprint briefings (pre-baked, go stale) | Session startup: `ticket list --status in_progress` + blocked-by graph |
|
||||
| Team branches (sprint-N/server) | Topic branches per logical chunk, any agent can touch any file |
|
||||
| File-scope restrictions per agent | Removed — personalities guide perspective, not file access |
|
||||
| Author and reviewer in same session | Worktree isolation enforced: reviewer spawns in separate worktree, reads diff cold |
|
||||
| Version `v0.1.{sprint_number}` | `v0.{phase}.{n}` tied to cascade phases |
|
||||
| Sprint-close cleanup sweep | Pre-push clerk hook (automated) + milestone-boundary audit (manual) |
|
||||
| Si (project manager) + Qatux (librarian) as separate agents | Merged into "clerk" agent — institutional guardrail |
|
||||
| Sprint velocity tracking | WIP limits per work-type (max N tickets in_progress) |
|
||||
|
||||
**What dies:**
|
||||
|
||||
- Sprint CLI (`tooling/db/sprint`)
|
||||
- Sprint briefing files (`docs/sprints/sprint-N/`)
|
||||
- Sprint-kickoff and sprint-close ceremonies
|
||||
- The Si agent as a standalone personality
|
||||
- Team-scoped file restrictions in CLAUDE.md
|
||||
|
||||
**Personalities are not teams.** Gestalt, Tyre, Paula, Burnelli-Sheldon, etc. survive as prompt-seeded divergence engines. They make pushback legible — when Jeroen sees a Burnelli-Sheldon objection he knows it's an economics concern, when he sees a Paula objection he knows it's a narrative/political concern. The personality is the signature, not a job description.
|
||||
|
||||
**Worktrees are context firewalls, not team boundaries.** Branches and worktrees survive — but their purpose changes from "team scope" to "context isolation." The reason a coding agent self-reviews its own PR is that it has all the context of writing the code. A reviewer spawned in a separate worktree physically cannot have that context — it reads the diff cold, which is exactly what a reviewer should do. The worktree enforces adversariality at the mechanism level, not the process level. This is an argument FOR keeping branch/worktree separation even after killing team-scoped restrictions.
|
||||
|
||||
---
|
||||
|
||||
#### Clerk Agent (Si + Qatux merge)
|
||||
|
||||
The team lead (interactive Claude session) optimizes for the user's current intent. This makes it structurally incapable of being the institutional guardrail — it will go along with whatever the user says in the moment, even if it contradicts a decision from three weeks ago.
|
||||
|
||||
The clerk is the separation of concerns between **responsiveness** (team lead) and **institutional memory** (clerk).
|
||||
|
||||
**Pre-push hook implementation:**
|
||||
|
||||
1. Pre-push hook spawns clerk agent with the diff
|
||||
2. Agent checks D-record consistency, ticket drift, contradiction with active decisions
|
||||
3. Agent writes findings to `.cache/pre-push-review.md`
|
||||
4. Agent outputs exactly one word: `APPROVED` or `REJECTED`
|
||||
5. Hook reads the word, exits 0 or 1
|
||||
6. **Timeout behavior:** if agent doesn't respond within N seconds, automatic `REJECTED`. Agent keeps running in background — findings file arrives later. User reads it, decides whether to fix or force-push.
|
||||
|
||||
The findings file separates the agent's reasoning from its authority. Binary gate, verbose reasoning.
|
||||
|
||||
**What the clerk checks:**
|
||||
- Changed files don't contradict active D-records
|
||||
- Referenced decisions still exist
|
||||
- Implementation doesn't drift from ticket intent (but ticket is descriptive, not prescriptive — drift is flagged, not blocked)
|
||||
- Q-records relevant to changed files are surfaced
|
||||
|
||||
**What the clerk does NOT do:**
|
||||
- Subjective code quality review (that's /pr-review)
|
||||
- Sprint management (no sprints)
|
||||
- Briefing maintenance (briefings replaced by live ticket queries)
|
||||
|
||||
---
|
||||
|
||||
#### Test Run Plan
|
||||
|
||||
**Scope:** The Tier 0/Tier 1 cascade work — all schema tables and Python importers from the planet-down-cascade workshop.
|
||||
|
||||
**Milestone definition:** "All schema tables and Python importers land on main. `make regen-db` produces a DB with heightmaps, city names, province boundaries, body_radius_km, normalized economic_role."
|
||||
|
||||
**Rules for the test run:**
|
||||
- No sprint number assigned
|
||||
- Topic branches per logical chunk (not team branches)
|
||||
- Any agent personality can touch any file
|
||||
- Tickets describe what needs doing, not how
|
||||
- WIP limit: 3 tickets in_progress at once
|
||||
- Milestone complete when all Tier 0 + Tier 1 tickets are done and verified
|
||||
|
||||
**What we're measuring:**
|
||||
1. Did work flow or stall without sprint pressure?
|
||||
2. Did removing file-scope restrictions cause chaos or remove friction?
|
||||
3. Did tickets-as-description work, or did agents flail without prescriptive tickets?
|
||||
4. Did anything get worse compared to Sprint 38's current state?
|
||||
|
||||
**Rollback trigger:** If after the test run the work feels less productive or less controlled than a sprint, Sprint 39 picks up where 38 left off. All sprint tooling remains in the codebase — dead code, not deleted code.
|
||||
|
||||
**Parallel work (independent of test run outcome):**
|
||||
- Build the clerk pre-push hook — pure additive, helps regardless of process
|
||||
- Can be tested against Sprint 38 pushes before the process switch
|
||||
|
||||
---
|
||||
|
||||
#### Risks
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|-----------|
|
||||
| No natural "stop and audit" moment | Clerk pre-push hook + milestone-boundary manual audit |
|
||||
| Work sprawl without sprint focus | WIP limits enforce focus; milestones enforce shipping |
|
||||
| Losing the "signature" on who did what | Personalities preserved — commits and PRs still carry agent identity |
|
||||
| Process change is a distraction from actual development | Test run uses real cascade work, not meta-work. Process change is the test. |
|
||||
| Can't roll back cleanly | Sprint tooling stays in repo. Reversible. |
|
||||
| Clerk agent too slow / too noisy | Timeout-reject for speed. Tune signal-to-noise over first milestone. |
|
||||
|
||||
---
|
||||
|
||||
#### Decision Timeline
|
||||
|
||||
1. **Now:** Sprint 38 continues as-is
|
||||
2. **Sprint 38 close:** Decision point — run test milestone or Sprint 39
|
||||
3. **During test milestone:** Build clerk pre-push hook in parallel
|
||||
4. **Test milestone complete:** Evaluate against measurement criteria
|
||||
5. **If positive:** Write D-record confirming kanban + milestones. Kill sprint tooling.
|
||||
6. **If negative:** Sprint 39. Revisit after more Claude Code harness fixes.
|
||||
|
||||
---
|
||||
|
||||
**Related:**
|
||||
- `feedback_broken_tests_not_preexisting_shield.md` — pattern sprints may enable
|
||||
- tmux teammate mode: confirmed working on Claude Code 2.1.148 (the earlier "broken" status was a `teammateMode: in-process` config issue, not a regression)
|
||||
- Epic #854 — pipeline discipline automation
|
||||
- D-166 — cascade phases
|
||||
|
||||
---
|
||||
|
||||
*Open count: 0.*
|
||||
@@ -0,0 +1,121 @@
|
||||
# Open Questions — Scope
|
||||
|
||||
Game concept, prototype boundaries, production pipeline, and feature decisions.
|
||||
|
||||
---
|
||||
|
||||
### Q-002: Scope of v0.1 playable prototype
|
||||
- **Status:** Resolved → [D-117](../decisions/scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content), [D-166](../decisions/architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order)
|
||||
- **Resolution:** The v0.1 prototype framing is superseded. D-117 establishes the tycoon as the v0.2 bookmark; D-166 defines the 6-phase development cascade as the authoritative build order. Prototype scope is determined by the cascade phases, not a standalone v0.1 spec.
|
||||
- **Date resolved:** 2026-03-24 (D-166 development cascade)
|
||||
- **Assigned to:** Full team
|
||||
|
||||
### Q-004: One campaign spanning all eras or separate era scenarios?
|
||||
- **Status:** Resolved (implicitly) → [D-117](../decisions/scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content), [D-166](../decisions/architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order)
|
||||
- **Resolution:** v0.2 is single-era (contemporary Settled Reach). The development cascade (D-166) defers all multi-era considerations well beyond current scope. The question remains interesting for the full game but is not load-bearing for any active phase.
|
||||
- **Date resolved:** 2026-04-05 (closed as implicitly resolved)
|
||||
- **Assigned to:** Gore, Miri to lead discussion
|
||||
|
||||
### Q-005: Scale for prototype - locations, characters, factions
|
||||
- **Status:** Resolved → [D-117](../decisions/scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content), [D-118](../decisions/scope.md#d-118-small-business-owner-starting-state--3-configurations), [D-166](../decisions/architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order)
|
||||
- **Resolution:** Scale is determined by the development cascade (D-166), not pre-scoped. 301 systems in the star map. All NPCs generated (D-122). Single character type (tycoon, D-117). Starting configurations defined in D-118. The "~10-20 characters" estimate is obsolete — NPC count is a generator output, not a hand-authored target.
|
||||
- **Date resolved:** 2026-03-24 (D-166 development cascade)
|
||||
- **Assigned to:** Gestalt, Tyre, Miri
|
||||
|
||||
### Q-007: Target platform(s)
|
||||
- **Status:** Resolved (implicitly) → [D-020](../decisions/architecture.md#d-020-engine-and-architecture-selection--godot-client--rust-simulation-via-subprocessipc)
|
||||
- **Resolution:** Godot 4 + Rust architecture (D-020) inherently supports cross-platform via Godot's export system. Primary development on Linux (Fedora). No platform-specific constraints have emerged. Cross-platform export is a deployment task, not an architectural decision.
|
||||
- **Date resolved:** 2026-04-05 (closed as implicitly resolved)
|
||||
- **Assigned to:** Tyre
|
||||
|
||||
### Q-008: Licensing / distribution model
|
||||
- **Status:** Not yet discussed
|
||||
- **Question:** Open source? Free? Commercial? This affects engine choice and asset decisions.
|
||||
- **Assigned to:** Team Leader
|
||||
|
||||
### Q-011: Character selection and playable characters
|
||||
- **Status:** Resolved → [D-117](../decisions/scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content), [D-115](../decisions/scope.md#d-115-character-creation-scoped-to-skills--bookmark-for-v02), [D-122](../decisions/content.md#d-122-all-npcs-generated--no-named-hand-authored-characters)
|
||||
- **Resolution:** v0.2 has one playable character type: the tycoon (small business owner starting state, D-118). One bookmark. All NPCs are generated — no canon named characters. Character creation is skills + bookmark only. The "how different are their starting positions?" question is answered by the small business owner economic variation (D-118: bar, logistics contract, storage franchise as starting configurations). The "canon characters vs original" question is answered by D-122: all NPCs generated, no canon characters exist in v0.2.
|
||||
- **Date resolved:** 2026-03-05 (Where's the Fun? Workshop)
|
||||
- **Question:** Which characters are playable in the prototype? How different are their starting positions? Can you play canon characters or only original ones?
|
||||
- **Assigned to:** Miri, Paula
|
||||
|
||||
### Q-027: Fast-travel system design
|
||||
- **Status:** Open
|
||||
- **Question:** How does inter-system travel work in production gameplay? The current hub teleport (Home key, #501) is scoped as Gauntlet-only dev tool. Production travel must be diegetic and respect asymmetric information. Proposed flow: player goes to local gate → warps to system gate → interacts with target menu → jumps to destination system gate. Key constraints:
|
||||
1. **Region gating:** fast-travel only available from safe or fast-travel-enabled regions. If you rented transport to reach a remote location (e.g. mountain colony), you must return the transport to civilization first — this can be a skip-travel interaction but must happen in-world.
|
||||
2. **Asymmetric information:** NPCs observe arrivals and departures. Travel choices leak information (who saw you leave, who sees you arrive, what transport was used).
|
||||
3. **Home key in production:** at most, Home could prompt "Do you want to fast-travel to the system hub?" if in a safe/enabled region — never instant teleport.
|
||||
4. **Transport types:** walking, rented vehicle, public transit, gate network — each with different information exposure profiles.
|
||||
- **Context:** #501 implemented instant Home key teleport gated behind `gauntlet_mode`. Re-scoped to Gauntlet-only after design review. Production fast-travel needs separate design and implementation.
|
||||
- **Assigned to:** Gestalt, Paula, Tyre
|
||||
- **Source:** Sprint 10 PR review discussion (2026-02-19)
|
||||
|
||||
### Q-032: Cultural ingredients menu
|
||||
- **Status:** Open
|
||||
- **Question:** Should world generation use a 6-category cultural ingredients menu (Heritage Roots, Settlement Motivation, Economic Function, Philosophical Alignment, Corporate/Faction Presence, Drift Stage) where each culture is composed by selecting from ingredient lists? The lead approved the "ingredients menu" model over fixed cultural taxonomies. Full specification needed: category definitions, ingredient lists per category, composition rules, absence-as-signal mechanics.
|
||||
- **Assigned to:** Miri, Gestalt
|
||||
- **Source:** Wiki Review Workshop R4, lead interview
|
||||
|
||||
### Q-034: PC archetypes
|
||||
- **Status:** Partially resolved → [D-117](../decisions/scope.md#d-117-tycoon-is-the-v02-bookmark--zero-investigation-content) (v0.2 scope only: tycoon bookmark, zero investigation)
|
||||
- **Partial resolution:** v0.2 scope is settled — one bookmark (tycoon, small business owner start per D-118). Smuggler and detective are abandoned for v0.2. The full 8-archetype model, fluid archetype transitions, and "vulnerable window" mechanics remain undesigned for the full game. The "detective, smuggler, tycoon are jobs you can have, not the game's identity" framing (Where's the Fun? Workshop) is the guiding principle for future archetype design.
|
||||
- **Question:** Should the full game support 8 fluid PC archetypes (Smuggler, Detective, Engineer, Diplomat, Medic, Scholar, Soldier, Merchant) with transition mechanics where archetype shifts during play based on player behavior? The lead approved 8 archetypes with fluid transitions as a game mechanic. v0.1 ships smuggler + detective only (D-027). Full archetype spec, transition triggers, and "vulnerable window" mechanics are undesigned. NOTE: The character-creation-game-setup workshop (Q-011) will address this — coordinate.
|
||||
- **Assigned to:** Nigel, Gestalt
|
||||
- **Source:** Wiki Review Workshop R4, lead interview
|
||||
|
||||
### Q-035: Sacred/Profane/Middle Kingdom framework
|
||||
- **Status:** Open
|
||||
- **Question:** Should all game systems map to a Sacred/Profane/Middle Kingdom architectural framework? The lead approved this model where Sacred = what the system protects, Profane = what threatens it, Middle Kingdom = where the player navigates. The wiki-review workshop produced a full mapping table covering information, social, economic, spatial, temporal, and narrative systems. Needs formal specification and validation against current architecture.
|
||||
- **Assigned to:** Gore, Gestalt
|
||||
- **Source:** Wiki Review Workshop R4, lead interview
|
||||
|
||||
### Q-036: District skeleton as generator output
|
||||
- **Status:** Open
|
||||
- **Question:** For the 300-world model, should the district skeleton (social sites, NPC slots, triangle templates, economic function, access topology) be the atomic output unit of the world generator? D-025 defines social sites as the atomic template unit for hand-authoring. The generator model reframes the district as a composed output from ingredient inputs. How does this interact with D-025?
|
||||
- **Assigned to:** Tyre, Gestalt
|
||||
- **Source:** Wiki Review Workshop R4
|
||||
|
||||
### Q-037: Generator development pipeline
|
||||
- **Status:** Partially resolved → [D-119](../decisions/scope.md#d-119-generator-spike-confirmed-for-sprint-25--critical-path), [D-166](../decisions/architecture.md#d-166-development-cascade--6-phase-first-things-first-build-order)
|
||||
- **Partial resolution:** D-166 (development cascade) establishes a strict 6-phase build order. The generator falls in Phase 5 (World Generation), not Phase 1. D-119's Sprint 25 sequencing is superseded by the cascade. The 6-phase pipeline spec (Ingredient Authoring, Template Authoring, Generator Development, Validation Development, Generation + Review, Hand-Elevation) remains open pending Phase 5.
|
||||
- **Question:** Should content production follow a 6-phase generator pipeline (Ingredient Authoring, Template Authoring, Generator Development, Validation Development, Generation + Review, Hand-Elevation)? The wiki-review workshop proposed this as the production model for 300 worlds. SI mapped a release path (v0.1 hand-authored, v0.2-0.5 template expansion, v0.6-0.10 generator development, pre-v1.0 validation). Needs scope assessment and sprint planning integration.
|
||||
- **Assigned to:** SI, Tyre
|
||||
- **Source:** Wiki Review Workshop R4
|
||||
|
||||
### Q-038: Authored content estimate at 300-world scale
|
||||
- **Status:** Open
|
||||
- **Question:** What is the irreducible authored content volume for 300 worlds? The wiki-review workshop estimated ~1,600-2,800 hours of hand-authoring for generator inputs (ingredient definitions, template specifications, validation rules, hand-elevation passes). How does this compare to the 20-district hand-authoring model it replaced? Is this estimate still valid given subsequent architectural decisions?
|
||||
- **Assigned to:** Mellanie, SI
|
||||
- **Source:** Wiki Review Workshop R4
|
||||
|
||||
### Q-039: Gate topology generation
|
||||
- **Status:** Resolved → D-095 (amended), star-map.json, systems.db
|
||||
- **Question:** How should the world generator produce gate (wormhole) network topology for 300 worlds? The wiki-review workshop proposed: gate connectivity = Sacred (what connects), which worlds connect = Profane (what separates), accessible world count = Middle Kingdom (where the player navigates). Small-world network properties, hub-and-spoke vs mesh topology, and Sacred/Profane constraints on gate placement are all unresolved. D-012 covers chunk-based map architecture but predates the 300-world model.
|
||||
- **Resolution:** 301-system star map generated and populated. Topology is alien-determined (horizon station infrastructure), producing a small-world network with hub-and-spoke characteristics: 3 hub systems (5 apertures), junction nodes (3-4 apertures), loop members (2), and spur ends (1). The distribution was sculpted through iterative passes (`generate-star-map.py`, `sculpt-star-map.py`, `tune-star-map-topology.py`, `patch-core-sector.py`) to produce realistic network properties. Gate connections are stored in `star-map.json` (334 edges) and `server/data/systems.db` (system_gates table). Sacred/Profane framing resolved: connections are Sacred (alien-given, not human-chosen); what humans do with them is Profane.
|
||||
- **Assigned to:** Tyre, Nigel
|
||||
- **Source:** Wiki Review Workshop R4
|
||||
|
||||
---
|
||||
|
||||
### Q-058: Runtime behavior text serving system
|
||||
- **Status:** Open
|
||||
- **Question:** How should NPC observable behaviors be served to the client at runtime? `NpcBlueprint.observable_behaviors` exists as generator output but no runtime system reads it or sends behavior text to the client. The voice pipeline (D-138) needs an integration point: voice cache lookup replaces base text with re-voiced text before delivery. Needs: which system selects the current behavior, how it's delivered in `ObserverSnapshot`, and how tell behaviors (always passthrough) are distinguished from voiceable behaviors.
|
||||
- **Assigned to:** Tyre, SI
|
||||
- **Source:** Voice pipeline Spike 2 Phase 3
|
||||
|
||||
### Q-061: How many base clothing meshes needed for v0.2 proof-of-life?
|
||||
- **Status:** Open
|
||||
- **Question:** The Quaternius Fantasy pack (62 parts) is genre-incompatible with an industrial sci-fi life-sim. What is the minimum viable clothing catalogue for the v0.2 proof-of-life milestone? Needs a scope decision before clothing work begins. The multiplier stack (30 base meshes × shape keys × AI textures × tint = ~20K visual variants) was identified during the spike but the base mesh count is arbitrary.
|
||||
- **Assigned to:** Gestalt, Araminta
|
||||
- **Source:** Quaternius aesthetic spike — clothing pipeline research
|
||||
|
||||
### Q-062: What does Quaternius Source tier include for body types?
|
||||
- **Status:** Open
|
||||
- **Question:** The standard tier only includes Superhero Male and Female body meshes. Does the Source tier ($5/mo Patreon) include Regular and Tiny body meshes in full Blender format? These would provide 2 additional body types (mapping to Average and Thin in D-159) that could be forked and segmented, reducing the hand-authoring burden from 9 to 5 meshes.
|
||||
- **Assigned to:** Jeroen (acquisition decision)
|
||||
- **Source:** Quaternius aesthetic spike
|
||||
|
||||
---
|
||||
|
||||
*17 questions (6 resolved, 3 partially resolved, 8 open). Last updated: 2026-04-05 (Q-002, Q-004, Q-005, Q-007 closed as resolved)*
|
||||
@@ -0,0 +1,43 @@
|
||||
# Rejected Alternatives — Architecture
|
||||
|
||||
Rejected proposals in the **architecture** domain, rationale preserved for the audit trail.
|
||||
|
||||
### R-001: Stellaris mod
|
||||
- **Rejected:** 2026-02-08
|
||||
- **Reason:** Character system too shallow, multi-empire assumption conflicts with the Settled Reach's single-civilization focus, wormhole-as-infrastructure not achievable within Stellaris modding. Team Leader's experience with Star Trek: New Horizons confirmed that even well-suited IPs struggle with character connection in Stellaris.
|
||||
|
||||
### R-002: CK3 total conversion
|
||||
- **Rejected:** 2026-02-08
|
||||
- **Reason:** Would require building a space map from scratch within CK3's framework - essentially building a game inside a game. The map system fundamentally doesn't support the complexity needed.
|
||||
|
||||
### R-003: Other existing games (Distant Worlds 2, GalCiv IV, Sins of a Solar Empire II, Victoria 3)
|
||||
- **Rejected:** 2026-02-08
|
||||
- **Reason:** Each captures at most 40% of what's needed. Smaller modding communities, less mature tools, and none solve the core CK3+Stellaris hybrid requirement.
|
||||
|
||||
### R-004: Pure Bevy (Rust) — no Godot
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** No visual editor (level design is code-only). UI framework in flux. API breaks significantly between versions. For a solo developer who needs visual tools for hand-crafted buildings ([D-014](../decisions/scope.md#d-014-v01-map-specification)), Godot's editor is a massive productivity advantage. Bevy's ECS is used — just not its renderer.
|
||||
|
||||
### R-005: Pure Godot (GDScript or C#)
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** Scene tree paradigm fights ECS-style simulation. Perception queries ([D-017](../decisions/perception.md#d-017-perception-modes-as-character-build-system)) and information boundaries ([D-010](../decisions/architecture.md#d-010-multiplayer-ready-architectural-baseline)) map naturally to ECS component queries, not scene tree traversal. Multi-core scaling for expanded content impossible in GDScript. Kept as kill-switch fallback if Rust architecture exceeds time budget.
|
||||
|
||||
### R-006: Godot + Rust via GDExtension
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** gdext is pre-1.0 with breaking API changes. Godot version upgrades break GDExtension ABI. Thread safety at FFI boundary is CRITICAL risk (`Gd<T>` is `!Send`/`!Sync`). Couples Rust and Godot learning curves. Subprocess/IPC achieves the same architecture without the FFI risk surface, and maps directly to [D-010](../decisions/architecture.md#d-010-multiplayer-ready-architectural-baseline) client-server. See `docs/architecture/risk-godot-rust-bridge.md` for full analysis.
|
||||
|
||||
### R-007: Godot + C++ via GDExtension
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** More mature bindings than gdext, but trades Rust's safety guarantees for C++ memory unsafety. No advantage over subprocess/IPC approach. Developer not experienced in C++.
|
||||
|
||||
### R-008: Fyrox (pure Rust engine)
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** Single maintainer. ~1/50th of Godot's community. Less documentation, fewer tutorials, weaker AI training data for Claude Code. Single-maintainer risk unacceptable for multi-year project.
|
||||
|
||||
### R-009: Custom framework (Rust + raylib/macroquad)
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** Maximum control but you build everything — tilemap rendering, camera, UI, audio, input, asset pipeline. Months before testing a mechanic. The game's hard problems are simulation, not rendering — don't reinvent the rendering wheel.
|
||||
|
||||
### R-010: protobuf for client-server serialization
|
||||
- **Rejected:** 2026-02-09
|
||||
- **Reason:** Schema evolution across independent deployments is a problem we don't have (one developer, client and server ship together). Poor GDScript support. Rigid schema fights dynamic HUD composition driven by perception modes ([D-017](../decisions/perception.md#d-017-perception-modes-as-character-build-system)). MessagePack's schema-optional nature fits better.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Rejected Alternatives — Economics
|
||||
|
||||
Rejected proposals in the **economics** domain, rationale preserved for the audit trail.
|
||||
|
||||
### R-011: Single currency for Phase 2 economics
|
||||
- **Rejected:** 2026-04-05
|
||||
- **Proposed by:** Burnelli-Sheldon (economist), Sprint 32 Workshop #796 Round 1
|
||||
- **Proposal:** Use a single currency for the Phase 2 economics simulation to reduce model complexity; exchange-rate mechanics could be added in a later phase.
|
||||
- **Reason:** Three currencies create structural economic bloc tension as an emergent property of initialization, requiring no event generation. The Tractus/Mark divide maps directly to the canonical Assembly vs. Compact political divide. Deferring to a later phase would require retrofitting political geography into a running simulation. Complexity cost low; design value high.
|
||||
- **Raised by:** Lead directive overruling the recommendation.
|
||||
- **Cross-reference:** [D-171 (economics.md)](../decisions/economics.md#d-171-three-currency-system)
|
||||
- **Note:** Canonical location is `rejected.md`. Two duplicate copies in `economics.md` were removed 2026-06-06 (id-collision cleanup).
|
||||
@@ -0,0 +1,8 @@
|
||||
# Rejected Alternatives — Perception
|
||||
|
||||
Rejected proposals in the **perception** domain, rationale preserved for the audit trail.
|
||||
|
||||
### R-012: Overheard NPC conversation system (D-078) — scrapped
|
||||
- **Rejected:** 2026-04-10
|
||||
- **Reason:** The entire NPC ambient interaction model (overheard conversations, room grammar, zone-type NPC population, behavior engine for physical spaces) is scrapped. These systems were designed speculatively before a walkable environment exists. The NPC interaction model will be designed and built from scratch after Phase 5 (world generation at tile level) is complete. All content authored against these systems (overheard.ron, zone-type conversation pools) is orphaned. Related content pattern note in content.md and D-078 in perception.md are superseded.
|
||||
- **Cross-reference:** D-078 (perception.md), content pattern note (content.md #664)
|
||||
Reference in New Issue
Block a user