story-illustrations

Verified@baize/story-illustrations
Use it in Cohub

Paste this into your agent's chat — it fetches the skill and follows it.

Use the skill: story-illustrations. Run `npx -y @neta-art/neta-search-cli@latest skills use @baize/story-illustrations --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.
Use in Neta Studio Open it in Neta Studio and see what people made with it.
Install from a terminal
npx -y @neta-art/neta-search-cli@latest skills use @baize/story-illustrations
Summary

Turn a moment or a storyline from your world into captioned illustrations, collected in one storybook you can read full screen.

  • Draw a single scene, or a series of 2 to 8 pictures that read in order, each with a short caption.
  • Choose your world's own art style, or pick from 150+ looks such as Chinese ink, picture book, cinematic photography or line art.
  • Every story is added to one illustrated storybook page for your world: swipe through it full screen, save one picture, or download everything.
  • Works best with characters that have a clear look and a storyline to follow, such as a journey, a mystery or how two people met.
  • Portrait pictures by default, or wide ones for crowds and panoramas. Your cards, covers and world settings are left unchanged.
SKILL.md
# Story illustrations

Pictures of **what happens** in this world: the characters, in a place of this world, at a moment
that matters. One scene, or a series of 2–8 that reads in order, each with a caption. The creator
gets the world's storybook — a page they can read full screen, save from and share — not loose
images.

## Requirements

This skill decides *what* the pictures are; the neta platform's `generate` skill does the generating.

- Step 1 (what to draw and the look, maybe one questionnaire round) comes first. Only once both are
  settled, read `/mods/neta/.agents/skills/generate/SKILL.md` and
  `/mods/neta/.agents/skills/generate/playbooks/image.md` and follow their core loop (declaration,
  references, submit, look). Steps 3–5 run inside that loop.
- If `/mods/neta` does not exist in this world, say image generation is not available here and stop.
- `<skill-dir>` = the folder this SKILL.md sits in. The scripts need `python3` and ImageMagick
  (`magick` or `convert`), both in the Studio sandbox.

## Inputs

| Input | Required | Counts as given when |
|---|---|---|
| What to draw | yes | a **scene**: the message describes one moment, or carries selected cards (characters + a place and/or an event); a **thread**: the message names a storyline ("her journey south", "the red thread mystery", "how they met", an arc card, a script file). "Draw something from the story" does not count → ask (step 1). |
| Look | asked when not given | the message names a look: "like the world", a style name, a style id or an old handraw number |
| How many | no | scene → 1; thread → 6 (the user may say 2–8) |
| Shape | no (portrait 2:3) | the user asks for wide / 横版, or the moment is a crowd or a panorama → landscape 3:2 |
| Language | no | the user's language; the world's language if the user wrote none |

Ask at most **one** round, with the platform questionnaire, only for what is open (see
[`references/questionnaire.md`](references/questionnaire.md)). Everything else has a default.

## Looks

| Look | When | How it is made |
|---|---|---|
| **world** | asked for, picked in the questionnaire, or the questionnaire skipped | the world's own `visualStyle` (in `world/WORLD.md`), characters referenced with `@Name` (their covers), on the creator's own image model |
| **styled** | the user names one of the tested styles, or picks it in the questionnaire | style first: the style's sample image is the only image, characters described in words (no `@`), on GPT Image 2.5 |

Styled looks: in `references/scene-styles.json`. Every one drew the same place well, and a
two-character scene test kept both the style and the characters (see `tested`). Do not read the file
whole; use `python3 <skill-dir>/scripts/styles.py` — `find "<words>"` (a name in any language, a
keyword, an id like `FE-004`, an old handraw number), `get <id>` (`prompt`, `sample`, `preview`),
`tiles --kind guofeng|modern|nature|fantasy` (the questionnaire's choices). Add `--lang <user
language>` for names. Not in the list → the closest `find` result, and say which.
When the creator asks which styles there are, give the gallery page
(`gallery` in `scene-styles.json`): every style with its sample, searchable, in their language.

## Deliver

**One storybook per world**: a published web Work, `works/web/<world-slug>-stories`. Every run adds
one story on top (a single scene is a story with one picture). Pictures in reading order, caption
under each, full-screen reader with swipe, save one picture, a story, or everything as a zip; page
UI in the user's language. Re-publishing the same Work keeps one storybook card on the Board. Each
picture is also its own image work (generated as one). Handed over with an interaction-components
work card and the frames as a short list, then next-steps.

**Nothing else in the world changes**: no covers, no `visualStyle`, no cards edited. If the creator
wants a picture as a cover, they ask, and you set only that one (`atom cover set`), saying the old
cover stays in the card's media.

## Steps

1. **What and look.** Read `manifest.json`, `world/WORLD.md`, the cards
   (`node /mods/neta/neta atom list`), and any script or outline files (`story/`, `works/` titles)
   so the pictures follow what already exists.
   - Scene or thread *given* → go on. A selected character + place without a moment → it is a
     scene: pick the most telling moment for those two from the cards, and say which in the reply.
   - Look *given* → go on.
   - Anything open → one questionnaire round per [`references/questionnaire.md`](references/questionnaire.md).
     Nothing is generated before the answers are back.

2. **Plan the pictures** per [`references/picking-scenes.md`](references/picking-scenes.md): for each
   frame a short title, a scene line (who, where, what they are doing, light, shot), and the caption;
   plus the story's title and a one-line blurb. Characters appear with the same **anchor line** in
   every frame (from their card's look: hair, clothes colours, one signature object). Do not stop to
   confirm — the plan shows up in the reply with the pictures.

3. **Generate** (one image each). Read the declaration first
   (`node /mods/neta/neta generate image params`, with the model prefix below for styled looks):
   portrait → `size` `1024x1536` / `aspect_ratio` `2:3`; landscape → `1536x1024` / `3:2`. Submit all
   frames **as parallel tool calls**, each with `--work-title "<Story title> · <N> · <frame title>"`.
   Prompts: [`references/scene-prompt.md`](references/scene-prompt.md).
   - **World look**: `@Name` for each named character in the frame (their covers come along);
     `--image <the place's cover>` when the frame is set in a location card that has one. First
     open one or two of those covers: if they are in a different look from `visualStyle` (covers
     restyled as illustrations while the style says photographic, or the other way round), attach
     **no** covers — names without `@`, anchor lines only — and never fight a reference with
     "not a drawing / not anime" in the prompt.
   - **Styled look**: prefix each command with `NETA_DEFAULT_IMAGE_MODEL=gpt-image-2.5`;
     `--image <sample URL>` is the only image; **no `@`** (a cover would pull the picture back to the
     world's look). Say in one short line that it takes 1–2 minutes.
   - If the provider blocks a frame: soften that frame's scene line once (no weapons drawn, no
     blood, no injuries shown, no named franchise) and resubmit it alone; blocked again → finish
     without it and say so. At most `frames + 3` submits for one story.

4. **Look, then file the story.**
   - Open each picture: the right characters (anchors visible: hair, clothes), the right place and
     moment, the look right, no garbled text. One picture wrong → one rework of it
     (`--target-work`), then go on. Captions say only what the picture and the cards support.
   - Find or create the storybook and add the story:

     ```bash
     B=<skill-dir>/scripts/storybook.py
     python3 $B find                                   # {"work": "works/webs/<world-slug>-stories", ...} or {"work": null}
     # no storybook yet:
     WORK="works/web/<world-slug>-stories"
     node /mods/neta/neta work init web "$WORK" --title "<World> · <Illustrated stories in the user's language>"
     # use the work dir init printed, then:
     python3 $B init --work "$WORK" --title "<World> · …" --subtitle "<world name>" --lang <code> --file-base <world-slug>
     # either way:
     DIR=$(python3 $B next --work "$WORK" | python3 -c "import sys,json;print(json.load(sys.stdin)['dir'])")
     # frames.json: [{"image": "<mediaPath>", "title": "…", "caption": "…"}, …] in reading order
     python3 $B add --work "$WORK" --dir "$DIR" --title "<story title>" --blurb "<one line>" \
       --style "<look name in the user's language>" --frames-file frames.json
     ```

     `<World>` / `<world name>` = the world's own name exactly as in `world/WORLD.md` (never
     translated or renamed); only the words around it ("Illustrated stories", "故事绘本") follow the
     user's language. The look name: "World style" / "原画风" for the world look, the style's `name` otherwise.
     `init` on a storybook that already exists keeps it (`"kept"`) — carry on with `next`.

5. **Publish and place.**

   ```bash
   cp <skill-dir>/templates/index.html "$WORK/index.html"
   cp -r <skill-dir>/templates/neta "$WORK/"
   T=$(python3 -c "import json;t=open('$WORK/storybook.js').read();print(json.loads(t[t.index('{'):t.rindex('}')+1])['title'])")
   sed -i "s|{{BOOK_TITLE}}|$T|" "$WORK/index.html"
   node /mods/neta/neta work publish web "$WORK"
   node /mods/neta/.agents/skills/board-ops/scripts/place.mjs --title "$T" --work "$WORK"
   ```

   - `world_slug_required` → set a readable kebab-case world slug (`neta world slug set`), publish again.
   - Publishing fails → place the image works instead and say plainly the storybook did not publish.

6. **Reply and close.** Hand over the storybook with an **interaction-components** link card to the
   work (`{ "type": "work", "workId": "<jq -r .cohubWorkId "$WORK/meta.json">" }`, a real
   `<interaction-json>` block). Under it, the story's title and each frame as
   `N · <frame title> — what the picture shows`, describing what you **saw**. Then **next-steps**:
   first "the same story in another look" (no look named, so the questionnaire comes up), then the
   next part of this thread or another thread of this world by name, then one single scene from
   this story the creator might want bigger.

## Changing one picture later

"Redo the third one", "make the lake scene at night": rework that frame's image work with
`--target-work`, same look and prompt with the scene line changed, then
`storybook.py replace --work "$WORK" --dir <the story's dir> --frame <N> --image <new mediaPath>`
(`--caption` / `--title` to change the text) and publish the same Work again.

## Out of scope

- No changes to covers, world settings or cards (see Deliver).
- No deleting files that existed before the run.
- No speech bubbles or lettering in the pictures — captions live on the page. For a comic page,
  use a comic skill.
- No real people, no named franchises, no gore.

## Not this skill

- Postcards of one place at different moments → `location-postcards`.
- Stickers of a character → `character-emotes`. A character model sheet → `character-design-sheet`.
- A story as prose chapters → `novel-chapter-pages`. A video → `generate` (video) or a PV skill.