Skip to main content
This guide will walk you through creating a simple linear dialogue sequence, the foundation of any dialogue system.

Overview

A simple dialogue consists of a sequence of text entries that play one after another. The Dialogue Engine handles the flow automatically, and you control when to advance to the next entry.

Creating Your First Dialogue

1

Extend DialogueEngine

Create a new GDScript file that extends DialogueEngine:
extends DialogueEngine

func _setup() -> void:
    add_text_entry("Hey...")
    add_text_entry("[i]Have [i][b]you[/b][/i] seen the code for this sample?[/i]")
    add_text_entry("[rainbow freq=1.0 sat=0.4 val=0.8]It's beautiful![/rainbow]")
    add_text_entry("[i][shake rate=20.0 level=5 connected=1]You won't believe it![/shake][/i]")
    add_text_entry("[code][i]Press <Enter> or <Space> to exit.[/i][/code]")
The _setup() function is called automatically when the DialogueEngine is instantiated. This is where you define your dialogue structure.
2

Connect to Signals

Create a UI script that listens to the dialogue events:
extends VBoxContainer

@export var dialogue_gdscript: GDScript = null
var dialogue_engine: DialogueEngine = null

func _ready() -> void:
    dialogue_engine = dialogue_gdscript.new()
    dialogue_engine.dialogue_started.connect(__on_dialogue_started)
    dialogue_engine.dialogue_continued.connect(__on_dialogue_continued)
    dialogue_engine.dialogue_finished.connect(__on_dialogue_finished)

func __on_dialogue_started() -> void:
    print("Dialogue Started!")

func __on_dialogue_continued(p_dialogue_entry: DialogueEntry) -> void:
    var label: RichTextLabel = RichTextLabel.new()
    label.set_use_bbcode(true)
    label.set_fit_content(true)
    label.set_text("  > " + p_dialogue_entry.get_text())
    add_child(label)

func __on_dialogue_finished() -> void:
    print("Dialogue Finished!")
The dialogue_continued signal is emitted every time a text entry is visited. This is where you update your UI to display the dialogue text.
3

Advance the Dialogue

Call advance() to move to the next dialogue entry:
func _input(p_input_event: InputEvent) -> void:
    if p_input_event.is_action_pressed(&"ui_accept"):
        dialogue_engine.advance()
Each call to advance() will emit the dialogue_continued signal with the next entry, or dialogue_finished when the dialogue ends.

BBCode Support

Dialogue text supports Godot’s RichTextLabel BBCode formatting:
add_text_entry("[b]Bold text[/b]")
add_text_entry("[i]Italic text[/i]")
add_text_entry("[u]Underlined text[/u]")

Key Signals

The DialogueEngine provides three essential signals for simple dialogues:
SignalWhen EmittedUse Case
dialogue_startedWhen the first entry is readInitialize UI, play sounds
dialogue_continued(DialogueEntry)For each text entry visitedDisplay dialogue text
dialogue_finishedWhen dialogue completesClean up, transition scenes

Complete Example

Here’s a full working example:
extends DialogueEngine

func _setup() -> void:
    add_text_entry("Hey...")
    add_text_entry("[i]Have [i][b]you[/b][/i] seen the code for this sample?[/i]")
    add_text_entry("[rainbow freq=1.0 sat=0.4 val=0.8]It's beautiful![/rainbow]")
    add_text_entry("[i][shake rate=20.0 level=5 connected=1]You won't believe it![/shake][/i]")
    add_text_entry("[code][i]Press <Enter> or <Space> to exit.[/i][/code]")
You can call dialogue_engine.advance() at any time - the engine will automatically loop back to the beginning when it reaches the end.

Next Steps

Build docs developers (and LLMs) love