Teaches Claude how to render a ChapterScript into panel PNGs via the ernie-mcp image server and stitch them into a webtoon chapter.png. Use after a ChapterScript JSON has been approved by the user, typically inside the /manhwa-chapter flow or when the user asks to "render this script", "re-render from script.json", or "make the panels".
You have an approved ChapterScript (from the writing-manhwa-scripts skill). This skill turns it into panel PNGs plus a stitched chapter.png.
/manhwa-chapterscript.json pathmcp__ernie__ernie_generate and mcp__ernie__ernie_health tools must be available. They come from the ernie-mcp MCP server (installed separately).Before rendering a single panel, call mcp__ernie__ernie_health. If the response is do not proceed. Tell the user:
{"ok": false, ...}The ERNIE server at
<host>isn't reachable:<error>. Start it and retry. (See the ernie-mcp README for exact startup commands.)
Do not attempt to "fix" ERNIE by calling other tools. The user starts the server themselves.
For each PanelBeat in script.panels, construct a prompt string by concatenating these parts in order (space-separated):
A Korean manhwa panel in full color, vertical composition, <framing>.
Where <framing> is the panel's framing field verbatim.
Filter panel.characters_in_panel to characters that actually exist in script.characters (skip any meta/unknown names). For each visible character, emit Name: visual_description. Join with | and wrap:
Characters visibly present (draw exactly as described): Kenji: Japanese man, late 50s... | Hana: Japanese girl, about 7... .
If characters_in_panel is empty, skip this part entirely.
Append the panel's description field verbatim (stripped of leading/trailing whitespace).
Look up the panel's mood in this table and append the matching lighting string plus a period:
| mood | lighting string |
|---|---|
| tense | harsh contrasting shadows, dramatic rim lighting |
| melancholic | soft diffused light, muted palette, rain drops or fog |
| hopeful | warm golden hour light, gentle bloom, pastel highlights |
| ominous | deep cool shadows, blue-green palette, eerie glow |
| action-packed | motion blur, speed lines, high-contrast dynamic lighting |
| wistful | soft twilight purples and pinks, gentle haze |
| neutral / other | balanced natural lighting |
dialogue is non-null)A clean white speech bubble with black outline, English text reading exactly: "<dialogue>".
If speaker is also set AND appears in the visible character list, append Bubble points toward <speaker name>.
caption is non-null)A narration caption box with dark background and white English text reading exactly: "<caption>".
Art style: <script.style>. Sharp cel-shading, thick digital linework, clean outlines, professional webtoon quality.
ERNIE only accepts specific sizes. Pick (width, height) for each panel:
| framing keyword contains | width × height |
|---|---|
wide or establishing | 848 × 1264 |
close (close-up, extreme close) | 1264 × 848 |
| anything else (medium, low, high) | 768 × 1376 |
Lowercase the framing string before matching. These three sizes are all in ERNIE's allowed set.
For each panel idx, call:
mcp__ernie__ernie_generate(
prompt=<built prompt from Step 2>,
width=<width from Step 3>,
height=<height from Step 3>,
seed=42 + idx,
steps=8,
)
Seeding with 42 + idx keeps re-runs reproducible. The response includes a path key — the PNG is already on disk. Copy or move it to the chapter's output folder as <out_dir>/panels/panel_<NN>.png where <NN> is zero-padded two digits (panel_00.png, panel_01.png, ...).
Also write the built prompt to <out_dir>/panels/panel_<NN>.prompt.txt so the user can reproduce or tweak.
Render panels sequentially, not in parallel — the ERNIE server is single-GPU and will queue anyway, and sequential output lets you give the user incremental progress updates ("panel 7 of 30 done").
If ernie_generate raises:
Once all panels are saved, run the bundled composition script:
python ${CLAUDE_PLUGIN_ROOT}/skills/rendering-manhwa-panels/scripts/compose_chapter.py \
--panels-dir "<out_dir>/panels" \
--out "<out_dir>/chapter.png" \
--title "<script.title>"
If that command fails with ModuleNotFoundError: No module named 'PIL', retry with uv (which self-installs Pillow in an ephemeral env):
uv run --with pillow python ${CLAUDE_PLUGIN_ROOT}/skills/rendering-manhwa-panels/scripts/compose_chapter.py \
--panels-dir "<out_dir>/panels" \
--out "<out_dir>/chapter.png" \
--title "<script.title>"
If uv also isn't available, tell the user:
Pillow (the Python imaging library) isn't installed. Either run
pip install Pillowor installuv(https://docs.astral.sh/uv/) and retry. All the individual panels are saved in<out_dir>/panels/regardless.
Summarize to the user:
chapter.pngscript.json laterERNIE cannot "remember" a character between separate generations. Consistency comes entirely from the visual description you inject into every panel prompt (Part 2 above). That's why the writing-manhwa-scripts skill insists on dense casting sheets — and why you must NOT paraphrase them during rendering.