304 lines
13 KiB
Markdown
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
|