diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-06 16:39:48 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-06 16:39:48 +0300 |
| commit | 00488c7e8d7e93406c3bcf2264d7c7239c3a5516 (patch) | |
| tree | 418a9946e345516aebd6b2173c3fb6d8bdcb2fcb /internal/story/runner.go | |
| parent | 4721d82036bf572b927c36b1df5f3202236d4471 (diff) | |
feat: Gemini panel script drives comic panels in narrative order, v0.25.0v0.25.0
Previously story text was split mechanically into 5 sections and each panel
was guessed from raw prose — causing repeated compositions and incoherent plots.
Now GenerateFull requests a 20-entry panel visual script (P1-A…P5-D) from Gemini
in the same API call as the story and bible. Each panel gets an explicit 1-2 sentence
description of WHO/WHAT/WHERE/expression, written in chronological story order.
buildStoryPagePrompt now uses these descriptions to drive the image model directly
("Draw each panel EXACTLY as described") instead of "scene N from the excerpt".
Falls back to excerpt-driven prompts when the script is absent or incomplete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/story/runner.go')
| -rw-r--r-- | internal/story/runner.go | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/internal/story/runner.go b/internal/story/runner.go index e5e9aa5..c9571a6 100644 --- a/internal/story/runner.go +++ b/internal/story/runner.go @@ -173,7 +173,7 @@ func (r *Runner) Run(batchFile string) error { fmt.Fprintf(os.Stderr, "Warning: could not write theme file: %v\n", err) } - r.drawComicPages(result.StoryText, result.Bible, slug, entries) + r.drawComicPages(result.StoryText, result.Bible, slug, entries, result.PanelScript) // Narration is opt-in (--narrate flag). Skip entirely when not requested // so runs complete faster and don't consume TTS quota unnecessarily. @@ -184,12 +184,16 @@ func (r *Runner) Run(batchFile string) error { return r.handleNarration(result.StoryText, slug, comicsDir) } -// drawComicPages generates the 5 comic images and assembles them into a PDF. -// entries carries the vocabulary words so panels can visually feature and label them. +// drawComicPages generates all 12 comic pages and assembles them into a PDF. +// panelScript carries the explicit per-panel visual descriptions from Gemini so +// each panel illustrates the correct story beat in narrative order. // Errors are non-fatal — story.txt is always accessible regardless of image failures. -func (r *Runner) drawComicPages(storyText, bible, titleSlug string, entries []batch.WordEntry) { +func (r *Runner) drawComicPages(storyText, bible, titleSlug string, entries []batch.WordEntry, panelScript [][]string) { fmt.Printf("Generating %d comic pages...\n", storyPageCount+galleryPageCount+2) // cover + story + gallery + back - paths, err := r.artist.DrawComicPages(storyText, bible, titleSlug, entries) + if len(panelScript) > 0 { + fmt.Println(" Panel script ready — panels will follow narrative order.") + } + paths, err := r.artist.DrawComicPages(storyText, bible, titleSlug, entries, panelScript) if err != nil { fmt.Fprintf(os.Stderr, "Warning: comic page generation failed: %v\n", err) } |
