[Foundry] Map structured stat blocks (sidebar_fields, #130) into npc_to_actor #148

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

Motivation/Context

#130 ("[Table Tools] One-click 'Flesh out' NPC backstory and stat block in the wiki") stores generated stat blocks as both markdown in body and structured sidebar_fields rows ({label, value, visibility}), explicitly "semi-machine-readable (eases a future Foundry push)" per its own Decisions section — it names this Foundry pillar (#9/#10, v4.1.0) and the FoundryVTT live-push investigation (2026-07-15) as the consumers. Until this mapping exists, an NPC's "stats" are unmappable free prose from a Foundry adapter's point of view, which undercuts the headline live-push ask ("push stats", not just a name and a description). This issue is the direct extension of #9's npc_to_actor that makes the sidebar_fields rows actually land on pf2e actor fields.

Approach

Extend the pf2e npc_to_actor() adapter (#9) to consume LoreEntry.sidebar_fields rows in addition to title/body/gm_notes:

  • Best-effort translation of {label, value} rows to pf2e actor system fields (level, HP, AC, saves, ability scores, etc.) where the label recognizably maps to a known pf2e field.
  • Anything unmapped (label doesn't match a known field, or the row's value doesn't parse cleanly) falls through into the actor's biography/notes rather than being dropped — matching #24's "unmappable → notes" pattern already used for the generic adapter.
  • Visibility must be respected: rows with visibility: gm or player_private must never be written into system.details.publicNotes or any player-visible actor field — they go into GM-only fields (system.details.privateNotes or equivalent) only. Public rows may populate public-facing fields.
  • Because #130's rows are LLM-shaped {label, value} pairs guided by free-text game_system rather than a schema-validated pf2e representation, this mapping is inherently best-effort. Note explicitly (in code comments and this issue) that the separate game-aware-systems investigation (structured per-system stat schemas replacing free-form game_system, referenced in #130's "Related/future" section) is what would eventually make this mapping reliable instead of best-effort. The two efforts should be sequenced deliberately: this issue ships the best-effort mapping now so live push (Phase 2.5) isn't blocked on game-aware systems landing first; if/when game-aware systems lands, this mapping should be revisited to target the real schema instead of guessing from free-form labels.

Dependencies

  • Extends #9 (v4.1.0 NPC push / npc_to_actor) — this issue has no standalone value without #9's base actor-creation path.
  • Hard-depends on #130 (accepted into v3.7.0) having actually shipped sidebar_fields stat rows — there is nothing to map until then.
  • Should be sequenced ahead of, or in tandem with, the game-aware-systems investigation being read together per the live-push report — do not block this issue on that investigation landing.
  • Feeds #146 (foundry_links) as the "what gets synced" logic behind that table's create-vs-update lookups, and is a hard dependency for the live-push slice in v4.4.0 ("Send to live scene", "Push update").

Out of scope

  • Any non-pf2e system mapping (stays in the generic adapter, #10, which already degrades to biography-only).
  • Redesigning sidebar_fields itself or #130's generation prompts.
  • Schema-valid stat generation — that's the game-aware-systems investigation's job, noted above as a future upgrade path, not built here.
  • Token/scene placement (later live-push issues).

Acceptance criteria

  • npc_to_actor() reads sidebar_fields and maps recognized pf2e-relevant rows onto actor system fields.
  • Unmapped rows land in actor biography/notes rather than being silently dropped.
  • GM-only and player-private sidebar_fields rows never appear in player-visible actor fields.
  • Behavior is verified against a real pf2e actor in the validated Foundry test instance (per #143's connectivity validation).
  • Code/issue comments record the intended handoff to the game-aware-systems investigation for a future, schema-valid version of this mapping.
## Motivation/Context #130 ("[Table Tools] One-click 'Flesh out' NPC backstory and stat block in the wiki") stores generated stat blocks as **both** markdown in `body` and structured `sidebar_fields` rows (`{label, value, visibility}`), explicitly "semi-machine-readable (eases a future Foundry push)" per its own Decisions section — it names this Foundry pillar (#9/#10, v4.1.0) and the FoundryVTT live-push investigation (2026-07-15) as the consumers. Until this mapping exists, an NPC's "stats" are unmappable free prose from a Foundry adapter's point of view, which undercuts the headline live-push ask ("push *stats*", not just a name and a description). This issue is the direct extension of #9's `npc_to_actor` that makes the `sidebar_fields` rows actually land on pf2e actor fields. ## Approach Extend the pf2e `npc_to_actor()` adapter (#9) to consume `LoreEntry.sidebar_fields` rows in addition to `title`/`body`/`gm_notes`: - Best-effort translation of `{label, value}` rows to pf2e actor system fields (level, HP, AC, saves, ability scores, etc.) where the label recognizably maps to a known pf2e field. - Anything unmapped (label doesn't match a known field, or the row's value doesn't parse cleanly) falls through into the actor's biography/notes rather than being dropped — matching #24's "unmappable → notes" pattern already used for the `generic` adapter. - **Visibility must be respected**: rows with `visibility: gm` or `player_private` must never be written into `system.details.publicNotes` or any player-visible actor field — they go into GM-only fields (`system.details.privateNotes` or equivalent) only. Public rows may populate public-facing fields. - Because #130's rows are LLM-shaped `{label, value}` pairs guided by free-text `game_system` rather than a schema-validated pf2e representation, this mapping is inherently best-effort. Note explicitly (in code comments and this issue) that the separate **game-aware-systems investigation** (structured per-system stat schemas replacing free-form `game_system`, referenced in #130's "Related/future" section) is what would eventually make this mapping reliable instead of best-effort. **The two efforts should be sequenced deliberately**: this issue ships the best-effort mapping now so live push (Phase 2.5) isn't blocked on game-aware systems landing first; if/when game-aware systems lands, this mapping should be revisited to target the real schema instead of guessing from free-form labels. ## Dependencies - Extends #9 (v4.1.0 NPC push / `npc_to_actor`) — this issue has no standalone value without #9's base actor-creation path. - Hard-depends on #130 (accepted into v3.7.0) having actually shipped `sidebar_fields` stat rows — there is nothing to map until then. - Should be sequenced ahead of, or in tandem with, the game-aware-systems investigation being read together per the live-push report — do not block this issue on that investigation landing. - Feeds #146 (`foundry_links`) as the "what gets synced" logic behind that table's create-vs-update lookups, and is a hard dependency for the live-push slice in v4.4.0 ("Send to live scene", "Push update"). ## Out of scope - Any non-pf2e system mapping (stays in the `generic` adapter, #10, which already degrades to biography-only). - Redesigning `sidebar_fields` itself or #130's generation prompts. - Schema-valid stat generation — that's the game-aware-systems investigation's job, noted above as a future upgrade path, not built here. - Token/scene placement (later live-push issues). ## Acceptance criteria - `npc_to_actor()` reads `sidebar_fields` and maps recognized pf2e-relevant rows onto actor system fields. - Unmapped rows land in actor biography/notes rather than being silently dropped. - GM-only and player-private `sidebar_fields` rows never appear in player-visible actor fields. - Behavior is verified against a real pf2e actor in the validated Foundry test instance (per #143's connectivity validation). - Code/issue comments record the intended handoff to the game-aware-systems investigation for a future, schema-valid version of this mapping.
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#148
No description provided.