[Foundry] "Send to live scene": place pushed NPC token into the active scene #152

Open
opened 2026-07-15 22:03:41 +00:00 by claude-bot · 0 comments
Contributor

Motivation/Context

This is the headline feature requested by the original ask: "while actively playing, let the GM push stats/backstory/character tokens to Foundry in real time — e.g. spin up an NPC just generated in Quest Board directly into the live Foundry scene." Everything else in the Foundry pillar up to this point (#9, and its live-push extensions #146/#148/#150) gets an NPC into Foundry's actor directory; this issue is the entire delta that makes it "live" — placing a token for that actor onto the scene the GM currently has open, during play.

Approach

After the actor create/update path (#9 + #148's stat mapping + #150's token image) completes, place a TokenDocument for the resulting actor on the currently viewed/active scene using the REST module's active-scene query and token-creation APIs (validate exact API shape during #143's module testing pass). Default placement: scene center, hidden: true — the GM positions and reveals the token manually in Foundry rather than the push deciding placement/visibility for them.

API surface: POST /api/campaigns/{campaign_id}/lore/{entry_id}/foundry-push with {"target": "directory" | "active_scene"}, GM-authorized via require_gm. target=directory reuses #9's existing behavior unchanged; target=active_scene is new in this issue — create/update the actor exactly as #9 does, then additionally place the scene token.

Execution: run as a short Celery task, consistent with the existing "queue a task, POST out, fall through gracefully" pattern already used in app/tasks/reminder_tasks.py. The API returns immediately with a push-status the UI polls or receives via existing toast plumbing (UI itself is tracked separately). Feedback states: queued → pushed (actor name + scene) → failed, with the "no Foundry client connected" relay failure surfaced as an actionable, specific error message rather than a generic failure. All errors follow the repo-wide {"detail": "..."} shape.

Uses foundry_links (#146) to determine create-vs-update for the underlying actor, so repeated live pushes of the same NPC don't spawn duplicate actors — only the scene-token placement is genuinely new each time. Default to always creating a new token instance on the active scene per push, since GMs may want the same NPC on stage twice; refining this is left to the follow-on "Push update" work.

Dependencies

  • Hard dependency: #9 (v4.1.0, npc_to_actor + directory-level "Send to Foundry") — this issue is #9 plus scene placement, not a replacement for it.
  • Hard dependency: #146 (foundry_links) — needed for actor-level idempotency before adding a token on top.
  • Hard dependency: #148 (structured stat mapping) — without it, the pushed actor has no usable stats, which undercuts the point of pushing during play.
  • Depends on #143's connectivity/topology decision and validated module API for active-scene queries and token creation.
  • Should reuse #150's token image work if available, though not a strict blocker (falls back to default token art).

Out of scope

  • The GM-facing button/UI (tracked separately).
  • "Push update" semantics for re-pushing an already-placed NPC (tracked separately).
  • Any scene selection UI — v1 always targets whatever scene is currently active/viewed in Foundry, no scene picker.
  • Journal/backstory linking (Phase 3).

Acceptance criteria

  • POST .../lore/{entry_id}/foundry-push with target=active_scene creates/updates the actor (via #9 + #146's link table) and places a token for it on Foundry's currently active scene.
  • Placed tokens default to scene-center, hidden: true.
  • The push runs as a Celery task and the API surfaces queued/pushed/failed status.
  • "No Foundry client connected" (relay mode with no connected world) produces a specific, actionable error, not a generic failure.
  • Verified end-to-end against the real Foundry test instance: an NPC generated in Quest Board appears as a token on the GM's active scene after the push.
## Motivation/Context This is the headline feature requested by the original ask: "while actively playing, let the GM push stats/backstory/character tokens to Foundry in real time — e.g. spin up an NPC just generated in Quest Board directly into the live Foundry scene." Everything else in the Foundry pillar up to this point (#9, and its live-push extensions #146/#148/#150) gets an NPC into Foundry's actor directory; this issue is the entire delta that makes it "live" — placing a token for that actor onto the scene the GM currently has open, during play. ## Approach After the actor create/update path (#9 + #148's stat mapping + #150's token image) completes, place a `TokenDocument` for the resulting actor on the **currently viewed/active scene** using the REST module's active-scene query and token-creation APIs (validate exact API shape during #143's module testing pass). Default placement: scene center, `hidden: true` — the GM positions and reveals the token manually in Foundry rather than the push deciding placement/visibility for them. API surface: `POST /api/campaigns/{campaign_id}/lore/{entry_id}/foundry-push` with `{"target": "directory" | "active_scene"}`, GM-authorized via `require_gm`. `target=directory` reuses #9's existing behavior unchanged; `target=active_scene` is new in this issue — create/update the actor exactly as #9 does, then additionally place the scene token. Execution: run as a short Celery task, consistent with the existing "queue a task, POST out, fall through gracefully" pattern already used in `app/tasks/reminder_tasks.py`. The API returns immediately with a push-status the UI polls or receives via existing toast plumbing (UI itself is tracked separately). Feedback states: *queued → pushed (actor name + scene) → failed*, with the "no Foundry client connected" relay failure surfaced as an actionable, specific error message rather than a generic failure. All errors follow the repo-wide `{"detail": "..."}` shape. Uses `foundry_links` (#146) to determine create-vs-update for the underlying actor, so repeated live pushes of the same NPC don't spawn duplicate actors — only the scene-token placement is genuinely new each time. Default to always creating a new token instance on the active scene per push, since GMs may want the same NPC on stage twice; refining this is left to the follow-on "Push update" work. ## Dependencies - Hard dependency: #9 (v4.1.0, `npc_to_actor` + directory-level "Send to Foundry") — this issue is #9 plus scene placement, not a replacement for it. - Hard dependency: #146 (`foundry_links`) — needed for actor-level idempotency before adding a token on top. - Hard dependency: #148 (structured stat mapping) — without it, the pushed actor has no usable stats, which undercuts the point of pushing during play. - Depends on #143's connectivity/topology decision and validated module API for active-scene queries and token creation. - Should reuse #150's token image work if available, though not a strict blocker (falls back to default token art). ## Out of scope - The GM-facing button/UI (tracked separately). - "Push update" semantics for re-pushing an already-placed NPC (tracked separately). - Any scene selection UI — v1 always targets whatever scene is currently active/viewed in Foundry, no scene picker. - Journal/backstory linking (Phase 3). ## Acceptance criteria - `POST .../lore/{entry_id}/foundry-push` with `target=active_scene` creates/updates the actor (via #9 + #146's link table) and places a token for it on Foundry's currently active scene. - Placed tokens default to scene-center, `hidden: true`. - The push runs as a Celery task and the API surfaces queued/pushed/failed status. - "No Foundry client connected" (relay mode with no connected world) produces a specific, actionable error, not a generic failure. - Verified end-to-end against the real Foundry test instance: an NPC generated in Quest Board appears as a token on the GM's active scene after the push.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#152
No description provided.