[](README.md) [](README.en.md) [](https://x.com/eternityspring) # novel-characters Feed it a novel or a short story, and get a complete design bible for every character: - **Cast list** — who appears, how central they are, with every name a character is called by folded into one person - **Profile** — gender, age, standing, appearance, temperament, motivation, arc, relationships, each backed by **verbatim quotes from the source** - **Design prompts** — bilingual image prompt + negative prompt + tags, ready for Midjourney / SD / GPT-Image. The look is not written into the prompt: the caller prepends one style instruction to the whole batch at generation time - **Voice prompts** — timbre, pitch, pace, accent, emotion, plus a voice-design prompt for Qwen3-TTS / ElevenLabs Voice Design - **A character model sheet** — **one per character**: a 16:9 image in three zones: an ID-photo-style bust on the left (~34%, the reference for the face design), a full-body turnaround top-right, and a strip of key-detail close-ups bottom-right. White background for clean cut-out. **This skill does not generate the image** — the instruction is the deliverable - **Relationship map** — a whole-cast view inside the report: who is tied to whom, and how. Hover a character to light up every link they are part of, click to jump to their profile Outputs `cast.json`, a Markdown report, and a self-contained `report.html` you can just double-click. **Any output language**, Chinese by default: ``` /novel-characters ./book.txt --lang en /novel-characters ./book.txt --lang ja ``` Chinese, English and Japanese UI strings ship built in. **Other languages work too** — the skill translates the UI labels on the fly into the target language and stores them in `cast.json` under `ui`, so French, Korean or Spanish reports come out fully localized rather than half-English.  A character model sheet (Shen Zhiwei, from the bundled sample story):  ## Upstream In the pipeline the **outline sits upstream of the character bible**: ``` novel-outline → outline.json (what: structure & episodes, who is in) novel-characters → cast.json (who: character assets) ``` If you have an `outline.json`, start with `seed` — its `characters` block already settles the roster: ```bash node scripts/novel-characters.mjs seed outline.json > seed.json ``` What comes across is what the outline already decided (character id, name, tier, arc, which source characters were merged into this one); what is left blank is the work this layer owes (aliases, profile, design prompt, voice prompt). `tier` maps onto `importance`: `lead` → protagonist, `support` → supporting, `functional` → minor. **Do not overturn the outline's tiers here**; if a tier looks wrong, go fix the outline. Splitting *within* the lead group is fine — `lead` covers leads plus the main antagonist, so `seed` assigns protagonist to all of them and you demote the non-leads to major using the `role` recorded in `seedNote`. **It runs fine without one** — this skill does not depend on it. Skip `seed`, feed it a raw novel, and it builds the roster from the text itself. ## Use For installation see the [repository README](../../README.en.md). Then: ``` /novel-characters ./your-novel.txt ``` Or just say "break this book down into characters" and give it the path. ### Report language Chinese by default. Use `--lang`, or just ask in words: ``` /novel-characters ./book.txt --lang en /novel-characters ./book.txt --lang ja ``` Chinese, English and Japanese UI strings ship built in. **Any other language works too** — the skill translates the UI labels into the target language on the fly and stores them in `cast.json` under `ui`, so French, Korean or Spanish reports come out fully localized rather than half-English. Two things never follow the language: **image and TTS prompts stay English** (those engines work best that way), and **source quotes stay in the original language** (translate them and they stop being evidence). ## What the report looks like A three-column workbench: search on top, synopsis plus a prominence-ordered cast list on the left, one character at a time in the main area. The **relationship map** sits at the top of the left rail and takes over the main area. Its edges come straight from each character's `relationships` — no extra model pass: - Edges resolve by **name *and* alias**, so a relationship written as "老伯" still lands on 老周's node - Two one-directional accounts of the same pair collapse into one edge, keeping both wordings - Each chord carries a short label (6 characters, full text in the tooltip and the side list). Labels get noisy on a large cast, so they are on by default up to 14 edges and off above that, with a toggle in the header - Hover a character to light up every link they are part of, hover a row to isolate one link, click either to open that character The circular layout is computed in Node and written straight into inline SVG — **no libraries**, so report.html stays a single file you can open offline. ### Export JSON The **Export JSON** button in the top bar downloads exactly the `cast.json` shape — not some separate export format: ```json { "source": "…", "lang": "zh", "summary": "…", "characters": [ … ] } ``` So an external tool can edit it and **feed it straight back into `render`**, and it still passes `validate`. Each character keeps its `sheetImage` path, so you know which sheet belongs to whom — point `render --images