Skip to main content

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.py
  • server/app/routers/npc_relationships.py
  • server/app/lib/npcs.py
  • server/app/lib/rag/generation.py
  • server/app/lib/rag/recap_extraction.py
  • server/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.tsx
  • web/src/components/GenerateNpcModal.tsx
  • web/src/components/NpcChatCard.tsx
  • web/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:

  • NPC
  • MEMBER

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_npc and web/src/types.ts aligned.
  • Preserve generated-NPC behavior as draft-only until saved.
  • Update Codex views if NPC display fields change.