SuperAPI AI Directory

godot-genre-visual-novel

Coding & development

View repository

Updated 10-15 23:23

About this skill

Genre: Visual Novel

Branching narratives, meaningful choices, and quality-of-life features define visual novels.

Core Loop

  1. Read → dialogue / narration
  2. Decide → choice moment
  3. Branch → flag or path change
  4. Consequence → immediate line variation and/or lasting flag
  5. Conclude → one of multiple endings

NEVER Do (Expert Anti-Patterns)

Narrative & Flow

  • NEVER create the "Illusion of Choice" exclusively; strictly provide Immediate Dialogue Variations or Flag Changes even if the plot converges later.
  • NEVER skip mandatory QoL features; strictly implement Auto-Play, Fast-Forward, and Backlog/History for replayability.
  • NEVER display "Walls of Text"; strictly limit dialogue boxes to 3-4 Lines max to avoid intimidating the reader.
  • NEVER hardcode dialogue text inside GDScripts; strictly store narrative scripts in External Files (JSON, CSV, or custom Resources) for iteration.
  • NEVER ignore the Rollback mechanic; strictly maintain a history stack so players can undo miss-clicks or reread missed lines.

Technical & UI

  • NEVER use plain text for emotional beats; strictly use RichTextLabel BBCode (e.g., [shake], [wave]) to add visual weight.
  • NEVER parse massive narrative files on the main thread; strictly use ResourceLoader.load_threaded_request() to prevent transition stutters.
  • NEVER use standard Strings for frequently accessed game flags; strictly use StringName (&"met_alice") for faster dictionary lookups.
  • NEVER use _process for letter-by-letter animation; strictly use a Tween on visible_ratio for smooth, frame-independent reveals.
  • NEVER neglect character Z-ordering; strictly ensure the active speaker is brought to the front for visual clarity.
  • 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.
  • NEVER use absolute pixel positioning for character sprites; strictly rely on Anchors & Percent-based Offsets for responsive scaling.
  • NEVER allow text animations to continue when the player skips; strictly set visible_ratio to 1.0 instantly on input.
  • NEVER leave orphaned character sprites; strictly use queue_free() when actors exit the stage to prevent memory leaks.
  • NEVER mutate flags before snapshotting rollback state — always push history, then apply the choice.

🛠 Expert Components (scripts/)

MANDATORY before implementing undo / branching / presentation:

  1. vn_rollback_manager.gd — history stack (flags/backgrounds/index)
  2. story_manager.gd — flag-aware dialog orchestration
  3. dialogue_ui.gd — typewriter + choice UI
  4. visual_novel_patterns.gd — BBCode, choice filtering, sprite layering

Catalog (deduped)

  • story_manager.gd - Flag-aware dialog orchestrator with branching logic and character state persistence.
  • dialogue_ui.gd - Presentation layer: typewriter tweens (visible_ratio) and choice-window generation.
  • vn_rollback_manager.gd - History stack for state rollback (flags/backgrounds/index).
  • visual_novel_patterns.gd - Reusable BBCode effects, choice filtering by flags, sprite layering.

Decision Tree: Script Storage vs Plugin

Approach When to choose Notes
JSON / CSV scripts Writers edit outside Godot; rapid iteration Load via FileAccess or threaded ResourceLoader; validate schema in StoryManager
Custom Resource dialogue trees Designer Inspector editing, typed fields Peer godot-resource-data-patterns; MANDATORY story_manager.gd
Dialogic (plugin) Full VN suite (timelines, characters, themes) with editor tooling Prefer when shipping a large route graph fast; still keep rollback + flag discipline. Skip building a second StoryManager if Dialogic already owns timelines
Build lightweight custom Tiny kinetic novel / learning project Use scripts in this skill; do not re-stub StoryManager inline

Do not paste incomplete JSON StoryManager demos — implement from MANDATORY story_manager.gd.


Golden Path (order matters)

  1. Snapshot before mutate — On every advance/choice, MANDATORY vn_rollback_manager.gd pushes {line_index, flags, background, music} before flag writes.
  2. Typewriter + skip — dialogue_ui.gd: Tween visible_ratio 0→1; on skip/advance input set visible_ratio = 1.0 and kill the tween.
  3. Choice filter by flags — Present only options whose requires StringName flags pass; apply choice → mutate flags → jump label (visual_novel_patterns.gd + story_manager.gd).
  4. Speaker focus — move_to_front() on Control actors (not z_index alone) + dim inactive.
  5. Heavy CG/BG — ResourceLoader.load_threaded_request for backgrounds; never sync-parse huge scripts on the main thread.
# Choice handler shape (flags after snapshot)
func make_choice(choice_id: StringName) -> void:
    rollback_manager.push_snapshot()  # BEFORE mutate
    match choice_id:
        &"be_nice":
            flags[&"relationship_alice"] = int(flags.get(&"relationship_alice", 0)) + 1
            story_manager.jump_to_label(&"alice_happy")
        &"be_mean":
            flags[&"relationship_alice"] = int(flags.get(&"relationship_alice", 0)) - 1
            story_manager.jump_to_label(&"alice_sad")

Common Pitfalls

  1. Walls of text — Cap dialogue to 3–4 lines.
  2. Illusion of choice — Always vary lines or flags even on converging plots.
  3. Missing QoL — Auto / Skip / Backlog / Save are mandatory genre features.
  4. Broken rollback — Mutating flags before snapshot makes undo lie.

Deep recipes (on demand)

Topic Reference / script
Story driver & typewriter UI architecture-overview.md
Branching / rollback / focus key-mechanics.md
RichText / async loads godot-tips.md

Reference

Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.

Official Documentation

  • BBCode in RichTextLabel — shake/wave BBCode and append_text for emotional dialogue without plain Label walls.
  • Size and anchors — percent offsets and anchors so character sprites and dialogue boxes scale across resolutions.
  • GUI containers — VBox/HBox choice rows and dialogue chrome instead of absolute pixel layouts.
  • Background loading — ResourceLoader.load_threaded_request so heavy CG/background swaps never hitch the typewriter.
  • Saving games — FileAccess patterns for flags, history stacks, and multi-slot VN saves.
  • Resources — typed dialogue/choice Resources as an alternative to brittle hardcoded JSON strings.
  • Internationalizing games — tr() / CSV keys so script lines stay localization-ready.
  • Audio streams — BGM crossfades and optional voice lines tied to line advances.
  • Using InputEvent — skip/advance/ui_accept handling that finishes visible_ratio instantly.
  • Singletons (Autoload) — persistent flag/history owners across chapter scene changes.
  • Signals — line_advanced / options_presented wiring between StoryManager and DialogueUI.
  • Tween — tween_property on RichTextLabel.visible_ratio for frame-independent typewriter reveals.

Related Skills

Prerequisites

Complements

Downstream / consumers

Master

  • godot-master — library router and mirrored module entry for cross-skill discovery.