Files
settled-reach/docs/design/character-definition-schema.md
T
jpmschweitzerandClaude Sonnet 4.6 6b1c5e4d29 docs(copy): Sprint 12 Wave 1 — Paula's ten design documents
Character schema and builds:
- #179: Character definition schema (6-section formal spec)
- #180: Smuggler character build (full schema instantiation)
- #181: Detective character build (full schema instantiation)
- #182: Divergent starting knowledge (master comparison table)
- #183: Divergent relationships (NPC web per character)

Institutional design:
- #322: Detective chain of command (Veth, Pres, Tsev backstory)

NPC pattern documents:
- #332: Contradiction arc — reusable FRIEND pattern (5 phases, checklist)
- #329: Mirror moment design — 10 paired dual-lens observations

Experience design:
- #259: First 5 minutes (narrative texture additions to Gestalt's systems doc)
- #307: Flat NPC trait pass (Pael, Ren, Tev — traits, routines, dual-lens)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 16:18:23 +01:00

12 KiB

Character Definition Schema

Ticket: #179 | Priority: Critical | Sprint: 12 Status: v0.1 Draft Blocks: #180 (Smuggler character build), #181 (Detective character build) Decisions referenced: D-005 (single character, asymmetric information), D-016 (internal monologue), D-027 (vertical slice), D-028 (dialogue layers), D-032 (separate monologue pools), D-034 (THE FRIEND), D-035 (tag taxonomy), D-041 (knowledge graph), D-065 (smuggler inventory)


1. Purpose

This document defines the canonical schema for a playable character in v0.1. A playable character is not just a perspective — it is a complete starting state that determines what the player sees, who they know, what they understand, and what they can do. Every field in this schema has downstream content implications.

Two characters share the same world. Two different schemas produce two different games.


2. Schema Overview

A playable character definition has six top-level sections:

Section Purpose
identity Who this character is in the world
starting_knowledge What the character knows at session start (KG seed)
starting_relationships Pre-existing relationships and their initial state
access_permissions Which dialogue tiers are available at session start
skills Capability flags affecting gameplay options
presentation Voice, monologue register, and diegetic evidence display

3. Identity

identity:
  canonical_id: "pc:{slug}"        # e.g., "pc:smuggler", "pc:detective"
  display_name: "{Name}"           # Player-visible name (stub until #180/#181)
  archetype: "{archetype}"         # "smuggler" | "detective"
  occupation: "{occupation}"       # Diegetic job title
  posting_duration: "{duration}"   # How long they've been in Sova Transit District
  faction: "{faction}"             # Institutional affiliation if any
  lattice_tier: "{tier}"           # "civilian" | "professional" | "investigative"
  description: >
    1-2 paragraph description of who this character is in the world, from
    a fictional universe perspective — not mechanical. Establishes emotional
    baseline, social position, and what they stand to lose.

Field notes:

  • archetype is used internally by the engine for monologue pool selection (D-032 hard partition). It is NOT exposed in the UI. Character feels like a person, not a game mechanic.
  • lattice_tier determines which perception overlays are available (D-017). Civilian: no enhanced perception. Professional: diagnostic tools, analytical overlays. Investigative: full analytical suite.
  • posting_duration affects which starting knowledge entries are plausible. A character who arrived 3 days ago cannot know the bar regulars by name.

4. Starting Knowledge

The starting knowledge section defines the Knowledge Graph seed (D-041) — the fact-set the character enters the session with. Facts not listed here are genuinely unknown at session start.

starting_knowledge:
  confidence_floor: "{tier}"   # Minimum confidence level; see D-041
  known_facts:
    - key: "{fact.key}"        # Namespaced fact key (e.g., "contraband.ring_exists")
      confidence: "{tier}"     # KnowsOf | KnowsDetails | KnowsEverything
      source: "{source}"       # "direct" | "secondhand" | "institutional" | "rumor"
      notes: >
        Optional. Authoring note on how the character holds this knowledge.
  unknown_facts:
    - key: "{fact.key}"
      notes: >
        Why this gap exists — what would they need to do to discover it?

Fact key namespaces:

Namespace Covers
contraband.* Ring existence, cargo types, supply chain, operational methods
location.* Specific places, access routes, surveillance gaps
investigation.* Manifest discrepancies, evidence, case file data
relationship.* Who knows whom, trust levels, ring membership
world.* Station geography, shift schedules, institutional structures
person.* Specific facts about named individuals

Critical rule: The unknown_facts section is as important as known_facts. It defines what the character CANNOT react to at session start and bounds what monologue triggers are legal.


5. Starting Relationships

Pre-existing relationships that determine initial RelationshipState (D-075) and AccessTier for every named NPC in the district. NPCs not listed here start at Unknown / public access.

starting_relationships:
  - target: "npc:{canonical_id}"
    relationship_state: "{state}"     # Unknown | Known | Friendly | PersonOfInterest | Hostile
    access_tier: ["{tiers}"]          # public | peer | insider | authority | hostile
    trust_level: "{level}"            # uncertain | reliable | trusted | hostile
    relationship_type: "{type}"       # colleague | friend | superior | contact | adversary
    known_attributes:
      name: "{name}"                  # Whether the character knows the NPC's name
      role: "{role}"                  # What role the character assigns to this NPC
      faction: "{faction}"            # Whether the character knows the NPC's affiliation
      notes: >
        Short description of the nature of this relationship and how it was established.

Relationship state → access tier mapping (default):

RelationshipState Default Access Tier Override possible?
Unknown public Yes (authority overrides via badge/credentials)
Known public, peer Yes
Friendly peer, insider No insider without explicit history
PersonOfInterest authority (detective) Yes
Hostile hostile No

Character-specific overrides: The smuggler has insider access to ring-member NPCs from session start (shared criminal history). The detective has authority access to institutional NPCs from session start (institutional credentials). These overrides are specified per-relationship, not as a global archetype flag (D-075).


6. Access Permissions

Global access tier capabilities at session start — what the character can unlock through gameplay versus what is structurally inaccessible.

access_permissions:
  can_unlock:
    - tier: "{tier}"
      condition: "{condition}"     # When this tier becomes accessible
      max_npcs: "{n | unlimited}"  # How many NPCs can reach this tier
  structurally_locked:
    - tier: "{tier}"
      reason: >
        Why this tier is never accessible to this character across the
        entire v0.1 vertical slice.

v0.1 constraints:

  • Smuggler can unlock: public (all), peer (Known→Friendly), insider (ring-member NPCs from start; others locked). Cannot unlock: authority (no institutional credentials).
  • Detective can unlock: public (all), authority (any Unknown/Known NPC via credentials), peer (Friendly NPCs only — currently Sera at session start). Cannot unlock: insider (ring dialogue never becomes available, even with investigation progress — the ring locks tighter, not looser, when the detective gets close).

This asymmetry is structural, not a content choice. It defines the two-keyhole architecture (D-027).


7. Skills

Capability flags that affect which game verbs are available and how gameplay systems respond.

skills:
  lattice_tier: "{tier}"           # Copied from identity; determines perception modes (D-017)
  movement_default: "{stance}"     # Default stance from D-053 MovementProfile
  inventory_slots: {n}             # Physical inventory capacity (D-065)
  evidence_display: "{format}"     # "case_file" | "personal_notebook" (D-065)
  capability_flags:
    - "{flag}"                     # e.g., "manifest_access", "authority_credentials", "ring_routes"
  starting_items:
    - item_id: "{id}"
      description: "{description}"
      leverage_type: "{type}"      # "proof" | "access" | "leverage"
      notes: >
        What this item proves, enables, or demonstrates.

Capability flags vocabulary:

Flag Effect
manifest_access Can request freight manifests from institutional NPCs
authority_credentials Badge/identification; unlocks authority tier with Unknown/Known NPCs
ring_routes Knows smuggling corridors and timing windows
ring_membership Treated as insider by ring-member NPCs from session start
analytical_lattice Pattern recognition overlay; flags behavioral anomalies at Careful stance
cargo_handling_cert Can interact with freight systems without triggering security flags

8. Presentation

How this character's internal voice, diegetic evidence display, and monologue pool are configured.

presentation:
  monologue_pool: "{archetype}"       # Hard partition per D-032 ("smuggler" | "detective")
  evidence_display: "{format}"        # Inherited from skills; documented here for content authors
  voice_register:
    sentence_length: "{pattern}"      # "fragments" | "complete" | "mixed"
    vocabulary: "{style}"             # "concrete/sensory" | "institutional/analytical"
    emotional_mode: "{mode}"          # "feeling-first" | "analysis-first"
    relationship_mode: "{mode}"       # "first-name/relational" | "surname-first/categorical"
  emotional_baseline:
    state: "{state}"                  # One-word summary of starting emotional state
    description: >
      3-5 sentences on the character's psychological starting position. This
      is the foundation that monologue lines build from. Lines that contradict
      this baseline are wrong.
  opening_monologue:
    lines:
      - "{line}"                      # 3-5 authored lines; see D-039 wow moment #1
    emotional_payload: >
      What the player should feel in the first 60 seconds.

Voice register is non-negotiable. The smuggler thinks in fragments. The detective thinks in complete sentences. The moment an author writes a complete-sentence analysis for the smuggler or a terse fragment for the detective, they've broken the dual-lens contract. The voice register fields in this schema exist so downstream authors never have to re-read the authoring guide — the character build IS the authoring guide.


9. Schema Validation Rules

Before finalizing a character build, validate against these rules:

Rule Check
Knowledge symmetry For every known_fact about an NPC, that NPC file must have a corresponding known_attributes entry in the character's relationship
Access tier consistency No insider access without ring_membership or equivalent history
Monologue pool All authored monologue lines tagged with this character's archetype (hard partition)
Unknown facts are real Every fact in unknown_facts must NOT appear in any authored monologue line at session start
Opening monologue Opening lines must NOT reference facts the character doesn't yet know
Inventory items All starting items must have corresponding world entities in content files
Emotional baseline Opening monologue lines must match the character's emotional_baseline.state

10. Cross-Reference: Downstream Documents

Document How This Schema Feeds It
character-build-smuggler.md (#180) Full instantiation of this schema for the smuggler
character-build-detective.md (#181) Full instantiation of this schema for the detective
divergent-starting-knowledge.md (#182) Comparison table derived from both builds' starting_knowledge sections
divergent-relationships.md (#183) Comparison table derived from both builds' starting_relationships sections
npcs/pc-smuggler.yaml NPC mode representation when detective is the active player
npcs/pc-detective.yaml NPC mode representation when smuggler is the active player
Content packs (#190, #191, #192) Access tier decisions in this schema determine which content each character sees
Opening hooks (#299, #300) Opening monologue section provides the first lines

Ticket #179 — Character definition schema. v0.1 scope. Blocks #180, #181.