NPCs and Relationships
NPCs are living campaign state. They can be created manually, generated by the Sage, linked to sessions, given status, connected to party members or other NPCs, and shown in the Codex.
Backend
Primary files:
server/app/routers/npcs.pyserver/app/routers/npc_relationships.pyserver/app/lib/npcs.pyserver/app/lib/rag/generation.pyserver/app/lib/rag/recap_extraction.pyserver/app/models.py(NPC,NpcSession,NpcRelationship)
NPC routes are DM-only and AI generation additionally requires AI access. Relationship endpoints validate both endpoints against the campaign.
Frontend
Primary files:
web/src/screens/CampaignNpcs.tsxweb/src/components/GenerateNpcModal.tsxweb/src/components/NpcChatCard.tsxweb/src/components/RelationshipEditor.tsx
The NPC tab supports manual CRUD, generated NPC drafts, inline status editing, and relationship editing.
Relationships
Relationship endpoints are directed and free-text labeled. Endpoints can be:
NPCMEMBER
They are not modeled as strict foreign keys because party members and NPCs have different tables and lifecycle rules. Service-layer validation enforces scope.
Recap Integration
Recap extraction can propose NPC create/link/update operations and relationship create operations. Applying a changeset processes story entities first, then NPCs, then relationships so relationships can target NPCs created earlier in the same review.
Change Checklist
- Validate every endpoint against campaign scope.
- Clean up relationships when NPCs or party members are removed.
- Keep
serialize_npcandweb/src/types.tsaligned. - Preserve generated-NPC behavior as draft-only until saved.
- Update Codex views if NPC display fields change.