Skip to main content

Overview

DialogueEntry is the basic representation of a node in a dialogue tree managed by DialogueEngine. Each entry is composed of:
  1. An entry ID that uniquely identifies the entry within the dialogue tree
  2. A branch ID that uniquely identifies the branch the entry belongs to
  3. The dialogue text and possible response options OR a boolean Callable for conditional bifurcation
  4. Custom metadata for triggering events (actor name, emotional state, etc.)
DialogueEntry objects are automatically created when you call DialogueEngine.add_text_entry() or DialogueEngine.add_conditional_entry(). You typically don’t construct them directly.

Constructor

func _init(p_dialogue_entry_id: int = 0, p_dialogue_engine: DialogueEngine = null, p_target_dialogue_entry_dictionary: Dictionary = {}) -> void
This is a low-level constructor. Use DialogueEngine.add_text_entry() or DialogueEngine.add_conditional_entry() instead.
p_dialogue_entry_id
int
default:"0"
The unique ID for this entry
p_dialogue_engine
DialogueEngine
default:"null"
Reference to the parent dialogue engine
p_target_dialogue_entry_dictionary
Dictionary
default:"{}"
Internal data dictionary

Constants

GOTO_DEFAULT
int
default:"-1"
Default top-level goto value.
INVALID_CONDITION_GOTO
int
default:"-2"
Indicates an invalid condition goto.
INVALID_OPTION_GOTO
int
default:"-2"
Indicates an invalid option goto when an option is added but not configured.
INVALID_CHOSEN_OPTION
int
default:"-2"
Indicates an invalid chosen option.

Format Constants

FORMAT_NONE
int
default:"1"
Makes get_formatted_text() return the text as-is with no error.
FORMAT_FUNCTION
int
default:"2"
Makes get_formatted_text() use String.format() for formatting.
FORMAT_OPERATOR
int
default:"3"
Makes get_formatted_text() use the % operator for formatting.
FORMAT_INVALID
int
default:"4"
Makes get_formatted_text() return the text as-is with a warning.

Text Methods

set_text()

func set_text(p_dialogue_text: String) -> void
Sets the text for the dialogue entry.
p_dialogue_text
String
required
The dialogue text to display
If this entry has a condition installed, the text will be ignored unless the condition is removed.
Example:
var entry = dialogue_engine.add_text_entry()
entry.set_text("Hello, adventurer!")

get_text()

func get_text() -> String
Returns the text of the dialogue entry. Returns: The dialogue text or empty string

has_text()

func has_text() -> bool
Returns true if the dialogue entry has text. Returns: true if text is set

get_formatted_text()

func get_formatted_text() -> String
Returns the text with the given format data applied. See set_format(). Returns: The formatted text Example:
var entry = dialogue_engine.add_text_entry("Hello, {name}!")
entry.set_format({"name": "Alice"}, DialogueEntry.FORMAT_FUNCTION)
print(entry.get_formatted_text()) # "Hello, Alice!"

set_format()

func set_format(p_format_data: Variant, p_format_operation_id: int) -> void
Stores the format array or dictionary to be used in get_formatted_text().
p_format_data
Variant
required
An Array or Dictionary containing format data. Can contain Callables that will be evaluated.
p_format_operation_id
int
required
Either FORMAT_OPERATOR (use % operator) or FORMAT_FUNCTION (use String.format())
Example with String.format():
var entry = dialogue_engine.add_text_entry("You have {gold} gold and {items} items.")
entry.set_format({
    "gold": func(): return player.gold,
    "items": func(): return player.inventory.size()
}, DialogueEntry.FORMAT_FUNCTION)
Example with % operator:
var entry = dialogue_engine.add_text_entry("Health: %d/%d")
entry.set_format([player.health, player.max_health], DialogueEntry.FORMAT_OPERATOR)

get_format()

func get_format() -> Dictionary
Returns the format specified in set_format() as a Dictionary. Returns: Dictionary with keys format_data and format_operation_id, or empty dictionary

has_format()

func has_format() -> bool
Returns true if set_format() has been called previously. Returns: true if format is set

remove_format()

func remove_format() -> void
Removes the format data and format operation id.

get_evaluated_format()

func get_evaluated_format() -> Variant
Returns a copy of the format data where all the Callable getters are called and substituted with their return values. Returns: The evaluated format data

Option Methods

add_option()

func add_option(p_text: String) -> int
Adds an option to the dialogue entry and returns its option ID.
p_text
String
required
The text for this option
Returns: The option ID (0-indexed)
If this entry has a condition installed, the option will be ignored unless the condition is removed.
Example:
var entry = dialogue_engine.add_text_entry("What will you do?")
var opt1 = entry.add_option("Fight")
var opt2 = entry.add_option("Run away")

set_option_text()

func set_option_text(p_option_id: int, p_text: String) -> void
Overwrites the option text entry.
p_option_id
int
required
The option ID to modify
p_text
String
required
The new text for the option

get_option_text()

func get_option_text(p_option_id: int) -> String
Returns the option text at the specified option ID.
p_option_id
int
required
The option ID
Returns: The option text or empty string if invalid

set_option_goto_id()

func set_option_goto_id(p_option_id: int, p_goto_id: int) -> void
Sets the option goto entry ID. When the player chooses this option, the dialogue will jump to the specified entry.
p_option_id
int
required
The option ID to configure
p_goto_id
int
required
The entry ID to jump to when this option is chosen
Example:
var question = dialogue_engine.add_text_entry("Do you accept the quest?")
var opt_yes = question.add_option("Yes")
var opt_no = question.add_option("No")

var accept = dialogue_engine.add_text_entry("Great! Good luck!")
var decline = dialogue_engine.add_text_entry("Maybe next time.")

question.set_option_goto_id(opt_yes, accept.get_id())
question.set_option_goto_id(opt_no, decline.get_id())

get_option_goto_id()

func get_option_goto_id(p_option_id: int) -> int
Returns the option goto ID stored at the specified option ID.
p_option_id
int
required
The option ID
Returns: The goto ID or INVALID_OPTION_GOTO

get_option_goto_entry()

func get_option_goto_entry(p_option_id: int) -> DialogueEntry
Returns the DialogueEntry stored at the specified option ID.
p_option_id
int
required
The option ID
Returns: The target DialogueEntry or null

choose_option()

func choose_option(p_option_id: int) -> void
Sets the option ID to be processed by the next DialogueEngine.advance() call.
p_option_id
int
required
The option ID chosen by the player
Example:
func _on_option_button_pressed(entry: DialogueEntry, option_id: int) -> void:
    entry.choose_option(option_id)
    dialogue_engine.advance()

get_chosen_option()

func get_chosen_option() -> int
Returns the chosen option. If no chosen option was previously set, returns INVALID_CHOSEN_OPTION. Returns: The chosen option ID or INVALID_CHOSEN_OPTION

has_chosen_option()

func has_chosen_option() -> bool
Returns true if an option has been chosen. Returns: true if an option was chosen

remove_chosen_option()

func remove_chosen_option() -> void
Removes the chosen option.

get_option_count()

func get_option_count() -> int
Returns the number of options associated with the dialogue entry. Returns: Number of options

has_options()

func has_options() -> bool
Returns true if the entry has options. Opposite of is_options_empty(). Returns: true if options exist

has_option_id()

func has_option_id(p_option_id: int) -> bool
Returns true if the specified option ID exists.
p_option_id
int
required
The option ID to check
Returns: true if the option exists

is_options_empty()

func is_options_empty() -> bool
Returns true if the entry has no options. Opposite of has_options(). Returns: true if no options exist

clear_options()

func clear_options() -> void
Removes all the options associated with the dialogue entry.

remove_option_at()

func remove_option_at(p_option_id: int) -> void
Removes the option at the specified option ID.
p_option_id
int
required
The option ID to remove

Conditional Methods

set_condition()

func set_condition(p_callable: Callable) -> void
Attaches a condition to the entry. Useful for branching dialogues when certain conditions must be met.
p_callable
Callable
required
A callable that returns a boolean. The dialogue will branch based on the result.
This function will convert a text-based DialogueEntry to a conditional one, meaning that its goto and options will be ignored.
Example:
var condition = dialogue_engine.add_conditional_entry(func() -> bool:
    return player.level >= 10
)

var high_level = dialogue_engine.add_text_entry("You're quite powerful!")
var low_level = dialogue_engine.add_text_entry("You should train more.")

condition.set_condition_goto_ids(high_level.get_id(), low_level.get_id())

get_condition()

func get_condition() -> Callable
Returns the condition Callable. Returns: The condition or an empty Callable

has_condition()

func has_condition() -> bool
Returns true if the DialogueEntry has a condition. Returns: true if a condition exists

set_condition_goto_ids()

func set_condition_goto_ids(p_goto_id_if_true: int = INVALID_CONDITION_GOTO, p_goto_id_if_false: int = INVALID_CONDITION_GOTO) -> void
Sets the condition goto IDs for when the condition evaluates to true or false.
p_goto_id_if_true
int
default:"INVALID_CONDITION_GOTO"
Entry ID to jump to if condition returns true
p_goto_id_if_false
int
default:"INVALID_CONDITION_GOTO"
Entry ID to jump to if condition returns false

get_condition_goto_ids()

func get_condition_goto_ids() -> Dictionary
Returns the condition goto IDs. Returns: Dictionary with true and false keys mapping to entry IDs

remove_condition()

func remove_condition() -> void
Removes the condition and converts the conditional-based DialogueEntry into a text-based one unless set_condition() is called again.

Goto Methods

set_goto_id()

func set_goto_id(p_goto_id: int) -> void
Attaches a top-level goto dialogue entry which gets processed when no options are present and the dialogue entry was visited by DialogueEngine.advance().
p_goto_id
int
required
The entry ID to jump to after this entry
If the goto DialogueEntry has a different branch ID, DialogueEngine.set_branch_id() will be called automatically.
If this entry has a condition installed, the goto will be ignored unless the condition is removed.
Example:
var entry1 = dialogue_engine.add_text_entry("First line")
var entry2 = dialogue_engine.add_text_entry("Second line")
entry1.set_goto_id(entry2.get_id())

get_goto_id()

func get_goto_id() -> int
Returns the goto dialogue entry ID. Returns: The goto ID or GOTO_DEFAULT

has_goto_id()

func has_goto_id() -> bool
Returns true if the dialogue entry has a specified top-level goto. Returns: true if goto is set

remove_goto_id()

func remove_goto_id() -> void
Removes the goto ID. A default goto is calculated in DialogueEngine.advance() by default.

get_goto_entry()

func get_goto_entry() -> DialogueEntry
Returns the goto dialogue entry. Returns: The target DialogueEntry or null if invalid

Identification Methods

set_name()

func set_name(p_dialogue_entry_name: String) -> void
Sets the name of the DialogueEntry. Useful for viewing it in the debugger or finding the entry through DialogueEngine.get_entry_with_name().
p_dialogue_entry_name
String
required
The name for this entry
Example:
var boss_intro = dialogue_engine.add_text_entry("Prepare to face me!")
boss_intro.set_name("boss_introduction")

# Later...
var entry = dialogue_engine.get_entry_with_name("boss_introduction")

get_name()

func get_name() -> String
Returns the name of the dialogue entry. Returns: The entry name or empty string

has_name()

func has_name() -> bool
Returns true if the dialogue entry has a name. Returns: true if name is set

get_id()

func get_id() -> int
Returns the ID of the entry. Returns: The entry ID

get_id_as_text()

func get_id_as_text() -> String
Returns the ID of the entry as a String. Returns: The entry ID as text

set_id()

func set_id(p_id: int) -> void
Attaches the ID to the entry.
p_id
int
required
The new ID
This is part of a low-level API. This function does not directly update the ID as seen through DialogueEngine. Only use this if you know what you are doing.

Branch Methods

set_branch_id()

func set_branch_id(p_branch_id: int) -> void
Attaches the branch ID of the entry.
p_branch_id
int
required
The branch ID
Example:
var side_quest = dialogue_engine.add_text_entry("This is a side quest!")
side_quest.set_branch_id(100)

get_branch_id()

func get_branch_id() -> int
Returns the branch ID of the entry. Returns: The branch ID

get_branch_id_as_text()

func get_branch_id_as_text() -> String
Returns the branch ID of the entry as text. Returns: The branch ID as text

Metadata Methods

set_metadata()

func set_metadata(p_key: Variant, p_value: Variant) -> void
Attaches the specified metadata to the dialogue entry. Useful for storing custom data like actor names, emotions, camera angles, etc.
p_key
Variant
required
The metadata key
p_value
Variant
required
The metadata value
Example:
var entry = dialogue_engine.add_text_entry("I'm so angry!")
entry.set_metadata("actor", "Knight")
entry.set_metadata("emotion", "angry")
entry.set_metadata("voice_pitch", 1.2)

get_metadata()

func get_metadata(p_key: Variant, p_default_value: Variant = null) -> Variant
Returns the specified metadata from the dialogue entry.
p_key
Variant
required
The metadata key
p_default_value
Variant
default:"null"
Default value if key doesn’t exist
Returns: The metadata value or default value Example:
func _on_dialogue_continued(entry: DialogueEntry) -> void:
    var actor_name = entry.get_metadata("actor", "Unknown")
    var emotion = entry.get_metadata("emotion", "neutral")
    
    actor_label.text = actor_name
    portrait.set_emotion(emotion)
    text_label.text = entry.get_text()

has_metadata()

func has_metadata(p_key: Variant) -> bool
Returns true if there’s metadata available with the specified key.
p_key
Variant
required
The metadata key to check
Returns: true if the metadata exists

get_metadata_data()

func get_metadata_data() -> Dictionary
Returns a reference to the internal metadata dictionary. Returns: The metadata dictionary

set_metadata_data()

func set_metadata_data(p_metadata: Dictionary) -> void
Directly sets the internal metadata dictionary. Useful when a dialogue entry must share the same metadata with other entries.
p_metadata
Dictionary
required
The metadata dictionary

Engine Reference

set_engine()

func set_engine(p_dialogue_engine: DialogueEngine) -> void
Sets the associated dialogue engine.
p_dialogue_engine
DialogueEngine
required
The dialogue engine
This is part of a low-level API. Only use this if you know what you are doing.

get_engine()

func get_engine() -> DialogueEngine
Returns the associated dialogue engine. Returns: The parent DialogueEngine

Data Methods

set_data()

func set_data(p_data: Dictionary) -> void
Sets the associated dialogue entry data.
p_data
Dictionary
required
The entry data dictionary

get_data()

func get_data() -> Dictionary
Returns a reference to the internal dialogue entry data. Returns: The entry data dictionary

Complete Example: NPC Dialogue with Metadata

extends Node

var dialogue_engine: DialogueEngine
@onready var portrait: TextureRect = $Portrait
@onready var name_label: Label = $NameLabel
@onready var text_label: Label = $TextLabel
@onready var options_container: VBoxContainer = $OptionsContainer

func _ready() -> void:
    dialogue_engine = DialogueEngine.new()
    dialogue_engine.dialogue_continued.connect(_on_dialogue_continued)
    dialogue_engine.dialogue_finished.connect(_on_dialogue_finished)
    
    # Create a conversation with an NPC
    var greeting = dialogue_engine.add_text_entry("Welcome to my shop!")
    greeting.set_name("greeting")
    greeting.set_metadata("actor", "Shopkeeper")
    greeting.set_metadata("emotion", "happy")
    greeting.set_metadata("portrait", "res://portraits/shopkeeper_happy.png")
    
    var question = dialogue_engine.add_text_entry("What can I do for you?")
    question.set_metadata("actor", "Shopkeeper")
    question.set_metadata("emotion", "neutral")
    question.set_metadata("portrait", "res://portraits/shopkeeper_neutral.png")
    
    var opt_buy = question.add_option("I'd like to buy something")
    var opt_sell = question.add_option("I have items to sell")
    var opt_leave = question.add_option("Just browsing")
    
    var buy_response = dialogue_engine.add_text_entry("Take a look at my wares!")
    buy_response.set_metadata("actor", "Shopkeeper")
    buy_response.set_metadata("emotion", "happy")
    buy_response.set_metadata("action", "open_shop")
    
    var sell_response = dialogue_engine.add_text_entry("Show me what you've got.")
    sell_response.set_metadata("actor", "Shopkeeper")
    sell_response.set_metadata("emotion", "interested")
    sell_response.set_metadata("action", "open_sell")
    
    var leave_response = dialogue_engine.add_text_entry("Come back anytime!")
    leave_response.set_metadata("actor", "Shopkeeper")
    leave_response.set_metadata("emotion", "happy")
    
    # Set up navigation
    greeting.set_goto_id(question.get_id())
    question.set_option_goto_id(opt_buy, buy_response.get_id())
    question.set_option_goto_id(opt_sell, sell_response.get_id())
    question.set_option_goto_id(opt_leave, leave_response.get_id())
    
    # Start dialogue
    dialogue_engine.advance()

func _on_dialogue_continued(entry: DialogueEntry) -> void:
    # Update UI with entry text
    text_label.text = entry.get_text()
    
    # Update metadata-driven elements
    if entry.has_metadata("actor"):
        name_label.text = entry.get_metadata("actor")
    
    if entry.has_metadata("portrait"):
        var portrait_path = entry.get_metadata("portrait")
        portrait.texture = load(portrait_path)
    
    # Trigger custom actions
    if entry.has_metadata("action"):
        var action = entry.get_metadata("action")
        match action:
            "open_shop":
                open_shop_menu()
            "open_sell":
                open_sell_menu()
    
    # Display options or continue button
    clear_options()
    if entry.has_options():
        for i in entry.get_option_count():
            var button = Button.new()
            button.text = entry.get_option_text(i)
            button.pressed.connect(func(): _on_option_selected(entry, i))
            options_container.add_child(button)
    else:
        var button = Button.new()
        button.text = "Continue"
        button.pressed.connect(func(): dialogue_engine.advance())
        options_container.add_child(button)

func _on_option_selected(entry: DialogueEntry, option_id: int) -> void:
    entry.choose_option(option_id)
    dialogue_engine.advance()

func clear_options() -> void:
    for child in options_container.get_children():
        child.queue_free()

func _on_dialogue_finished() -> void:
    text_label.text = "[Conversation ended]"
    clear_options()

func open_shop_menu() -> void:
    # Open your shop UI
    pass

func open_sell_menu() -> void:
    # Open your sell UI
    pass

Build docs developers (and LLMs) love