Files
settled-reach/docs/design/content-structure-canonical.md
T
jpmschweitzer 23d9ff0a58 Merge remote-tracking branch 'origin/main' into planning
# Conflicts:
#	CHANGELOG.md
#	content/_meta/README.md
#	content/_meta/npc-authoring-style-guide.md
#	wiki/_templates/cultural-group.md
#	wiki/_templates/institution.md
#	wiki/_templates/star-system.md
#	wiki/characters/devra.md
#	wiki/characters/drin.md
#	wiki/characters/harek.md
#	wiki/characters/lera-sessik.md
#	wiki/characters/maret-korr.md
#	wiki/characters/naia-tamm.md
#	wiki/characters/nils-davan.md
#	wiki/characters/pell.md
#	wiki/characters/renn.md
#	wiki/characters/resha.md
#	wiki/characters/sabel.md
#	wiki/characters/sera-venn.md
#	wiki/characters/torek-lintar.md
#	wiki/characters/voss.md
#	wiki/star-systems/krenn/index.md
2026-03-14 00:24:53 +01:00

252 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Content Structure — Canonical Template (v0.2+)"
description: "Post-cleanup canonical directory layout for campaign content, superseding v0.1 content-directory-structure"
type: design
status: active
ticket: "#656"
decision_refs: [D-117, D-138]
author: ""
created: 2026-03-13
updated: 2026-03-13
---
# Content Structure — Canonical Template (v0.2+)
**Created:** 2026-03-13 (Sprint 26, #656 cleanup)
**Supersedes:** `content-directory-structure.md` v0.1 design spec (that doc describes the *removed* structure)
This document defines the canonical directory layout for campaign content after removal of v0.1 hand-authored dead weight. It is the template to replicate across 300 systems.
---
## Actual Directory Hierarchy
The real hierarchy (note: diverges from old design doc which used `content/districts/`):
```
content/
global/ # Cross-system content
culture-{name}.ron # Voice pipeline persona (LIVE GENERATOR INPUT)
culture-{name}.example.ron # Example output for reference
zone-identity-spec.example.ron # Zone identity template example
factions/ # Faction profiles (one per faction)
knowledge/ # Shared FactId catalog (one per category)
enums/ # Shared enum definitions
contraband/ # Contraband item profiles
technology/ # Technology definitions
campaigns/
main/
systems/
{system-slug}/ # e.g. van-maanens-star/
system.yaml # System metadata
stations/
{station-slug}/ # e.g. sova/
station.yaml # Station metadata
districts/
{district-slug}/ # e.g. transit/
district.yaml # Zone metadata (CANONICAL METADATA)
locations/ # Physical location definitions
templates/ # Social site role-slot definitions
triangles/ # Drama triangles (3-NPC clusters)
environmental/ # Environmental text (signs, terminals, docs)
routines/ # NPC schedule definitions
ticker/ # News ticker content
modules/
tier1/ # Tier 1 drama modules (authored)
{module-slug}.yaml
gauntlet/ # Test world (immutable — do not modify)
rooms/
_schema/ # JSON Schema validation files
_meta/ # Infrastructure metadata
schemas/ # (additional schemas)
```
---
## What Each Piece Is
| Path | Type | Who produces it | Notes |
|------|------|-----------------|-------|
| `global/culture-{name}.ron` | **Generator input** (authored) | Copy team | Voice pipeline persona. One per culture. DO NOT DELETE. |
| `global/factions/*.yaml` | **Authored** | Copy team | Faction profiles. One per faction. |
| `global/knowledge/*.yaml` | **Authored** | Copy team | FactId catalog by category. |
| `global/enums/*.yaml` | **Authored** | Copy team | Shared enum definitions (situations, moods, etc.) |
| `system.yaml` | **Metadata** | Copy team | System display name, factions present, setting notes. |
| `station.yaml` | **Metadata** | Copy team | Station description, district list. |
| `district.yaml` | **Metadata** | Copy team | Zone display name, location list, target NPC count. |
| `locations/*.yaml` | **Metadata** | Copy team | One file per location: display name, description, type. |
| `templates/*.yaml` | **Authored** | Copy team | Role slot definitions (what roles exist, capacity range). Survives to v0.2+. The `v01_assignments` field is v0.1-only — clear for generated content. |
| `triangles/*.yaml` | **Authored** | Copy team | Drama triangles with fork conditions and resolution states. Template material for generated equivalents. |
| `environmental/*.yaml` | **Authored** | Copy team | Environmental text objects with optional dual-lens properties (v0.1 remains). |
| `routines/schedules.yaml` | **Authored** | Copy team | NPC daily routines. Will be generated per-NPC in v0.2+. |
| `ticker/*.yaml` | **Authored** | Copy team | News ticker content for this district. |
| `modules/tier1/*.yaml` | **Authored** | Copy team | Drama modules (Paula's schema). |
---
## What Was Removed (v0.1 Dead Weight)
These directories and files existed in v0.1 and have been deleted (Sprint 26, #656/#657):
| Removed | Reason |
|---------|--------|
| `npcs/*.yaml` | Hand-authored named NPC profiles. Replaced by generator output. All 23 files deleted. |
| `dialogue/` | Hand-authored NPC dialogue pools per role/location. Replaced by voice pipeline. |
| `monologue/detective/` | Detective player monologue. Detective archetype removed per D-117. |
| `monologue/smuggler/` | Smuggler player monologue. Smuggler archetype removed per D-117. |
| `insert/detective.yaml` | Detective insert HUD content. |
| `insert/smuggler.yaml` | Smuggler insert HUD content. |
| `items/smuggler-inventory.yaml` | Smuggler item definitions. |
| `pools.yaml` | v0.1 NPC candidate pool definitions. All candidates referenced deleted NPCs. |
| `content/global/knowledge/investigation.yaml` | Investigation facts. Detective system removed. (Deleted in #657.) |
| `content/global/factions/lattice-commission.yaml` | Detective faction. (Deleted in #657.) |
| Several `docs/design/` detective/smuggler docs | Archetype design docs. (Deleted in #657.) |
---
## Canonical Template: New System Checklist
When adding a new system for v0.2+ (target: 300 systems), replicate this pattern:
```
content/campaigns/main/systems/{system-slug}/
system.yaml # 1. Author system metadata
stations/
{station-slug}/
station.yaml # 2. Author station metadata
districts/
{district-slug}/
district.yaml # 3. Author district metadata
locations/ # 4. Define locations (5-10 per district)
{location-slug}.yaml
templates/ # 5. Define social site templates (role slots)
{template-slug}.yaml
routines/ # 6. Author schedule structure
schedules.yaml # (v0.2: generated per NPC)
ticker/ # 7. Author news ticker content
{location-slug}.yaml
```
**Note:** `environmental/` and `triangles/` are authored for hand-crafted districts. For generated districts, these may be generated or omitted in v0.2+.
**No NPCs.** No dialogue. No monologue. Those are generator outputs, not authored inputs.
---
## Culture RON File Reference
Culture files are the primary input for the voice pipeline. One file per culture, living at `content/global/culture-{name}.ron`.
**Use `content/global/culture-van-maanens-star.ron` as the authoring template — not `culture-van-maanens-star.example.ron`.** The example file is an older stub without voice pipeline fields.
### Required fields (must be present)
```
id: "slug" # kebab-case, matches filename
name: "Display Name Culture"
description: "Single sentence: settlement age, location type, economic base, social character"
naming: (
style: # prose: phoneme style, casing norms
given_names: [...] # 30-50 names minimum for adequate generator variety
family_names: [...] # 10-20 names
family_name_used_socially: bool
)
speech: (
register: # prose: formality, rhythm, directness
filler_words: [...] # 4-8 words
greetings: [...] # 3-6 phrases
farewells: [...] # 3-6 phrases
exclamations: [...] # 4-8 oath/exclamation phrases
)
values: (
description: # prose: core value system
favored_traits: [...] # subset of valid traits (see below)
disfavored_traits: [...] # subset of valid traits
)
```
### Optional fields (omit or include as needed)
```
voice_persona: Some("PERSONA: ...") # Full LLM prompt persona block
voice_examples: [ # 3-5 input/output pairs
(input: "...", output: "..."),
]
occasional_injections: [ # Rolled per-prompt at given frequency
(
kind: "oath" # human-readable category label
clause: "When ... use ...", # LLM instruction text
example: Some((input: "...", output: "...")), # optional
frequency: 0.25, # 0.01.0
suppress_on_tells: [Guarded], # optional: omit injection when these tells active
),
]
behavior_modifiers: [ # Culture-specific action modifier clauses (#633)
(category: "work_style", clause: "with mechanical efficiency"),
]
```
### Valid enum values
**PersonalityTrait** (for `favored_traits` / `disfavored_traits`):
`Cautious, Bold, Honest, Deceptive, Compassionate, Ruthless, Curious, Incurious, Social, Reclusive`
**TellCategory** (for `suppress_on_tells`):
`Nervous, Angry, Friendly, Guarded, RoutineDeviation`
### voice_persona: NOT-list requirement (D-138, Spike 2)
Spike 2 found that **explicit NOT-lists in the persona block are critical** for voice quality. Without them, the LLM defaults to register-neutral generic output. Add an explicit "NEVER:" or "NOT:" section at the end of the persona block:
```
voice_persona: Some(
"PERSONA: ...\n
[positive instructions]\n\n
NEVER: [list 3-5 explicit negatives that define what this culture does NOT sound like]"
),
```
Example negatives for Van Maanen's Star (currently explicit in `culture-van-maanens-star.ron`):
- Never corporate or institutional language
- Never effusive, never polished, never deferential to rank
- Never flowery or verbose
- Never use family names in casual conversation
- Never express deference to authority that hasn't earned it
`culture-van-maanens-star.ron` has a full NEVER block in `voice_persona`. All three culture files (Van Maanen's Star, Vael, Osse) now include explicit NOT-lists. *(Updated Sprint 26 #653)*
### behavior_modifiers: status
All culture files (`culture-van-maanens-star.ron`, `culture-vael.ron`, `culture-osse.ron`) now populate `behavior_modifiers` with 11-12 clauses across all seven hint categories (`work_pace`, `physical_manner`, `social_signal`, `task_completion`, `environmental_scan`, `offduty_posture`, `authority_response`). The decomposed behavior system (#633/#634) shipped in Sprint 26. New culture files must populate this field. *(Updated Sprint 26 #634)*
---
## Scale Readiness Audit
### Passes at 300 systems
| Structure | Ready | Notes |
|-----------|-------|-------|
| `content/campaigns/main/systems/` | Yes | One directory per system. No monolithic files. |
| `content/global/factions/` | Yes | One file per faction — will grow to ~20-50 factions across 300 systems |
| `content/global/knowledge/` | Mostly | Knowledge catalog is organized by category, not by system. Flat list works to ~500 facts. |
| `content/global/culture-{name}.ron` | Yes | One file per culture (expected ~10-20 cultures total). |
| `templates/*.yaml` | Yes | Role slot definitions are reusable across systems of the same type. |
| `modules/tier1/` | Yes | Flat directory. Drama modules are self-contained. |
### Needs attention at scale
| Structure | Issue | Recommendation |
|-----------|-------|----------------|
| `content/global/knowledge/investigation.yaml` | **Deleted** — was detective-system-only. Other knowledge files need review for detective/smuggler references. | Audit surviving knowledge files post-#657. |
| `environmental/*.yaml` | Has v0.1 `dual_lens` (smuggler/detective) properties in the terminal/bar/corridors files. These are dead properties once archtypes are removed. | Flag to client team — strip `dual_lens` field from environmental schema for v0.2. |
| `templates/` v01_assignments | Fields reference deleted named NPCs. Not validated but stale. | Remove `v01_assignments` and `reference_links` from templates when generating v0.2+ content. |
| `triangles/` members | Reference deleted named NPCs (e.g., `npc:voss`, `npc:kael-davan`). These are unresolvable after NPC deletion. | These triangles are v0.1 examples. Either delete or annotate as templates for generated equivalents. |