← QuestforgeCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Questforge
Snapshot Sep 30, 2026 · 23:13 UTC · version 1.3.1
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "questforge-visuals",
"description": "Use native image generation as a Questforge table aid for scenes, objects, maps, inventory, merchants, outfits, symbols, recaps, persistent local galleries, interactive 360 POV viewers, and optional scene ambience with visual continuity.",
"included_files": [],
"skill_md_contents": "---\nname: questforge-visuals\ndescription: Use native image generation as a Questforge table aid for scenes, objects, maps, inventory, merchants, outfits, symbols, recaps, persistent local galleries, interactive 360 POV viewers, and optional scene ambience with visual continuity.\n---\n\n# Questforge Visuals\n\nUse this skill when a visual would clarify the shared imagination, preserve an\nimportant object or location, help spatial decisions, or make inventory/trade\neasier to understand.\n\nIf local file or browser access is unavailable, show generated static images in the conversation and skip local galleries and 360 viewers. Never block the next playable turn on an unsupported visual surface.\n\n## Format Choice\n\nBefore generating, plan the visual beat:\n\n```powershell\npython ../../scripts/visual_planner.py --beat \"<resolved player-facing beat>\"\n```\n\nUse the returned `format`, `kind`, `continuity_requirements`, and `next_steps`.\nIf `should_generate` is false, answer in chat and skip image generation.\nIf `should_generate` is true, satisfy the continuity requirements before\nrequesting native image generation.\n\nA saved prompt is preparation, not a completed visual. Count a beat as generated only after an image asset exists, is registered, and is shown once in chat for static formats or linked through its viewer for `pov-360`.\n\nThe planner chooses among:\n\n- `single_scene`: one location, one moment, one main action.\n- `comic-page`: two or more places, times, or actions in one response.\n- `map`: spatial decisions, routes, exits, fog of war, or tactical planning.\n- `inventory`: current gear, loot, money, burden, or carried clues.\n- `merchant`: buy/sell comparison boards.\n- `reference_plate`: recurring character, object, outfit, creature, or place.\n- `pov-360`: first-person spatial immersion.\n\nUse `../../scripts/comic_panels.py classify --summary \"<beat>\"` when unsure. If\nthe beat contains \"después\", \"luego\", \"mientras\", \"antes de\", \"vuelve\",\n\"camino a\", \"paga y desayuna\", \"entra y sale\", or several locations, do not\nrequest a single naturalistic scene unless the user explicitly asks for it.\n\n## Cadence\n\nFor image-rich play, generate a visual for important turns where the fiction\nchanges: decision consequences, dialogue turns with new posture or leverage,\nreveals, movement, danger, spell effects, item discoveries, maps, and scene\ntransitions. Skip images for brief rules questions, quick clarifications, purely\nmechanical back-and-forth, or beats already covered by a recent useful image.\n\nAt the start of a new or continued session, the first player-facing scene should have a visual by default. After setup, file loading, or recap is complete, actually generate and register a fresh establishing image for the current scene or explicitly point to a still-current generated gallery image. Do not treat `prompt-saved` as completion and do not defer the opening visual merely because the scene is urgent. Do not let the first actionable scene be text-only unless the user asks for speed, the turn is only out-of-character setup, no in-fiction scene has started yet, or native image generation is unavailable.\n\nDo not set a hard image cap by default. If the user enjoys a visual-first game,\nkeep generating scene frames as the fiction advances. Static generated images\nshould appear once in the Codex conversation so mobile users can see them, and\nthey should also be registered in the local gallery for desktop history and\nreview. Do not paste duplicate thumbnails or extra file links for the same\nstatic image. Use fewer images only when the user asks for speed, is asking\nrules questions, or is clearly trying to move quickly.\n\nIf native image generation is unavailable, say so only once when it first matters, log `visual_unavailable`, and continue play. Do not repeatedly save prompts, rebuild empty galleries, or imply that an image exists. When generation is available, invoke it; generating a prompt without invoking the tool is not a latency optimization.\n\nBefore returning any turn that selected a visual, check the corresponding visual-index status. `prompt-saved` requires one of two explicit outcomes in that same reply: generate/register/show the asset, or report the unavailable surface once, set the row to `unavailable`, and record `visual_unavailable`. Silent pending prompts are not allowed.\n\nDefault visual style should be immersive fantasy realism: grounded materials,\nclear staging, dramatic but plausible light, and no unwanted film grain. Use a\ndifferent style only when the campaign has already established one or the user\nasks for it.\n\n## Local Gallery\n\nUse one stable local gallery per campaign as the desktop visual board and\nhistory. After each saved and registered native image, refresh it:\n\n```powershell\npython ../../scripts/visual_gallery.py --campaign-root <campaign-root> --title \"<campaign title>\"\n```\n\nThe script writes `<campaign-root>/images/visual-gallery.html`, prints a `file:///` URL ending in `#latest`, and renders a chronological scroll log: older images at the top, newer images lower down, with every image in a stable same-size frame and one compact line such as `#35 · scene · Nela explica su olvido`. Panorama/360 entries are embedded as interactive viewer iframes in the gallery, not static images. If a panorama-like asset has no viewer yet, the gallery creates a default local viewer under `images/viewers/`.\n\nAfter the first registered visual in each local play session, proactively return the stable `gallery_url` once as a compact Markdown link such as `[Open the live Questforge visual table](<file:///.../visual-gallery.html#latest>)`. Do not wait for the player to ask for a gallery or viewer. The link is opt-in: do not navigate the player's browser automatically unless the player asks to open or keep it beside the story. When left on `#latest`, the gallery refreshes itself and follows later static images and 360 viewers, so do not repeat the link after every beat.\nWhen the page is on `#latest`, it follows the latest image while visible. If\nthe player jumps to `#visual-<n>`, it stops following so historical review is\nstable.\nIf the current Browser surface refuses `file:///` navigation by policy, return\nthe link and continue; do not spend play time on browser workarounds.\n\nFor `pov-360` assets, create the panorama viewer first under\n`<campaign-root>/images/viewers/`, then refresh the gallery. Matching 360\nviewers are linked from the selected gallery item. Older entries that were\nsaved as `location` still link when their label or asset name clearly contains\n`360`, `panorama`, or `panoramico`; the gallery also links existing matching\nviewer filenames such as `<asset-stem>-360.html`. Use `--viewer-root` for\nlegacy viewer folders outside the campaign.\n\n## Chat Image Surface\n\nFor every useful static generated image (`scene`, `location`, `character`,\n`creature`, `item`, `spell`, `map`, `inventory`, `merchant`, `outfit`,\n`symbol`, `recap`, and `comic-page`), show the selected image once in the\nconversation after it has been saved or copied into `images/assets/`. Use\nstandard Markdown with an absolute filesystem path:\n\n```markdown\n\n```\n\nKeep the nearby text short: narrate the scene normally, then show the image, or show the image after the consequence paragraph. Do not also return a separate `Image` button, prompt link, or raw local file path for that same static image unless the user asks for debugging details. The one stable live visual-table link offered after the first registered visual of the session is the deliberate exception. Continue to refresh the local gallery in the background for history and desktop play.\n\nFor `pov-360`, return the local viewer link and optionally open it with\n`@Browser`; do not treat the raw panorama as the main chat image unless the\nuser explicitly asks for a flat preview.\n\n## Pre-Session Prep\n\nFor important scenes, prepare visuals before live play. Use this for recurring\ncharacters, NPCs, enemies, maps, locations, persistent items, rewards, symbols,\noutfits, and likely action beats.\n\nComplete a campaign-specific copy of the neutral prep spec from the accepted conception and current visual ledger. Never run the bundled empty structure unchanged or infer its subjects from a documentation example. Then create reference prompts:\n\n```powershell\npython ../../scripts/visual_prep.py --campaign-root <campaign-root> --spec ../../templates/visual-prep-spec.json\n```\n\nThen generate native images from the saved prompts, register selected PNGs, and\nmark accepted references as `canon`. Use session `0` for pre-session reference\nassets. See `../../docs/visual-prep-workflow.md`.\n\n## Live Reuse\n\nBefore generating a scene with recurring visual elements, list usable canon\nanchors:\n\n```powershell\npython ../../scripts/campaign_memory.py list-visual-assets --campaign-root <campaign-root> --status canon --format markdown\n```\n\nCreate live scene-frame prompts from the relevant anchors instead of rewriting\ncontinuity by hand:\n\n```powershell\npython ../../scripts/visual_reuse.py --campaign-root <campaign-root> --session <n> --scene <n> --label \"<scene label>\" --action \"<player-facing action>\" --roll \"<actual roll or check>\" --outcome \"<resolved table outcome>\" --anchor-label \"<canon label>\" --require-asset\n```\n\nUse repeated `--anchor-label` values for multiple anchors. If a reviewed image\nis useful but not canonical, use `--anchor-status variant` intentionally and\nstate why in the prompt or session log. When a visual follows a roll, include\nthe actual roll and outcome so the image prompt cannot contradict the table.\n\nAlso check `images/visual-ledger.md` and preserve active visible states such as\nbandaged hands, disguises, carried objects, object scale, faction marks, and\nstable room layouts. Do not regress a visible state unless the fiction changes\nit.\n\nFor visual-first play, every generated prompt must either use `visual_reuse.py`\nwith relevant anchors or explicitly include the active visual ledger and explain\nwhy no existing canon anchor applies.\n\n## POV 360\n\nWhen the player asks to look around or inspect a scene from the character's point of view, when the character enters an important location, or when spatial immersion would help, request a native equirectangular 360 panorama. Generate, register, and build its viewer in the same turn instead of waiting for a second request. The viewer uses drag-to-look controls, inertial movement, smooth zoom, keyboard controls, and an initially muted audio toggle when ambience is available.\n\n```powershell\npython ../../scripts/panorama_viewer.py --image <generated-360.png> --output <campaign-root>/images/viewers/<label>-360.html --title \"<scene title>\" --narration \"<short in-scene narration>\" --initial-zoom-level 14\n```\n\nAlways return the `viewer_url` as a compact Markdown link. Do not automatically navigate the in-app browser; clicking the link is the player's opt-in action. If the player explicitly asks to open the viewer, use `@Browser` when available. The viewer is standalone and does not require a local server. Use narration text from the current scene instead of technical labels or file paths.\n\nFor a scene that benefits from sustained ambience, select one licensed or user-provided loop before creating the viewer. Do not ask the player whether a soundtrack exists or whether it should be attached. Prefer a campaign-local approved library at `<campaign-root>/audio/library.json`; if it does not exist, use the bundled starter pack at `../../assets/audio/library.json`. Select by the scene's concrete tags and intensity:\n\n```powershell\npython ../../scripts/audio_library.py select --library <campaign-root>/audio/library.json --tag archive --tag mystery --intensity 2 --format args\n```\n\nFallback example:\n\n```powershell\npython ../../scripts/audio_library.py select --library ../../assets/audio/library.json --tag dungeon --tag exploration --intensity 3 --format args\n```\n\nAppend the returned arguments to the panorama viewer command:\n\n```powershell\npython ../../scripts/panorama_viewer.py --image <generated-360.png> --output <campaign-root>/images/viewers/<label>-360.html --title \"<scene title>\" --narration \"<short in-scene narration>\" --initial-zoom-level 14 --audio <loop.mp3> --audio-title \"<track title>\" --audio-volume 0.24\n```\n\nChoose audio when ambience helps: tavern, wilderness, dungeon, ritual, chase, combat, dream, travel, aftermath, or another sustained location or pressure beat with a strong library match. Prefer campaign-specific loops when present, otherwise use the bundled starter pack. If no approved track matches well, create the viewer without audio and continue without interrupting play. The viewer embeds the selected loop and exposes a small speaker toggle. Do not start music for a new player by default. If the player enabled audio in a prior viewer, the next viewer should remember that preference and resume when the browser allows playback.\n\n## Visual Kinds\n\nUse these kinds with `save-visual-prompt`:\n\n- `scene`\n- `location`\n- `character`\n- `creature`\n- `item`\n- `spell`\n- `map`\n- `inventory`\n- `merchant`\n- `outfit`\n- `symbol`\n- `recap`\n- `pov-360`\n- `comic-page`\n\nBuild prompts from `../../templates/scene-image-prompt.md` and guidance in\n`../../docs/visual-playbook.md`. For `comic-page`, use\n`../../templates/comic-page-prompt.md`.\n\n## Persistence\n\nBefore requesting native image generation, save the prompt:\n\n```powershell\npython ../../scripts/campaign_memory.py save-visual-prompt --campaign-root <campaign-root> --session <n> --scene <n> --kind <kind> --label \"<label>\" --prompt \"<prompt>\"\n```\n\nThen request native Codex/ChatGPT image generation if available. Do not call\nimage API scripts or use `OPENAI_API_KEY` unless the user explicitly asks to use\nthe API.\n\nAfter generation, copy the selected image into `images/assets/` and register it:\n\n```powershell\npython ../../scripts/campaign_memory.py register-visual-asset --campaign-root <campaign-root> --asset-path images/assets/<asset-name>.png --kind <kind> --label \"<label>\" --session <n> --scene <n>\n```\n\nRefresh the gallery after registration:\n\n```powershell\npython ../../scripts/visual_gallery.py --campaign-root <campaign-root>\n```\n\nIf native image generation saved the PNG outside the campaign workspace, let\nQuestforge copy it:\n\n```powershell\npython ../../scripts/campaign_memory.py register-visual-asset --campaign-root <campaign-root> --asset-source <generated-image.png> --asset-filename <asset-name>.png --kind <kind> --label \"<label>\" --session <n> --scene <n>\n```\n\nTo mark a reviewed reference as canonical:\n\n```powershell\npython ../../scripts/campaign_memory.py set-visual-status --campaign-root <campaign-root> --kind <kind> --label \"<label>\" --session <n> --scene <n> --status canon\n```\n\nPersist recurring details:\n\n- characters, outfits, locations, symbols in `visual-bible.md`;\n- item, map, merchant, inventory, and recap prompts in `images/visual-index.md`;\n- object or clue references in `campaign-state.md` or character sheets.\n\nReview generated images before treating them as canon. Composite action scenes\ndrift most easily, so explicitly reuse prior anchors for characters, creatures,\nitems, maps, and locations, then compare the result with earlier assets.\nUse `visual_reuse.py` for those composite scenes when canon anchors already\nexist.\n\nValid statuses are `prompt-saved`, `asset-saved`, `canon`, `variant`,\n`rejected`, and `unavailable`. Use `unavailable` only when the current product\nsurface cannot invoke native image generation; it is not a substitute for a\nfailed or deferred generation attempt.\n\n## Fog Of War\n\nFor maps:\n\n- show only explored or known areas;\n- hide secret rooms, hidden doors, enemy counts, trap mechanisms, and unexplored\n paths;\n- use parchment shadow, mist, blank space, or unlabeled boundaries for unknown\n areas;\n- keep labels sparse and table-useful.\n\n## Copyright Boundary\n\nPrompt only for original fantasy imagery. Do not request official D&D style,\nofficial logos, named settings, named characters, commercial adventure maps, or\ncopied product art.\n\nUse only audio loops that the user owns, generated for the project, or whose\nlicense permits the intended local or redistributed use. Do not commit or\npackage music without clear license notes and required attribution.\nFor Suno-generated project audio, only package tracks generated while the\naccount has an active commercial-rights plan. Keep unreviewed candidates out of\nthe public audio library. See `../../docs/sound-atlas.md`.\n"
}SHA-256: fd0d4b475172769bb0eb4e0c519073bec6ab99abcb075935ac0cd1b0daabc21b