Files
Dawn-Godot/.claude/docs/dialogue.md
T
2026-06-11 19:59:31 -05:00

3.6 KiB

Dialogue System

All authored text — NPC conversations, item pickup messages, battle narration — is written in .dialogue files and played back via DialogueManager (godot_dialogue_manager v3.10.4).

Plugin

  • Autoload: DialogueManager (registered in project.godot)
  • Plugin must be enabled in Godot → Project Settings → Plugins → Dialogue Manager
  • .dialogue files are imported as DialogueResource once the plugin is active
  • Dialogue files live in dialogue/ organised by category (npc/, item/, battle/)

DialogueAction — the Cutscene bridge

cutscene/dialogue/DialogueAction.gd is the glue between the Cutscene queue and DialogueManager. It runs a .dialogue file through VNTextbox line-by-line and returns CUTSCENE_CONTINUE when the last line is dismissed.

# Add a dialogue step to any Cutscene
cutscene.addCallable(DialogueAction.getDialogueCallable(
  load("res://dialogue/npc/test.dialogue"),
  "start",          # title to begin from
  [entity]          # extra_game_states: objects/dicts accessible in the .dialogue file
))

Movement is blocked automatically while dialogue runs because VNTextbox is open (EntityMovement._canMove() checks UI.TEXTBOX.isClosed).

Writing .dialogue files

~ title_name          # entry point / jump target

Speaker: Line of dialogue.
Another line with no speaker.

~ another_section
Speaker: Variables resolve inline: {{some_property}}.
=> END                # end this dialogue

Key syntax:

  • ~ title — section anchor; use as the title argument to DialogueAction
  • => title — jump to another section; => END ends the dialogue
  • {{variable}} — resolves a property from any autoload or extra_game_states object
  • do AUTOLOAD.method() — call a method on any autoload (e.g. do PARTY.BACKPACK.addStack(stack))
  • set AUTOLOAD.property = value — set a property
  • - Option text — response branch (indented lines handle each branch)
  • [if condition] — conditional line or response

Mutations fire automatically before the next dialogue line is returned — you do not handle them manually in GDScript.

Passing runtime data to dialogue

Use extra_game_states to expose GDScript objects to {{variable}} tokens:

class ItemDialogueState:
  var item_name:String
  var quantity:int

DialogueAction.getDialogueCallable(resource, 'start', [ItemDialogueState.new("Potato", 1)])

Then in the .dialogue file:

Obtained {{item_name}} x{{quantity}}.

NPC entities

Set these two exports on an Entity node whose interactType = CONVERSATION:

Export Purpose
dialogueResource:DialogueResource The .dialogue file to run
dialogueTitle:String Title (section) to start from (default "start")

After first enabling the plugin and reimporting, assign dialogueResource directly in the Inspector. Until then, assign it in code (see TestMap.gd for the pattern).

Dialogue files

File Used by
dialogue/npc/test.dialogue TestMap NPC (NotPlayer)
dialogue/item/pickup.dialogue ItemAction — item pickup text with {{item_name}} and {{quantity}}
dialogue/battle/narration.dialogue BattleCutsceneAction — move announcements, victory/defeat

Response branching (current limitation)

DialogueAction auto-selects the first allowed response when a line has multiple options. There is no in-game response UI yet. To add one, replace the auto-select block in DialogueAction.dialogueCallable with a call to your response menu and await its selection signal.