[Table Tools] One-click "Flesh out" NPC backstory and stat block in the wiki #130
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
A GM often creates a thin NPC lore entry (just a name, maybe a one-line note) and later wants it turned into a full character: a fleshed-out backstory plus a usable stat block. Today the only AI action on a wiki entry is "Rephrase with LLM", which rewrites existing prose without inventing new facts. There is no "expand this stub into a full NPC" action.
Goal: from an NPC or creature wiki article, generate (a) an expanded backstory and (b) a stat block — as two separate one-click actions that produce coherent results — presented as proposed drafts the GM reviews, edits, and approves. Never auto-written.
Decisions (locked by GM 2026-07-15)
npcandcreatureentry types.bodyand structuredsidebar_fields(infobox rows) — readable and semi-machine-readable (eases a future Foundry push).visibilitykey onsidebar_fields(public/gm/player_private); default all newly generated stat content to GM-only. Newly invented backstory content the GM hasn't vetted should likewise default to GM-only (or be clearly delineated). Confirm exact default granularity during implementation.Approach — new draft modes on the existing rail
Reuse the existing LLM-draft pipeline (generating→ready→failed lifecycle, old-vs-new review UI, inline edit, iterate-with-feedback, versioning, approval). Add two modes alongside
rephrase/merge:expand_backstoryandgenerate_statblock.Backend
rephrase_lore_entry_body(~line 717): an expand-backstory prompt and a stat-block prompt. The stat-block prompt consumes the entry's backstory + free-textgame_system+ any level/role signal and emits both a markdown block and a small set of structured{label, value, visibility}sidebar rows. Core viagenerate_structured_text(~line 1158; usejson_modefor the structured half) andget_llm_config(Bot Settings, not env).start_rephrase_draft/start_merge_draft(~lines 63/93) and matching branches inrun_lore_entry_draft_generationin reminder_tasks.py (~line 2079). Existing Celery draft task — no new task plumbing.LoreEntryDraftand the existing draft endpoints in campaigns.py (POST .../lore/{entry_id}/drafts~line 2212; review/iterate/approve ~2270-2389).LoreDraftCreate(~line 2148) gains amodediscriminator.body; write structured rows intosidebar_fieldswith GM-onlyvisibilityby default. Gate toentry_type in (npc, creature).Frontend
startLoreDraft. Review UI must make the per-row player-visibility toggle obvious (default off).Coherence requirement
Stats must reflect the backstory. Simplest guarantee: stat-block generation always consumes the current backstory as context, and the GM regenerates stats after editing the backstory. Consider a hint in the review UI when the backstory changed after the stat block was generated (stale-stats warning).
Related / future (out of scope here)
game_system) — a much larger effort under separate investigation. This issue stays system-agnostic (LLM free-form guided by thegame_systemhint). If game-aware work lands, the stat-block generator can target a real schema. Storing stats as structuredsidebar_fieldsis chosen partly to smooth that transition.Acceptance
LoreEntryVersion.bodyand structuredsidebar_fields.GM decisions captured and folded into the body:
npcandcreatureentries.body) and structuredsidebar_fields.sidebar_fields.visibilitymodel.Game-aware stat schemas and FoundryVTT live-push are being investigated separately as larger efforts; this issue stays system-agnostic and wiki-only.
statsstorage + validation service #139sidebar_fields, #130) intonpc_to_actor#148Done — merged in PR #197 (backend
c23fb42+ frontend). CI green.Shipped (all GM-locked decisions honored):
LoreEntryDraftgains explicitmode(rephrase|merge|expand_backstory|generate_statblock, default rephrase) +current_sidebar_fieldsstaging column; migratione8f9a0b1c2d3(round-trips).## Backstorysection) and Generate stat block (json_mode → markdown and structuredsidebar_fields; generated from the current backstory for coherence).visibility="gm"; the review UI surfaces a prominent per-row visibility toggle (Public / GM-only / Player-private) with a "hidden from players by default" note, persisted via PATCH before approve.sidebar_fields(never dropping existing) and snapshots aLoreEntryVersion; nothing lands without GM approval.Tests: backend 516 pass (+14
test_npc_fleshout.py, incl. the PATCH visibility-toggle); frontend 262 (+13).Acceptance criteria met: both actions produce review drafts; stats coherent with backstory; content append-only + GM-only by default with explicit opt-in; everything flows through edit/iterate/approve/discard with a version snapshot; stat block stored as both markdown (body) and structured
sidebar_fields; generation uses the Admin → Bot Settings LLM via the existing Celery draft task.Out of scope as noted: game-aware/validated stat schemas and FoundryVTT push remain under their separate tracks.
Closing.