Branching allows you to create multiple dialogue paths that diverge and converge based on your game’s logic. Dialogue Engine uses branch IDs to organize entries into separate branches, and gotos to jump between them.
Searches for the next entry with the same branch ID as the current branch
Continues reading entries in that branch until a goto changes the branch
# The engine maintains a branch ID needlevar current_branch = dialogue_engine.get_branch_id()# You can also set it manually (though usually handled automatically)dialogue_engine.set_branch_id(FRIENDLY_PATH)
Top-level gotos jump to a specific entry after the current one is processed:
var first_entry = add_text_entry("This is the first entry.")var skip_entry = add_text_entry("This will be skipped!")var target_entry = add_text_entry("We jumped here directly!")# Jump from first_entry to target_entry, skipping skip_entryfirst_entry.set_goto_id(target_entry.get_id())
Here’s an example of skipping dialogue within the same branch:
extends DialogueEnginefunc _setup() -> void: var first_entry = add_text_entry("This is an example of...") add_text_entry("This text will be shown on the debugger but not in the dialogue") var first_entry_goto = add_text_entry("a skipped dialogue!") first_entry.set_goto_id(first_entry_goto.get_id()) add_text_entry("Press <Enter> or <Space> to exit.")
You can jump to entries in different branches, and the engine automatically updates the branch needle:
extends DialogueEngineenum { DEFAULT_BRANCH = 0, DIFFERENT_BRANCH_ONE, DIFFERENT_BRANCH_TWO, DIFFERENT_BRANCH_THREE}func _setup() -> void: var first_entry = add_text_entry("This is an example of...", DEFAULT_BRANCH) # Jump to a different branch first_entry.set_goto_id( add_text_entry("how gotos work against different branch IDs", DIFFERENT_BRANCH_TWO).get_id() ) # Continue in the new branch add_text_entry("Once you jump to a different branch...", DIFFERENT_BRANCH_TWO) add_text_entry("the engine only considers entries in that branch.", DIFFERENT_BRANCH_TWO)
When you set a goto to an entry in a different branch, advance() automatically calls set_branch_id() to update the branch needle.
Options also use gotos to determine where the dialogue flows after a player choice:
enum { DEFAULT_TOPIC = 0, GO_BACK_TO_SLEEP = 1, KEEP_WORKING = 2,}func _setup() -> void: var entry = add_text_entry("The storm rages outside. I should...") # Option 1: Go to sleep branch var option_id_1 = entry.add_option("Go back to sleep.") var sleep_entry = add_text_entry("Sleep is for the strong.", GO_BACK_TO_SLEEP) entry.set_option_goto_id(option_id_1, sleep_entry.get_id()) # Option 2: Keep working branch var option_id_2 = entry.add_option("Get back to work.") var work_entry = add_text_entry("Let's get back to work.", KEEP_WORKING) entry.set_option_goto_id(option_id_2, work_entry.get_id()) # Merge branches back together var merge_point = add_text_entry("Some time passes...") sleep_entry.set_goto_id(merge_point.get_id()) work_entry.set_goto_id(merge_point.get_id())
Branches can converge back to a common point using gotos:
# Create divergent branchesvar friendly_ending = add_text_entry("Thanks for being kind!", FRIENDLY_PATH)var hostile_ending = add_text_entry("I'll remember this.", HOSTILE_PATH)# Create a merge pointvar common_ending = add_text_entry("The conversation ends.", MAIN_PATH)# Point both branches to the merge pointfriendly_ending.set_goto_id(common_ending.get_id())hostile_ending.set_goto_id(common_ending.get_id())
DialogueEntry provides methods to work with gotos:
var entry = add_text_entry("Sample text")# Set a gotovar target = add_text_entry("Target text")entry.set_goto_id(target.get_id())# Check if entry has a gotoif entry.has_goto_id(): var goto_id = entry.get_goto_id() var goto_entry = entry.get_goto_entry() print(goto_entry.get_text())# Remove a gotoentry.remove_goto_id()
When an entry has no explicit goto, the engine automatically advances to the next entry with the same branch ID:
# These entries flow naturally without explicit gotosadd_text_entry("First", 0)add_text_entry("Second", 0)add_text_entry("Third", 0)# The engine finds the next entry with branch ID 0 automatically
Create a central dialogue point with multiple branches:
var hub = add_text_entry("What would you like to know?")var option_1 = hub.add_option("Tell me about the town.")var town_branch = add_text_entry("This is a peaceful place...", TOWN_BRANCH)hub.set_option_goto_id(option_1, town_branch.get_id())var option_2 = hub.add_option("Tell me about the quest.")var quest_branch = add_text_entry("The quest is dangerous...", QUEST_BRANCH)hub.set_option_goto_id(option_2, quest_branch.get_id())# All branches return to the hubtown_branch.set_goto_id(hub.get_id())quest_branch.set_goto_id(hub.get_id())