Skip to content

Sub-location / scene tracking for indoor spaces #21

Description

@barrulus

Problem

The LLM has no concept of "inside this building" vs "outside". NPCs are placed by world coordinates and burg id, but a 50-soul village has dozens of buildings and the same coordinates cover all of them. When players step into a cottage to talk to one NPC, the proximity query still returns every NPC in the village, so the LLM ends up putting the village herder inside the cottage as well.

Symptom from session: player addresses Kael in his cottage, the LLM has the old herder physically present inside the cottage too because both NPCs are at `world_position = (10153000, -11619000)`.

Proposed solution

Add a per-player "current scene" concept:

  1. Schema: add `current_scene` (text or jsonb) to `campaign_players`. Stores a short descriptor like "inside Kael's cottage" or "in the village square".
  2. NPC location: extend `npcs` with an optional `scene_tag` (text). Auto-extracted NPCs introduced in a scene get tagged with that scene.
  3. Movement detection: when the action interceptor parses an `interact` or `move` action whose narration implies entering/leaving a building, update the player's `current_scene`.
  4. Context filtering: `buildActionContext` filters "NPCs at this location" to those whose `scene_tag` matches the player's `current_scene`. NPCs without a scene tag default to the outdoor village scene.
  5. DM response schema: add an optional `sceneTransition` field so the LLM can explicitly signal "player is now inside the cottage" — same pattern as `phaseTransition`.

Why this matters

Without this:

  • Players can't have private conversations
  • NPCs follow players into buildings invisibly
  • The narration can't accurately reflect spatial separation
  • Combat encounters in confined spaces include random villagers

Workaround in place (interim)

Until this lands, the system prompt has been strengthened with explicit "if the player entered a building, only NPCs already inside are present" rules. This is unreliable on smaller models but helps Claude.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions