$npx -y skills add thedivergentai/GD-Agentic-Skills --skill godot-genre-visual-novelExpert blueprint for visual novels (Doki Doki Literature Club, Phoenix Wright, Steins;Gate) focusing on branching narratives, dialogue systems, choice consequences, rollback mechanics, and persistent flags. Use when building story-driven, choice-based, or dating sim games. Keywor
| 1 | # Genre: Visual Novel |
| 2 | |
| 3 | Branching narratives, meaningful choices, and quality-of-life features define visual novels. |
| 4 | |
| 5 | ## Core Loop |
| 6 | 1. **Read**: Consume narrative text and character dialogue |
| 7 | 2. **Decide**: Choose at key moments |
| 8 | 3. **Branch**: Story diverges based on choice |
| 9 | 4. **Consequence**: Immediate reaction or long-term flag changes |
| 10 | 5. **Conclude**: Reach one of multiple endings |
| 11 | |
| 12 | ## NEVER Do (Expert Anti-Patterns) |
| 13 | |
| 14 | ### Narrative & Flow |
| 15 | - NEVER create the "Illusion of Choice" exclusively; strictly provide **Immediate Dialogue Variations** or **Flag Changes** even if the plot converges later. |
| 16 | - NEVER skip mandatory QoL features; strictly implement **Auto-Play**, **Fast-Forward**, and **Backlog/History** for replayability. |
| 17 | - NEVER display "Walls of Text"; strictly limit dialogue boxes to **3-4 Lines** max to avoid intimidating the reader. |
| 18 | - NEVER hardcode dialogue text inside GDScripts; strictly store narrative scripts in **External Files** (JSON, CSV, or custom Resources) for iteration. |
| 19 | - NEVER ignore the **Rollback** mechanic; strictly maintain a history stack so players can undo miss-clicks or reread missed lines. |
| 20 | |
| 21 | ### Technical & UI |
| 22 | - NEVER use plain text for emotional beats; strictly use **RichTextLabel BBCode** (e.g., `[shake]`, `[wave]`) to add visual weight. |
| 23 | - NEVER parse massive narrative files on the main thread; strictly use **`ResourceLoader.load_threaded_request()`** to prevent transition stutters. |
| 24 | - NEVER use standard Strings for frequently accessed game flags; strictly use **`StringName`** (&"met_alice") for faster dictionary lookups. |
| 25 | - NEVER use `_process` for letter-by-letter animation; strictly use a **Tween on `visible_ratio`** for smooth, frame-independent reveals. |
| 26 | - NEVER neglect character **Z-ordering**; strictly ensure the active speaker is brought to the front (highest `z_index`) for visual clarity. |
| 27 | - NEVER use `z_index` for `Control` node priority if input handling is required; strictly use `move_to_front()` to ensure draw order and input propagation match. |
| 28 | - NEVER use absolute pixel positioning for character sprites; strictly rely on **Anchors & Percent-based Offsets** for responsive scaling. |
| 29 | - NEVER allow text animations to continue when the player skips; strictly set **`visible_ratio` to 1.0** instantly on input. |
| 30 | - NEVER leave orphaned character sprites; strictly use **`queue_free()`** when actors exit the stage to prevent memory leaks. |
| 31 | |
| 32 | --- |
| 33 | |
| 34 | ## Godot 4.7: Visual Novel UI |
| 35 | |
| 36 | - Migrate RichTextLabel images to `ImageUnit` API — `width_in_percent` removed in 4.7. |
| 37 | |
| 38 | ## 🛠 Expert Components (scripts/) |
| 39 | |
| 40 | ### Original Expert Patterns |
| 41 | - [story_manager.gd](scripts/story_manager.gd) - Flag-aware dialog orchestrator with branching logic and character state persistence. |
| 42 | - [dialogue_ui.gd](scripts/dialogue_ui.gd) - Presentation layer with typewriter tweens and choice-window generation. |
| 43 | - [vn_rollback_manager.gd](scripts/vn_rollback_manager.gd) - History stack maintenance for state rollback (flags/backgrounds/index). |
| 44 | |
| 45 | ### Modular Components |
| 46 | - [visual_novel_patterns.gd](scripts/visual_novel_patterns.gd) - Reusable patterns: BBCode effects, choice filtering, and sprite layering. |
| 47 | - [dialogue_ui.gd](scripts/dialogue_ui.gd) - Base UI core for dialogue and character management. |
| 48 | |
| 49 | --- |
| 50 | |
| 51 | | Phase | Skills | Purpose | |
| 52 | |-------|--------|---------| |
| 53 | | 1. Text & UI | `ui-system`, `rich-text-label` | Dialogue box, bbcode effects, typewriting | |
| 54 | | 2. Logic | `json-parsing`, `resource-management` | Loading scripts, managing character data | |
| 55 | | 3. State | `godot-save-load-systems`, `dictionaries` | Flags, history, persistent data | |
| 56 | | 4. Audio | `audio-system` | Voice acting, background music transitions | |
| 57 | | 5. Polish | `godot-tweening`, `shaders` | Character transitions, background effects | |
| 58 | |
| 59 | ## Architecture Overview |
| 60 | |
| 61 | ### 1. Story Manager (The Driver) |
| 62 | Parses the script and directs the other systems. |
| 63 | |
| 64 | ```gdscript |
| 65 | # story_manager.gd |
| 66 | extends Node |
| 67 | |
| 68 | var current_script: Dictionary |
| 69 | var current_line_index: int = 0 |
| 70 | var flags: Dictionary = {} |
| 71 | |
| 72 | func load_script(script_path: String) -> void: |
| 73 | var file = FileAccess.open(script_path, FileAccess.READ) |
| 74 | current_script = JSON.parse_string(file.get_as_text()) |
| 75 | current_line_index = 0 |
| 76 | display_next_line() |
| 77 | |
| 78 | func display_next_line() -> void: |
| 79 | if current_line_index >= current_script["lines"].size(): |
| 80 | return |
| 81 | |
| 82 | var line_data = current_script["lines"][current_line_index] |
| 83 | |
| 84 | if line_data.has("choice"): |
| 85 | present_choices(line_data["choice"]) |
| 86 | else: |
| 87 | CharacterManager.show_character(line_data.get("character |