Standardized YAML frontmatter on all 40 docs/design/ files with title, description, type, status, ticket, decision_refs, and author fields. Covers specs, wireframes, voice cards, spatial layouts, and system designs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
258 lines
12 KiB
Markdown
258 lines
12 KiB
Markdown
---
|
|
title: "Character Definition Schema"
|
|
description: "Canonical schema for playable character definitions covering identity, knowledge, relationships, and presentation"
|
|
type: design
|
|
status: draft
|
|
ticket: "#179"
|
|
decision_refs: [D-005, D-016, D-027, D-028, D-032, D-034, D-035, D-041, D-065]
|
|
author: ""
|
|
created: 2026-02-19
|
|
updated: 2026-02-19
|
|
---
|
|
|
|
# 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
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```yaml
|
|
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.
|
|
|
|
```yaml
|
|
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.*
|