# Sprint 18: Touch — Copy Tasks **Goal:** The player can examine entities and objects to generate character-filtered observations; NPCs detect and react when watched; social actions propagate through the relationship graph; minimap renders POIs on the client. **Branch:** `copy` **Agents:** Mellanie (author), Paula (narrative lead), Gestalt (systems) ## Carry-over from Sprint 17 None. Sprint 17 closed 19/19. ## New Tickets | # | Title | Blocked by | |---|-------|------------| | #544 | Design: collision-resistant line IDs for auto-generated NPCs | — | | #158 | Tier 1 drama module schema | — | Use `db/connectors/ticket show ` for full details. ## Key Decisions - `decisions/content.md` — D-023 (three-tier content model — Tier 1 is drama modules), D-024 (NPC generation — hundreds of auto-generated NPCs per D-029 population model), D-028 (dialogue line pool format), D-035 (line ID scheme — Amendment Sprint 15: NPC-scoped IDs; D-029 auto-generated NPCs need collision-resistant variant) - `decisions/scope.md` — D-027 (vertical slice scope — Tier 1 modules activate for the smuggler/detective scenario) ## Notes ### #544 — Design: collision-resistant line IDs for auto-generated NPCs **Context (Q-028):** The current line ID scheme (D-035 Amendment Sprint 15) uses `{npc-slug}_{d|m}_{###}` — e.g., `kael-davan_d_001`. For hand-authored NPCs with unique slugs this works. But D-029 specifies hundreds of procedurally generated NPCs (the 70% mundane majority), each with a generated slug like `dock-worker`. A district with 40 dock workers all using `dock-worker_d_001` produces immediate collision. **What this ticket must deliver:** - A design document (output to `docs/design/` or as a decision record) specifying the collision-resistant scheme for auto-generated NPC line IDs - Evaluation of at least three options: 1. **Short UUID suffix on NPC slug** — `dock-worker-a3f2_d_001`. Human-readable, unique per NPC, but IDs are not stable across seed changes 2. **StableId prefix** — `npc-00042_d_001`. Machine-readable, stable if `StableId` persists. Less author-friendly 3. **Role slug + instance counter** — `dock-worker-03_d_001`. Human-readable, author can write role-scoped lines used by all instances of that role. Requires a clear definition of "role" as the ID namespace 4. **Slug registry with collision resolution** — same slug gets `dock-worker`, `dock-worker-2`, etc. at generation time, recorded in content registry - The chosen scheme must satisfy: - Hand-authored NPCs (Kael, Sera, etc.) retain their current human-readable slugs — no migration - Auto-generated NPCs can be distinguished from one another in line IDs - The scheme is implementable in the content registry (`server/src/knowledge/registry.rs`) without breaking existing authored content - Authors can still write role-scoped lines that apply to all dock workers (shared content), distinct from instance-specific authored lines - **Gestalt owns this ticket** — it resolves Q-028. Output: a decision record (D-NNN) or documented convention added to `docs/design/`. Once the scheme is chosen, update `docs/design/interaction-verbs-v0.1.md` or the content authoring guide if needed. Timeline: resolve by end of week 1 so server/ci teams can implement the registry change in Sprint 18 or Sprint 19. ### #158 — Tier 1 drama module schema Tier 1 content (D-023) is authored drama modules drawn from a pool at game start. The smuggler/detective vertical slice (D-027) IS a Tier 1 module. This ticket defines the structure every Tier 1 module must follow so the storyteller can activate and manage them consistently. **What this ticket must deliver:** - A YAML schema definition file at `content/schemas/drama_module.schema.yaml` (or extend existing schema files in `content/schemas/`) - The schema must cover: - **Entry conditions**: what world-state must be true for this module to be activatable (NPC present, player relationship threshold, location accessible, etc.) - **NPC requirements**: which NPC slots the module requires (protagonist, antagonist, witness, etc.) and what axes they must satisfy (e.g., "protagonist must have Major secret") - **Event sequences**: ordered or unordered events the module can fire, with storyteller trigger conditions for each (proximity, tick threshold, player action) - **Outcomes**: resolution states the module can reach (exposed, escaped, ambiguous, abandoned) - **Pool format**: how multiple modules coexist in the pool — each module is a YAML file in `content/modules/tier1/` - A stub Tier 1 module file for the smuggling ring scenario at `content/modules/tier1/smuggling_ring_v0_1.yaml` — this is the vertical slice module - Coordinate with server team: the storyteller module stub (`server/src/storyteller/`) will eventually activate modules by reading this schema. Schema design choices constrain implementation — agree on the top-level structure with Tyre before finalizing **Paula owns the dramatic structure design** (entry conditions, event sequences, outcomes). **Gestalt owns the schema implementation** (YAML format, field names, validation rules). **Mellanie reviews** for authoring ergonomics — can a writer actually fill this template? Output: schema file + stub module file + brief authoring notes in `docs/design/tier1-module-authoring.md` explaining the fields to future writers. ## Dependency Chain ``` #544 (line ID design) → standalone — Gestalt starts week 1 → output unblocks server/ci registry implementation (Sprint 19) #158 (drama module schema) → standalone — Paula + Gestalt start week 1 → output unblocks storyteller activation (future sprint) ``` Both tickets are design-first — produce documents and schema files, not code. Both run in parallel from day 1. ## Open Questions to Resolve Early - **Q-028: collision-resistant line IDs** — #544 IS the resolution ticket. Gestalt must produce a concrete decision by end of week 1. The decision should be registered as D-NNN via the standard decision record format in `decisions/content.md`. ## PR Workflow When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see CLAUDE.md "Gitea access" section): ```bash tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(copy): description" --description "body" --base main --head copy ```