
whisk-image-generation
Generate D&D character images using Google Gemini or Whisk via manual browser automation (DevTools M
Image Generation Skill (Gemini & Whisk)
Use this skill to generate character art using Google's AI tools. This approach uses the unified image-gen MCP server or the agent's native devtools tools to drive the browser.
Prerequisites
- Chrome Browser: The script
scripts/workflows/gemini/core/image-gen-mcp.tsmanages the browser session (launchingchromewith a persistent profile).- Manual Login: Required on the first run. The script will pause and alert you if you are not logged in.
- Unified MCP Server:
- Server Name:
image-gen - Tools:
generate_image,download_image,verify_image_adherence
- Server Name:
Core Learnings & Obstacles
- Whisk vs. Gemini: Whisk (labs.google) is highly reactive and often ignores automated clicks. Gemini (gemini.google.com) is much more stable and is the default provider for the unified tool.
- Visual Verification: Use
verify_image_adherenceto check generated images against the "Full Body D&D Villager" guidelines. This tool re-uploads the image to Gemini and asks for a critique. - One-Turn Search & Generate: Gemini can handle "Search then Generate" in a single prompt. This is faster and more accurate than doing it in two steps.
Workflow
1. Launch & Connect
The script handles launching automatically.
- Run the server or script:
npx tsx scripts/workflows/gemini/core/image-gen-mcp.ts - If it's your first time, the window will open. Log in to Google.
- Once logged in, the script will be ready to accept tool calls.
2. Optimized Prompting (Two-Step Strategy)
To ensure accuracy and "mundane/slice-of-life" grounding, use a two-step approach.
Step 1: Research & Describe
"Research the visual characteristics of the [Race] race from canon D&D 5e sources. Focus on: physical appearance (skin, features, build), typical mundane habitat, and typical clothing for a COMMON VILLAGER or WORKER (not an adventurer/hero).
based on this, write a detailed visual description of a [Gender] [Race] Villager in a slice-of-life setting. The description should be vivid and suitable for image generation. DO NOT generate an image yet."
Step 2: Generate
"Generate a high-quality, detailed fantasy illustration based on the description above. D&D 5e art style. Full body view, showing the character from head to toe. Aspect ratio 1:1 (square)."
3. Submission & Interaction
- Use
evaluate_scriptto insert text and click send (see Fast-Path Automation below). - Always wait for the first response to complete (approx 10-15s) before sending the second prompt.
4. Downloading & Renaming
Use the download_image tool. It automatically handles finding the high-res URL or clicking the download button.
- Tool Call:
download_image(outputPath: "absolute/path/to/Parent_Subrace_Gender.png") - Path Convention:
public/assets/images/races/[Parent]_[Subrace]_[Gender].png(TitleCase).- Example:
Elf_Wood_Male.png - Example:
Dragonborn_Red_Male.png - Example:
Aarakocra_Female.png(No subrace)
- Example:
5. Verification
Use the verify_image_adherence tool to ensure quality.
- Tool Call:
verify_image_adherence(imagePath: "...") - Guidelines Checked: Full Body (Head to Toe), Common Villager/Worker, Slice-of-Life, D&D 5e Style.
- Action: If verification returns
complies: false, consider regenerating the image.
6. Layout Consistency
- Sizing: To ensure race images aren't "huge," generate both Male and Female (or two variations) for every race. This triggers the
hasDualImageslayout in the glossary, which uses small thumbnails instead of full-card width.
6. Automated Wiring & Auditing
Use the scripts/audit_and_wire_images.ts script to automatically:
- Rename files to the
Parent_Subrace_Gender.pngconvention. - Wire the new paths into
src/data/races/*.tsandglossary/*.json. - Audit for missing wiring.
Run with: npx tsx scripts/audit_and_wire_images.ts
7. Cleanup & Efficiency
- New Chat Protocol: The script automatically handles "New Chat" logic when necessary to avoid context bleed.
- Session Reset: If you encounter issues, kill the terminal and run
taskkill /F /IM chrome.exe /Tto fully reset the browser. - Fast-Path Automation: To save tokens and time, avoid
take_snapshotfor known static elements. Useevaluate_scriptwith stable CSS selectors:
8. Implementation (Linking Images)
You must wire up the images in TWO places: the Glossary (JSON) and the Character Creator (TypeScript).
A. Glossary Data (JSON)
- Open
public/data/glossary/entries/races/[race].json. - Add/Update:
"maleImageUrl": "/assets/images/races/[race]_male.png", "femaleImageUrl": "/assets/images/races/[race]_female.png"
B. Character Creator Data (TypeScript)
- Open
src/data/races/[race].ts. - Update the
visualobject within the race constant:
(Note: No leading slash for the TS file paths)visual: { // ... keep existing icon/color maleIllustrationPath: 'assets/images/races/[race]_male.png', femaleIllustrationPath: 'assets/images/races/[race]_female.png', },
Status Checklist (as of 2026-01-20)
Completed:
- Aarakocra (M/F)
- Aasimar (M/F)
- Air Genasi (M/F)
- Astral Elf (M/F)
- Autognome (M/F)
- Bugbear (M/F)
- Centaur (M/F)
- Changeling (M/F)
- Duergar (M/F)
- Dwarf (M/F)
- Earth Genasi (M/F)
- Eladrin (M/F)
- Elf (M/F)
- Fairy (M/F)
- Firbolg (M/F)
- Fire Genasi (M/F)
- Giff (M/F)
- Githyanki (M/F)
- Githzerai (M/F)
- Gnome (M/F)
- Goblin (M/F)
- Goliath (M/F)
- Half-Elf (M/F)
- Half-Orc (M/F)
- Halfling (M/F)
- Hill Dwarf (M/F)
- Hobgoblin (M/F)
- Human (M/F)
- Kalashtar (M/F)
- Kender (M/F)
- Kenku (M/F)
- Kobold (M/F)
- Orc (M/F)
- Plasmoid (M/F)
- Satyr (M/F)
- Shifter (M/F)
- Simic Hybrid (M/F)
- Tabaxi (M/F)
- Tiefling (M/F)
- Triton (M/F)
- Vedalken (M/F)
- Verdan (M/F)
- Warforged (M/F)
- Water Genasi (M/F)
Missing Subraces (To-Do):
Elves:
- High Elf (Male)
- High Elf (Female)
- Wood Elf (Male)
- Wood Elf (Female)
- Drow (Dark Elf) (Male)
- Drow (Dark Elf) (Female)
- Sea Elf (Male)
- Sea Elf (Female)
- Shadar-Kai (Male)
- Shadar-Kai (Female)
- Pallid Elf (Male)
- Pallid Elf (Female)
- Shadowveil Elf (Male)
- Shadowveil Elf (Female)
Dwarves:
- Mountain Dwarf (Male)
- Mountain Dwarf (Female)
- Runeward Dwarf (Male)
- Runeward Dwarf (Female)
Gnomes:
- Rock Gnome (Male)
- Rock Gnome (Female)
- Forest Gnome (Male)
- Forest Gnome (Female)
- Deep Gnome (Svirfneblin) (Male)
- Deep Gnome (Svirfneblin) (Female)
- Wordweaver Gnome (Male)
- Wordweaver Gnome (Female)
Halflings:
- Lightfoot Halfling (Male)
- Lightfoot Halfling (Female)
- Stout Halfling (Male)
- Stout Halfling (Female)
- Lotusden Halfling (Male)
- Lotusden Halfling (Female)
- Hearthkeeper Halfling (Male)
- Hearthkeeper Halfling (Female)
- Mender Halfling (Male)
- Mender Halfling (Female)
Dragonborn (Chromatic/Metallic/Gem):
- Black Dragonborn (Male)
- Black Dragonborn (Female)
- Blue Dragonborn (Male)
- Blue Dragonborn (Female)
- Brass Dragonborn (Male)
- Brass Dragonborn (Female)
- Bronze Dragonborn (Male)
- Bronze Dragonborn (Female)
- Copper Dragonborn (Male)
- Copper Dragonborn (Female)
- Gold Dragonborn (Male)
- Gold Dragonborn (Female)
- Green Dragonborn (Male)
- Green Dragonborn (Female)
- Red Dragonborn (Male)
- Red Dragonborn (Female)
- Silver Dragonborn (Male)
- Silver Dragonborn (Female)
- White Dragonborn (Male)
- White Dragonborn (Female)
- Ravenite Dragonborn (Male)
- Ravenite Dragonborn (Female)
- Draconblood Dragonborn (Male)
- Draconblood Dragonborn (Female)
Tieflings:
- Infernal Tiefling (Male)
- Infernal Tiefling (Female)
- Chthonic Tiefling (Male)
- Chthonic Tiefling (Female)
Aasimar:
- Protector Aasimar (Male)
- Protector Aasimar (Female)
- Scourge Aasimar (Male)
- Scourge Aasimar (Female)
- Fallen Aasimar (Male)
- Fallen Aasimar (Female)
Goliaths:
- Cloud Giant Goliath (Male)
- Cloud Giant Goliath (Female)
- Fire Giant Goliath (Male)
- Fire Giant Goliath (Female)
- Frost Giant Goliath (Male)
- Frost Giant Goliath (Female)
- Hill Giant Goliath (Male)
- Hill Giant Goliath (Female)
- Stone Giant Goliath (Male)
- Stone Giant Goliath (Female)
- Storm Giant Goliath (Male)
- Storm Giant Goliath (Female)
Shifters:
- Beasthide Shifter (Male)
- Beasthide Shifter (Female)
- Longtooth Shifter (Male)
- Longtooth Shifter (Female)
- Swiftstride Shifter (Male)
- Swiftstride Shifter (Female)
- Wildhunt Shifter (Male)
- Wildhunt Shifter (Female)
Eladrin:
- Autumn Eladrin (Male)
- Autumn Eladrin (Female)
- Winter Eladrin (Male)
- Winter Eladrin (Female)
- Spring Eladrin (Male)
- Spring Eladrin (Female)
- Summer Eladrin (Male)
- Summer Eladrin (Female)
Humans (Variants):
- Beastborn Human (Male)
- Beastborn Human (Female)
- Forgeborn Human (Male)
- Forgeborn Human (Female)
- Guardian Human (Male)
- Guardian Human (Female)
- Wayfarer Human (Male)
- Wayfarer Human (Female)
Half-Elves (Variants):
- Aquatic Half-Elf (Male)
- Aquatic Half-Elf (Female)
- Drow Half-Elf (Male)
- Drow Half-Elf (Female)
- High Half-Elf (Male)
- High Half-Elf (Female)
- Wood Half-Elf (Male)
- Wood Half-Elf (Female)
- Stormborn Half-Elf (Male)
- Stormborn Half-Elf (Female)
- Seersight Half-Elf (Male)
- Seersight Half-Elf (Female)
Completion Criteria
Before concluding any image generation task, you must satisfy the following checklist:
- Visual Adherence: Confirm that the generated image has been validated using the visual verification checks (adhering to Full Body view, common D&D villager aesthetic, slice-of-life setting).
- File Naming: Verify the image is saved to
public/assets/images/races/and is named strictly under theParent_Subrace_Gender.pngtitle-case convention. - Double Variation: Confirm that both Male and Female illustrations are generated and successfully saved to trigger the correct dual-image card layout in the UI.
- Data Wiring: Run
npx tsx scripts/audit_and_wire_images.tsand confirm that all new image paths are successfully wired into the glossary JSON files and Character Creator TypeScript definitions. - No Broken Links: Verify the images load correctly on the front-end without rendering missing resource fallbacks or broken image placeholders.