comic/odin/docs/PRODUCTION_PLAN.md
2026-05-22 03:51:50 +02:00

304 lines
13 KiB
Markdown

# Comic-Odin Production Readiness Plan
## Current State Summary
| Metric | Value |
|--------|-------|
| **Source files** | 38 .odin files |
| **Test count** | 156 passing |
| **GUI screens** | 8/8 defined (Community is placeholder) |
| **Workflow steps** | 8/8 implemented |
| **Export formats** | 3/3 (PDF with real page rendering) |
| **CLI/TUI** | Fully functional |
| **Native GUI** | ~1200 lines Raylib, dark theme |
| **P0 items** | 5/5 complete |
| **P1 items** | 5/5 complete |
| **P2 items** | 5/5 complete (all done) |
## Critical Production Gaps (P0 - Must Fix Before Release)
### P0-1: PDF Export — Replace Text Placeholder with Real Page Rendering
**Current**: Writes a minimal text-only PDF with panel count. No images embedded.
**Target**: Canvas-like page composition with panel images positioned per layout cells.
**Implementation plan**:
1. Add `stb_image.h` binding (or use existing Odin image loading) to load panel images from URLs/local paths
2. Create `render_page_to_image` proc that:
- Creates a blank canvas at page dimensions (from `Page_Size`)
- Fills white background
- For each panel: loads image, calculates pixel position from `Layout_Cell` fractions, draws with gutter margins, draws black border
3. Integrate with existing PDF writer or switch to a proper PDF library (e.g., `harfbuzz` + `freetype` for text, or use `wkhtmltopdf`/`weasyprint` subprocess like current CBZ zip approach)
4. Add DPI scaling (default 300 DPI)
5. Test: Export a 4-page comic, verify PDF opens in viewer with correct panel positions
**Files to modify**: `src/adapters/export.odin`
**New files**: `src/adapters/image_loading.odin`
**Estimated effort**: 2-3 days
### P0-2: Character Consistency — IP-Adapter Reference Images
**Current**: `generate_panel_image` ignores character reference images (`_ = characters`).
**Target**: Pass character reference image URLs to fal.ai API for consistent character appearance.
**Implementation plan**:
1. Add `reference_images: []string` and `reference_image_strength: f32` to fal.ai request body
2. Collect `character.reference_image_url` for all characters in `panel.characters_present`
3. Pass `reference_image_strength = 0.65` (the "sweet spot" from TypeScript)
4. Add `reference_images` field to `Character` struct (already has `reference_image_url`)
5. Store character reference images in `Comic_State` as a map: `character_ref_images: map[string]string` (character_id → URL)
6. Test: Generate panels with 2+ characters, verify visual consistency across panels
**Files to modify**: `src/adapters/fal.odin`, `src/core/types.odin`, `src/gui/actions.odin`
**Estimated effort**: 1-2 days
### P0-3: Shot-Type-Based Image Sizing
**Current**: All panels generated at fixed 1024x1024.
**Target**: Map shot types to appropriate aspect ratios for better composition.
**Implementation plan**:
1. Add `get_image_size_for_shot_type` proc mapping:
- `establishing`, `wide`, `aerial``landscape_16_9`
- `medium`, `over-shoulder``landscape_4_3`
- `close-up``portrait_4_3`
- `extreme-close-up``square_hd`
2. Pass `image_size` parameter to fal.ai request
3. Store actual returned dimensions in `Panel_Image.width/height`
4. Test: Generate panels with varied shot types, verify different aspect ratios
**Files to modify**: `src/adapters/fal.odin`, `src/core/layout.odin`
**Estimated effort**: 0.5 days
### P0-4: Art Style Keyword Mapping
**Current**: Raw `art_style` string passed to prompts.
**Target**: 8 defined art styles with detailed keyword expansions.
**Implementation plan**:
1. Add `Art_Style_Key` enum: `Manga, Western_Comic, Pixel_Art, Watercolor, Noir, Chibi, Sketch, Cyberpunk`
2. Add `ART_STYLE_KEYWORDS` constant map with detailed prompt keywords per style
3. Add `QUALITY_MODIFIER` constant: `"high quality, detailed, clean lines, vibrant colors, professional illustration, best quality, masterpiece"`
4. Add `get_style_keywords` proc to expand art style into prompt prefix
5. Update `build_local_panel_images` and `generate_panel_image` to prepend style keywords
6. Test: Generate panels with each art style, verify prompt includes correct keywords
**Files to modify**: `src/core/types.odin`, `src/adapters/fal.odin`, `src/gui/local_helpers.odin`
**Estimated effort**: 1 day
### P0-5: Negative Prompts
**Current**: No negative prompts in image generation.
**Target**: Add negative prompts to improve output quality.
**Implementation plan**:
1. Add `negative_prompt: string` to fal.ai request body
2. Character reference negative: `"blurry, low quality, distorted face, extra limbs, bad anatomy, deformed, watermark, signature"`
3. Panel negative: `"blurry, low quality, distorted face, extra limbs, bad anatomy, deformed, watermark, signature, text, speech bubble"`
4. Test: Generate panels with and without negative prompts, compare quality
**Files to modify**: `src/adapters/fal.odin`
**Estimated effort**: 0.5 days
## High Priority Gaps (P1 - Important for Quality)
### P1-1: Multi-Angle Character Sheet Generation
**Current**: Single reference portrait only.
**Target**: 4-angle character sheet (front, 3/4, profile, back) with IP-Adapter consistency.
**Implementation plan**:
1. Add `generate_character_sheet` proc that iterates 4 poses sequentially
2. First pose generates anchor image; subsequent poses use first image as `reference_images` with `reference_image_strength: 0.65`
3. Poses: front-facing, three-quarter, side profile, back view
4. Store sheet URLs in `Character.character_sheet_urls`
5. Add GUI button "Generate Character Sheet" on Characters screen
6. Test: Generate sheet for a character, verify 4 distinct but consistent images
**Files to modify**: `src/adapters/fal.odin`, `src/gui/actions.odin`, `src/gui/summary_views.odin`
**Estimated effort**: 2 days
### P1-2: Emotion Enum + Structured Dialogue
**Current**: `emotion` is a free-form string in `Dialogue`.
**Target**: Proper `Emotion` enum with 6 values.
**Implementation plan**:
1. Add `Emotion` enum: `Happy, Sad, Angry, Surprised, Neutral, Determined`
2. Update `Dialogue` struct: `emotion: Emotion`
3. Update DeepSeek response parser to map string emotions to enum
4. Update bubble auto-placement to consider emotion (e.g., Shout for Angry, Whisper for Sad)
5. Update JSON serialization/deserialization
6. Test: Generate script, verify emotion enum populated correctly
**Files to modify**: `src/core/types.odin`, `src/adapters/deepseek.odin`, `src/core/bubble.odin`
**Estimated effort**: 0.5 days
### P1-3: Character Description Parser
**Current**: Character descriptions are free-form text.
**Target**: Parse natural language descriptions into structured `Character_Prompt_Template`.
**Implementation plan**:
1. Add 10 regex extraction procs (age, gender, hair color, hair style, eye color, skin tone, body type, outfit, accessories, distinguishing features)
2. Add `parse_description_to_template` proc
3. Add `extract_color_palette` proc
4. Add GUI helper: "Parse Description" button on Characters screen
5. Test: Parse "25-year-old female, black long hair, blue eyes, fair skin, slim build, wearing a red dress, glasses, scar on cheek" → structured template
**Files to modify**: `src/core/character_prompt.odin`, `src/gui/actions.odin`
**New files**: `src/core/character_parser.odin`
**Estimated effort**: 1-2 days
### P1-4: CBZ/PNG Export — Use Real Image Rendering Instead of Raw Copies
**Current**: CBZ/PNG exports copy raw panel images without page composition.
**Target**: Render full pages with panels positioned per layout (same as PDF).
**Implementation plan**:
1. Reuse `render_page_to_image` from P0-1
2. For CBZ: render each page to PNG, add to zip with `page_XXX.jpg` naming
3. For PNG: same but output as individual PNG files in a zip
4. Add `ComicInfo.xml` with proper metadata (Title, Series, Count, etc.)
5. Test: Export CBZ, open in comic reader (e.g., CDisplayEx)
**Files to modify**: `src/adapters/export.odin`
**Estimated effort**: 1 day
### P1-5: Progress Tracking During Generation
**Current**: No progress feedback during long operations.
**Target**: Real-time progress updates in GUI.
**Implementation plan**:
1. Add `progress_callback` parameter to `generate_all_panels_batched`
2. Update job manager to track progress percentage
3. Add progress bar to GUI during generation (overlay or inline)
4. Update status message with "Generating panel 3/12 (25%)"
5. Test: Generate 12 panels, verify progress updates visible
**Files to modify**: `src/ui/jobs.odin`, `src/gui/runtime.odin`, `src/adapters/fal.odin`
**Estimated effort**: 1 day
## Medium Priority Gaps (P2 - Polish)
### P2-1: DeepSeek Streaming Generation
**Current**: Waits for full response before showing results.
**Target**: Streaming partial JSON for real-time preview.
**Implementation plan**:
1. Add `stream_comic_script` proc using curl with streaming response
2. Parse partial JSON chunks, update GUI progressively
3. Add "Generating..." overlay with partial script preview
4. Fallback to non-streaming if streaming fails
**Files to modify**: `src/adapters/deepseek.odin`, `src/gui/runtime.odin`
**Estimated effort**: 2 days
### P2-2: Appearance Count Tracking
**Current**: `Character.appearance_count` field exists but is never populated.
**Target**: Auto-count character appearances across panels.
**Implementation plan**:
1. Add `count_character_appearances` proc that iterates all panels
2. Call after script generation and panel generation
3. Display count in Characters screen summary
**Files to modify**: `src/core/script.odin`, `src/gui/summary_views.odin`
**Estimated effort**: 0.5 days
### P2-3: Genre-Based Layout Pattern Selection
**Current**: Layout pattern selection considers genre but `pattern_matches_genre` is basic.
**Target**: Full genre-to-pattern mapping with tightest-fit algorithm.
**Implementation plan**:
1. Add `get_patterns_by_genre` proc
2. Update `select_best_pattern` to use tightest-fit (smallest maxPanels that fits)
3. Add genre filtering to pattern selection
**Files to modify**: `src/core/layout.odin`
**Estimated effort**: 0.5 days
### P2-4: Bubble Text Editing in GUI
**Current**: Bubble text can only be changed via project file edit.
**Target**: Inline text editing in bubble editor.
**Implementation plan**:
1. Add text input field to bubble detail panel
2. Add "Save" button to commit text changes
3. Update `action_update_bubble` to accept new text
4. Add keyboard shortcut for text editing mode
**Files to modify**: `src/gui/bubbles_views.odin`, `src/gui/runtime.odin`, `src/gui/actions.odin`
**Estimated effort**: 1 day
### P2-5: Manual Bubble Positioning
**Current**: Bubbles are auto-placed only.
**Target**: Drag-to-reposition bubbles in GUI.
**Implementation plan**:
1. Add mouse drag detection on bubble preview
2. Update bubble `position` on drag
3. Add "Reset Position" button to revert to auto-place
4. Save position changes to project
**Files to modify**: `src/gui/bubbles_views.odin`, `src/gui/runtime.odin`
**Estimated effort**: 2 days
## Low Priority Gaps (P3 - Nice to Have)
### P3-1: Community Features
**Current**: Placeholder screen.
**Target**: Publish/share/browse functionality.
**Estimated effort**: 5+ days (defer to future release)
### P3-2: Undo/Redo for Bubble and Layout Edits
**Current**: No undo support.
**Target**: Command history for bubble/layout changes.
**Estimated effort**: 2-3 days
### P3-3: Multi-Monitor Awareness
**Current**: Launches on primary monitor only.
**Target**: Remember last window position, support multi-monitor.
**Estimated effort**: 1 day
### P3-4: Image Asset Caching to Disk
**Current**: Images stored in memory only.
**Target**: Cache generated images to `assets/` directory.
**Estimated effort**: 1-2 days
### P3-5: Custom Layout Pattern Assignment
**Current**: Layout regeneration cycles through patterns.
**Target**: Manual pattern selection dropdown.
**Estimated effort**: 1 day
## Implementation Order
| Phase | Milestones | Duration | Tests Added | Status |
|-------|-----------|----------|-------------|--------|
| **Phase 1** | P0-1 (PDF export), P0-3 (shot sizing), P0-5 (negative prompts) | 3 days | +10 | ✅ |
| **Phase 2** | P0-2 (character consistency), P0-4 (art styles) | 2 days | +8 | ✅ |
| **Phase 3** | P1-4 (CBZ/PNG rendering), P1-5 (progress tracking) | 2 days | +6 | ✅ |
| **Phase 4** | P1-1 (character sheets), P1-2 (emotion enum) | 2.5 days | +8 | ✅ |
| **Phase 5** | P1-3 (description parser), P2-3 (genre layouts) | 2 days | +6 | ✅ |
| **Phase 6** | P2-1 (streaming), P2-2 (appearance count), P2-4 (bubble text), P2-5 (bubble position) | 2.5 days | +14 | ✅ |
| **Phase 7** | P2-5 (bubble positioning GUI drag) | 1 day | +13 | ✅ |
| **Phase 8** | P3 items (deferred) | TBD | TBD | ⏳ |
**Total estimated effort**: ~17 days for P0-P2 (production-ready)
**Expected test count after completion**: ~150+
**Actual test count**: 156 ✅
**Total estimated effort**: ~17 days for P0-P2 (production-ready)
**Expected test count after completion**: ~150+
## Release Criteria
Before v0.3.0 release:
- [x] All P0 items complete and tested
- [x] All P1 items complete and tested
- [x] All P2 items complete and tested
- [x] 150+ tests passing (156/150)
- [ ] No memory leaks in test output
- [x] PDF export produces valid comic with images
- [x] CBZ opens in standard comic readers
- [x] Character consistency verified across 10+ panels
- [ ] GUI smoke test: full pipeline (story → script → panels → layout → bubbles → export) works end-to-end
- [ ] CLI smoke test: `auto-all` command completes without errors
- [ ] Package script produces valid artifact with checksums