-
Notifications
You must be signed in to change notification settings - Fork 3
01. Dialog Tool: Discourse
- Navigate Fast: Double-click any item in the Nodes Tree (bottom-left) to instantly center the graph view on that node.
- Node IDs: The name displayed on a node is its ID. Click the Pencil Icon next to the name to edit it.
- Localizable Nodes: Nodes that can be localized have a button with an "a文". Pressing it will enable localization in that node. The only exception is the "Localized Text" node, which is always localized.
- Delocalizing Nodes: To delocalize a node, switch to the localization mode, find your node and press the trash bin icon to delete the localization.
- Quick Spawn: Drag a connection wire and hold Ctrl while releasing it in empty space to open the Quick Node menu.
- Locale Changes: Use the Localization Dropdown (top-right) to change the text language displayed on the graph without leaving the editor.
- Localization Mode: Click the Localization Button (button next to the locale dropdown) to switch views. Inside the window, you must Double-click a language to activate it and edit the node's localization. If no locale is chosen the Nodes/Phrases will be hidden/disabled.
- Debug: Double-clicking an error in the Issues Panel will jump directly to the problematic node.
The Discourse tool (Singleton: NexusForge.Discourse, Class: DialogParser) is the dedicated component within Nexus Forge for creating, organizing, and managing all your game's dialogue and conversational flow.
The primary purpose of Discourse is to produce conversations that are as dynamic and context-aware as possible. By leveraging built-in logic nodes, you can design a single dialogue path that automatically adapts to the game state—for instance, changing a single line of text if a player has completed a specific quest, without needing to duplicate or create entirely separate conversation files.
- Efficiency:: Discourse features tools to make creating and editing conversations easy.
- Clarity:: The tool has icon and color identifiers to try and make its use as straightforward as possible.
- Flexibility: Discourse will only output simple data types through its signals; This decoupled approach ensures that you have complete freedom to design your GUI, use any Godot nodes, and handle any performance constraints without being locked into a rigid scene or UI template.
Every conversation created using the Discourse tool is stored as an individual Resource (.tres) file of class EditorDiscourseDialog.
- Resource Management: The file features a custom icon, allowing for easy identification and organization of the files within your project file system.
-
Editor Integration: The plugin automatically opens a conversation file in the Discourse editor when you double-click the
.tresresource in the Godot FileSystem dock.
The Discourse tool is centered around a custom editor interface, divided into three main areas designed to maximize efficiency in dialogue creation, organization, and localization.
This panel manages all open conversation files:
- File Display: Displays the file name of each open conversation without the path or extension.
-
Tooltip: Hovering over a file name reveals the full path to the open resource (
.tres). - Switching: Single-clicking a file name instantly switches the main editor window to that conversation.
This panel provides a hierarchical view of all nodes within the current conversation:
- Node Listing: Shows all nodes added to the conversation, functioning similarly to Godot’s Scene Tree dock.
- Navigation: Double-clicking a node name in this list will automatically scroll the main GraphEdit window to center on that node.
- Organization: You can create folders within this panel and drag nodes into them. These folders are purely for organizational purposes and do not affect the conversation's logic or final output.
- Renaming/ID: Nodes can be renamed via the adjacent pencil icon. The name of the node serves as its unique user-given ID for programmatic access (e.g., starting a conversation at a specific point).
Note
When exporting not all editor nodes will included in the release build, so not all IDs will be available in the final game.
The central area is split between the GraphEdit canvas and the primary menu bar.
-
Discourse Dropdown: Contains file management and utility actions:
- Create New, Save Current, Open Dialog, Close Current Dialog.
- Check for Issues: Runs basic validation checks on the current conversation. When activated, a dedicated issues window opens at the bottom of the editor (similar to Godot’s output panel). Each issue displayed can be dismissed by clicking the adjacent X icon, and double-clicking an issue will automatically scroll the GraphEdit canvas to center the problematic node.
-
Set File Locale Group: Defines an ID (e.g.,
TownConversation) for the conversation file. This feature is key for export optimization. Any conversation files assigned the same ID will have their localization data merged into a single file resource during export. This prevents individual conversations from causing performance hiccups by requiring many small text loads, allowing developers to manage a single, large background load (e.g., all town dialogues) instead. -
Dialog ID field visible: Shows/Hides the field to set a custom ID to a dialog. This is useful if you plan to patch/mod the dialogs in the future as you can edit a dialog using
NexusForge.Discourse.edit_dialog() - Settings: Options to change the Discourse Default Language.
- Create Dropdown: This is the primary point for adding new nodes, categorized by function (e.g., Logic, Dialogue, Events).
- Quick Buttons: Includes dedicated buttons for Save Dialog and Open Dialog.
- GraphEdit Buttons: Several standard GraphEdit controls are placed here to keep the canvas clutter-free.
- Current Localization Dropdown: Allows you to quickly switch the language being displayed in all localizable nodes on the GraphEdit. This lets you work on translations without leaving the graph view.
- Localization Window Button: Toggles the editor to the specialized Localization Window for bulk editing and detailed translation work.
This specialized interface is designed for efficient localization and phrase management, replacing the GraphEdit view temporarily.
- Top-Left (Locales): Lists all active locales for the conversation. Double-clicking a locale switches the Localization Window view to that language. The currently active language is displayed below (e.g., "Current locale: United States of America's English").
- Bottom-Left (Localizable Nodes): Lists every node in the conversation that contains localizable text. Double-clicking a node here loads it into the central editor panel for translation in the currently selected locale.
The layout of the center area changes based on the node type being edited:
| Node Type | Editor View |
|---|---|
| Text | Displays the Original Text (in the default language) above, and the editable field for the Selected Language Text below. |
| Options | A three-column table showing the Choice Index, the Default Language Text, and the editable field for the Selected Language Text. |
This panel is where global, reusable format keys are defined, accessible in dialogue via the {&KEY} syntax.
-
Creation: Use the "Dialog Bubble and Green +" icon to define a new key (e.g.,
GREETING) and its default text (e.g.,"Hello {$player/name}"). - Case Editing: Click the pencil icon next to the phrase text to enter the advanced Case Definition view.
-
Case Definition View:
-
Top: Displays the key being edited (
GREETING) and a save button to exit. -
Dropdown: Defines the format field you are creating cases for (e.g.,
{$player/name}). - Default Case: The text used when none of the custom cases match the provided data.
- Custom Cases: Define specific matches (left field) and the replacement text (right field).
-
Advanced Use: Case text can utilize other format keys (e.g.,
{$player/name} level {$player/level}), allowing sophisticated, nested string substitution and context passing.
-
Top: Displays the key being edited (
- Returning: Use the "<" symbol button (top right of the Localization Window) to return to the main GraphEdit view.
The canvas uses standard GraphEdit functionality with several key workflow enhancements:
-
Connections and Ports (Visual Cues): Each node input and output port is designed for maximum clarity:
- Flow Ports: The main conversational flow is indicated by Green connectors, which feature a triangle pointing right to signify the directional progression of the dialogue.
- Data Ports: All other data ports are color-coded based on the data type (e.g., string, integer, boolean) and include a small icon representing the expected data type. This helps ensure quick, accurate connections.
- Quick Connection Spawning: When dragging a connection cable from an output port, hold Ctrl and release the mouse button (connecting to nothing) to open a popup menu. Selecting a compatible node type here will instantly spawn the new node and connect it.
-
Frames (Node Groups): Frames can be created via the Create menu and act as visual groups. Moving a frame moves all nodes inside it, and frames automatically resize.
- Controls: Buttons for changing the frame's tint and removing the frame.
- Title: Double-clicking the top-center area of the frame allows for a custom title.
-
Duplication and Copy/Paste:
- Copying/Duplicating a node preserves its connections to other copied/duplicated nodes.
- Nodes duplicated from within a frame will spawn inside the same frame, which will resize automatically.
- Spawning Location: Pasted or newly created nodes appear at the center of the GraphEdit. Duplicated nodes appear slightly below and to the right of their originals.
These nodes are the fundamental building blocks for text display, player choice, and conversation setup.
| Node Name | Purpose | Key Fields / Settings | Connections & Inputs | Outputs / Functionality |
|---|---|---|---|---|
| Entry | Defines the required starting point of the flow. | None | None | Single Flow Output: Connects to the first node in the conversation. |
| Dialog | Primary text display node. Generates string data and signals for the GUI. |
Dialog Box: Text field supporting advanced formatting ({$...}, {!...}, {&...}), {?...}).Character ID: String ID for the speaker. Persistence: Boolean flag to signal the GUI to keep the box visible. |
Flow Input: From previous node. Character Input: Connects to Character Setting.Dialog Input (Settings): Connects to Dialog Setting.Dialog Input (Data): Connects to Localized Text or logic for dynamic text. |
Flow Output: Continues flow. Dialog End: Exiting without connection triggers "Dialog End" signal. |
| Choices | Presents multiple selection options to the user. | Spinbox: Sets the number of choices (1, 2, 3...). |
Flow Input: From previous node. Settings Inputs: One input per choice to connect an Option Setting node. |
Multiple Outputs: One flow output for each defined choice. |
| End | Visual marker for a branch conclusion. | None | Flow Input: From previous node. | None (Purely visual). |
Tip
If you connect a dialog node and do not specify a character ID, the system copies the character ID from the preceding node if it is a dialog node.
These nodes configure the parameters for Dialogue and Choice nodes.
| Node Name | Purpose | Key Fields | Inputs | Notes |
|---|---|---|---|---|
| Dialog Setting | Provides display customization data for the connected Dialog node. |
None |
Font: Font Resource. Scene: Scene resource. Text Speed: Value for seconds-per-character. |
User is responsible for parsing and using this data in their GUI via the dialog_reached signal. |
| Character Setting | Provides character display info for the connected Dialog node. |
Display Name: String to show in UI. Portrait ID: String ID for the image. |
None | User is responsible for parsing and using this data via the dialog_reached signal. |
| Option Setting | Defines runtime conditions (logic) for a single choice in a Choices node. |
None |
Show (Bool): Is the choice included in the output? Unlocked (Bool): Is the choice selectable? Locked Hint (String): Text to show if locked. |
Crucial Logic: Connect logic nodes (e.g., Variable, Comparation) here to make choices dynamic based on game state. |
These nodes allow you to direct the flow of conversation based on data, handle organization, and execute runtime events.
| Node Name | Purpose | Settings / Key Fields | Inputs | Outputs / Functionality |
|---|---|---|---|---|
| Dialog Branch | Splits flow based on a simple True/False condition. | None |
Flow Input: From previous node. Result (Bool): Boolean data input determining the path. |
True Path: Flow if result is true. False Path: Flow if result is false. |
| Match | Multi-path branching (Switch statement) for Int, Float, or String. | Type Icon: Toggle between Int, Float, String. |
Flow Input: From previous node. Value Input: Data to match against cases. |
Case Outputs: One for each defined case. Default: Output if no case matches. |
| Dialog Merge | Funnels multiple flow paths into a single output. | None | Dynamic Inputs: Ports spawn/despawn automatically. Always maintains at most one empty input port. | Single Output: Continues the conversation flow. |
| Random Select | Randomly selects a path based on weights. |
Spinbox: Number of paths. Display: Shows % chance. |
Flow Input: From previous node. Weight Input: Optional Int input to override default weight of 1. |
Multiple Outputs: One for each path defined in the spinbox. |
| Pause | Stops flow logic immediately. | None | Flow Input: From previous node. | Emits dialog_paused signal to the API. |
| Anchor / Go to | Visual shortcuts to jump flow without messy wires. | ID Field: Unique string ID for the destination. |
Anchor: Flow Output. Go to: Flow Input. |
Go to Anchor instantly jumps flow to the matching Anchor node. (Not included in export). |
| Event | Executes game logic (Variables, Methods, Signals). | None |
Flow Input: From previous node. Set Variable: Input for data to set on Blackboard. Call Method: Connects to Call Method node.Emit Signal: Connects to Signal node. |
Execution Order: 1. Set Variable 2. Call Method 3. Emit Signal Note: Not designed for asynchronous ( await) calls. |
These nodes are used primarily to access, modify, generate, and condition the data that feeds the logic and text generation in the conversation graph.
| Node Name | Purpose | Configuration & Settings | Outputs & Functionality |
|---|---|---|---|
| Value | Represents a static, immediate data value. | Type Icon: Toggle data type (Int, Float, Bool, String). | Single Data Output: Provides the hardcoded value to connected nodes. |
| Variable | Retrieves a dynamic variable from global storage. |
Variable Path: Text field to define the path (e.g., player/name).Type Icon: Select output type to ensure type safety. |
Single Data Output: Fetches the value from the NexusForge.Blackboard singleton at runtime. |
| Random Value | Generates a random value based on configurable ranges or probability. |
Type Icon: Toggle type on the output port. Settings: • Float/Int: Min and Max ranges. • Bool: "True probability" percentage. |
Single Data Output: Returns a random value of the selected type. |
| Localized Text | Provides translatable string data for other nodes. | Localization: Automatically detected and included in the Localization Window. | Single String Output: Supplies localized string text to inputs that accept string data (e.g., a Dialog Node input). |
| Node Name | Purpose | Inputs (Ports) | Outputs & Logic |
|---|---|---|---|
| Conditional Value | Provides one of two different data values based on a boolean condition. |
Condition (Bool): Determines the path. True Value: Data used if true. False Value: Data used if false. |
Single Data Output: Passes through the data from either the True or False input based on the condition. |
| Comparation | Compares two data inputs to return a boolean result. |
Input A: First value. Input B: Second value. |
Configuration: Click the operator icon between inputs to change logic (==, >, <, etc.).Single Boolean Output: Result of the comparison. |
| Type Guard | Ensures data integrity by verifying input type and providing a fallback. | Data Input: The value to check. |
Fallback Field: If input data fails the type check, the value defined here (Text/Spinbox/Checkbox) is used instead. Single Data Output: Safe, type-assured data. |
| Node Name | Purpose | Configuration & Settings | Inputs & Outputs |
|---|---|---|---|
| Signal | Prepares a signal to be emitted by an Event node. |
Select Signal: Choose from signals defined in DiscourseAPI[1]. |
Inputs: Auto-spawns ports matching signal arguments.Output: Connects only to the Emit Signal port of an Event node. |
| Call Method | Prepares a synchronous method call for an Event node. |
Select Method: Choose from methods defined in DiscourseAPI[1]. |
Inputs: Auto-spawns ports matching method arguments. Output: Connects only to the Call Method port of an Event node. |
| Call Method (Return) | Calls a method and retrieves its return value as data. |
Select Method: Choose from methods in DiscourseAPI[1] that return a value. |
Inputs: Auto-spawns ports matching method arguments. Output: Single data port matching the method's return type (or Any). |
| Event Data | Executes events/logic within the data graph (independent of flow). |
Execution Order: 1. Set Variable 2. Call Method 3. Emit Signal |
Inputs: One event input. Connecting a data source to the top-most input enables the output. Output: Passes through the data from the top input. |
| Node Name | Purpose | Configuration | Functionality |
|---|---|---|---|
| Comment | Provides space for text notes and documentation. | Text Area: Editable field for notes. | No connections. Visual aid only. |
| Resource | Represents a path to a custom resource file. | Drag-and-Drop Field: Drag a file from FileSystem to set the path. | Single Resource Output: Designed to connect to Font and Scene inputs on the Dialog Setting node. |
| Frame | A visual group container for organizing nodes. |
Title: Double-click top-center to edit. Controls: Buttons to change tint or delete the frame. |
Grouping: Moving the frame moves all contained nodes. Resizes automatically to fit contents. |
Discourse provides a powerful, multi-layered formatting system that allows dialogue text to be highly dynamic, context-aware, and fully localized.
The formatting syntax is processed in Dialog Nodes, Choices Nodes, and the Phrase Section of the Localization Window.
All dynamic formatting is contained within curly braces {} and uses a special prefix to define the source of the data:
| Prefix | Name | Source | Use Case | Example |
|---|---|---|---|---|
{$...} |
Variable Access | Retrieves data directly from the NexusForge.Blackboard singleton. |
Inserting player name, currency count, or quest progress into text. | {$player/name} |
{!...} |
Method Call | Calls a function defined within the DiscourseAPI[1] script and uses its return value. | Calculating damage, generating dynamic insults, or conditional pluralization. | {!get_weapon_name} |
{&...} |
Phrase Key | Substitutes text with a globally defined, localized Format Phrase (created in the Localization Window). | Reusing complex, localized phrases like greetings or farewells. | {&GREETING} |
{?...} |
Random choice | Picks an item from the provided list separated by |. |
Getting dynamic dialog without changing the structure | {?Hello|Hi|Hey} |
The method call syntax allows for powerful interaction with your game's underlying GDScript through the DiscourseAPI class.
-
Basic Call: You call a method defined in
DiscourseAPI[1] and the node replaces the tag with the method's return value.-
Example:
"You found {!get_item_count}"calls the functionget_item_count()and inserts the returned integer/string.
-
Example:
-
Argument Passing (Available in Nodes Only): Arguments can be passed to the method by appending them after the function name, separated by a vertical bar (
|).-
Example:
{!get_character_display_name|jhon}is equivalent to callingget_character_display_name("jhon")in code.
-
Example:
-
Nested Argument Passing: You can nest calls, using results from other variables or methods as arguments:
-
Variable as Argument:
{!get_character_display_name|$player/name}-
Result: Calls
get_character_display_name(NexusForge.Blackboard.get_variable("player", "name")).
-
Result: Calls
-
Nested Method Calls (Chaining): You can chain multiple function calls, where the inner function's result is passed to the outer function.
-
Example:
{!get_a|!get_b|!get_c}is equivalent to callingget_a(get_b(get_c())).
-
Example:
-
Variable as Argument:
Warning
While powerful, creating large stacks of nested method calls is NOT recommended. It significantly increases complexity, reduces readability, and makes debugging difficult.
Format Phrases allow you to define complex, reusable strings once and refer to them throughout your dialogue using a key.
-
Phrase Definition: Defined in the Format Phrase Section of the Localization Window. The phrase itself can contain other formatting tags (
{$...}or{!...}).-
Example Key:
GREETING/ Default Text:"Hello {$player/name}"
-
Example Key:
Important
Top-Level Parsing Rule (Critical Distinction): The formatting engine only processes the primary variable or method tags defined directly in the phrase's text. Formatting does not recurse into the output of custom case substitutions.
- If the original phrase is
"Hello {$player/name}", and the custom case for the name "Jhon" is set to:"Hello {$player/name} {$player/nickname}", the result will be:Hello Jhon {$player/nickname}. - The engine processes and substitutes the top-level
{$player/name}correctly to"Jhon", but it does not proceed to parse the resulting{$player/nickname}tag left behind in the substituted text.
-
Argument Restriction: The advanced argument passing syntax (using
|) is not available within the Phrase Section's definition field. A phrase like"Hello {!get_player_nickname|$player/name}"will attempt to call a function literally namedget_player_nickname|$player/name().
This advanced feature, accessed via the pencil icon next to a phrase's definition in the Localization Window, allows for contextual string output based on data:
-
Purpose: Ideal for handling pluralization, gender-specific text, or other conditional phrasing based on the value passed to the tag.
-
Case Definition: Allows defining a Default Case and specific Custom Cases.
-
Example: For the tag
{!potion_count}(which returns an integer):-
Custom Case 0:
"I have no potions" -
Custom Case 1:
"I have one potion" -
Default Case:
"I have {!potion_count} potions"(used for all numbers$>1$ )
-
Custom Case 0:
-
Example: For the tag
-
Result: When the dialogue runs, the engine selects the case that matches the return value of
{!potion_count}before inserting the final string.
Important
Critical Note on Type Conversion: When comparing a method's return value against the custom cases, the return value is always converted to a string before comparison.
- If a method returns an integer (e.g.,
1), it is converted to the string"1"and compared against the string custom cases. - If a method returns a float (e.g.,
$1.0$ ), it is converted to the string"1.0". Since Godot includes the decimal, this will NOT match a custom case defined as"1". This distinction must be accounted for when defining custom cases for methods that might return floating-point numbers.
Discourse utilizes an export plugin to ensure efficiency and performance in the final compiled project by separating the editor-specific data and integrating localization files seamlessly.
-
Class Substitution: The editor-time conversation resource (
EditorDiscourseDialogclass) is processed via theEditorDiscourseDialog.convert_for_release()function. -
Release-Ready Resource: This function returns a new resource of the class
DiscourseDialog. - Data Exclusion: The resulting release file will only contain the logic and structure needed to run the dialogue flow. All editor is stripped from this file.
- File Generation: The exporter creates JSON files containing all text and format phrases for the conversation. Which are then read when the dialog file is loaded.
-
File Location: These localization resources are saved by default to
res://localization/(this path is configurable in Project Settings -> NexusForge -> Localization Directory). -
Runtime Loading: When
NexusForge.Discourse.load_dialog()is called, the system automatically loads the relevant localization file (which contains the required text) along with the logic file.
When exporting, the plugin will try to assign IDs in one of the next ways (in order):
- If an ID is assigned, it'll give it that ID unless the ID is already taken or the ID is empty. In which case it'll warn the user and try the next.
- It'll create a custom ID based on the path of the file. A file on the path
res://dialogs/town/mayor.treswill be assigned the IDdialogs.town.mayor. Note that whitespaces will be converted to underscores:res://character dialogs/town/big mayor.tres→character_dialogs.town.big_mayor - If the slug ID is taken, the ID will be the MD5 hash of the full path of the file.
The Discourse tool is accessed programmatically via the NexusForge.Discourse singleton.
The singleton emits the following signals to inform your game logic about the conversation state:
| Signal Name | Arguments | When Emitted |
|---|---|---|
dialog_started |
None | Emitted when a conversation officially begins via the next_dialog() function. Not emitted if the dialogue was already loaded or running. |
dialog_finished |
None | Emitted when the conversation flow reaches its end. |
dialog_paused |
None | Emitted when the flow encounters a Pause node. |
dialog_reached |
Dictionary |
Emitted when the flow reaches a Dialog Node. |
options_reached |
Array[Dictionary] |
Emitted when the flow reaches a Choices Node. |
The dictionary argument passed by dialog_reached contains all necessary data for display, based on connected setting nodes:
{
"dialog_text": "Hello world",
"character_id": &"Narrator"
"persist": false,
"scene": "res://path/to/scene.tscn",
"font": "res://path/to/font.tres",
"speed": 0.1,
"display_name": "Mysterious Voice",
"portrait_id": "shadowy_figure",
"metadata": {"some_numbers": 1525, "hello": "World"}
}| Key | Purpose | Data type |
|---|---|---|
dialog_text |
Contains the text to be displayed. | String |
character_id |
The ID of the character the dialog comes from. | StringName |
persist |
A value representing if the textbox should remain on screen. | Bool |
scene |
A path to the scene the dialog is supposed to be displayed with. | String |
font |
A path to the font resource to use for this dialog. | String |
speed |
A value representing seconds-per-character. A value of 0.0 means dialog should appear instantly. |
Float |
display_name |
An override for what name to display. | String |
portrait_id |
An override for what portrait to display. | String |
metadata |
A dicitionary containing metadata. | Dictionary[String, Variant] |
The array argument passed by options_reached contains a list of available choices.
[
{
"unlocked": true,
"text": "Ok, I'll return later.",
"target": &"c76d7256-eded-4a8c-b501-532d23933799",
"metadata": {"color": "BLUE"}
},
{
"unlocked": false,
"text": "(Requires persuasion 15)",
"target": &"1c2200e2-08c6-466f-8074-a1295a6a8a57"
"metadata": {"color": "GREY", "selectable": false}
},
# ... more options
]| Key | Purpose | Data type |
|---|---|---|
unlocked |
Represents if the option is available to be picked (Greyed out) | Bool |
text |
Will be the text to be displayed. If unlocked is false then text will be the lock hint. |
String |
target |
The UUID of the next node this choice points to | StringName |
metadata |
Data pertinent to the choice. | Dictionary[String, Variant] |
Note
Reaching an Options Node stops the flow. Calling next_dialog() again will only re-emit options_reached. To proceed, you must:
- Read the
targetUUID from the player's chosen option. - Call
NexusForge.Discourse.set_dialog_id(uuid). - Call
NexusForge.Discourse.next_dialog()to proceed down that specific choice path.
| Name | Type | Purpose |
|---|---|---|
API |
DiscourseAPI Instance |
An instance of the underlying API class. Allows developers to change any variables or settings defined within the DiscourseAPI[1] script at runtime. |
locale |
String |
The current locale code (e.g., "en_GB") used for localization lookups. Changing this updates the localized text provided by subsequent signals. |
| Function Signature | Purpose and Usage |
|---|---|
load_dialog(path: String, starting_id: String = "") |
Loads a conversation resource (.tres) from the given path. If provided, the optional starting_id sets the initial position. The starting_id can be either the Node ID (name given in the bottom-left panel) or the Node's UUID. |
set_dialog_id(id: String) |
Manually sets the current position within the loaded conversation graph. The id can be a Node ID or a UUID. Note: If load_dialog() is called afterward, this ID will be overridden. |
next_dialog() |
Advances the conversation flow one step. Behavior: If a dialog has not started, it emits dialog_started. If the flow hits an end node, it emits dialog_finished. If called after a dialog has finished (without a subsequent set_dialog_id()), the conversation will restart from the Entry Node. |
edit_dialog(locale: String, dialog_id: String, node: String, override) |
Adds an override (if override is a string) for a specific node from the dialog ID on a specific locale. Passing null as the override argument will clear the override allowing the original dialog to be used instead. |
edit_choices(locale: String, dialog_id: String, node: String, override) |
Adds an override (if override is an array/PackedStringArray) for a specific node from the dialog ID on a specific locale. Passing null as the override argument will clear the override allowing the original choices to be used instead. |
edit_choice(locale: String, dialog: String, node: String, choice_index: int, choice: String) |
Adds an override for a specific choice of a node on a dialog from a specific locale. Unlike edit_choices() this doesn't allow to "revert" changes. Use edit_choices() to revert instead. |
For advanced users, two constants can be modified in the parser base script (addons/nexus_forge/resources/parser/discourse_parser_base.gd) to adjust core behavior:
-
RANDOM_DEFAULT_WEIGHT: Defines the base integer weight used for all options in a Random Select node when no explicit weight is provided. -
FLOAT_SNAP: Defaults to0.01. This value defines the snapping point (or cutoff) for floats generated by the Random Value node in float mode. (e.g., a snap of0.01cuts1.25698to1.25).
Discourse comes with a scene to test your dialogs, but you can use your own scene by selecting it on Project Settings → Nexus Forge → Settings → Custom Dialog Debug Scene
Important
The dialog debug scene shouldn't be your game's dialog display, as the debug scene will need custom loading logic and has debug signals available that won't exist on a release enviroment. Instead use your main dialog display as a child of a separate scene and set up the loading and connections on the parent.
Your scene can connect to the default Discourse signals (eg. dialog_reached, options_reached, ...) but other debug signals are available that could help display what is happening in the background.
| Signal | Purpose | Data |
|---|---|---|
data_set |
Emmited when an event node sets data on the Blackboard | folder: String, variable: String, data: Variant
|
method_called |
Emmited when an event node calls a method | method_string: String, arguments: Array
|
signal_emmited |
Emmited when an event node emits a signal | signal_name: String, arguments: Array
|
When Nexus Forge launches the debug scene, your scene must load the specific dialog that was selected. Nexus Forge writes a config before launching the scene so your scene can load it. Below is a snippet of code that can be used to load the dialog resource onto the singleton from your scene:
func _ready() -> void:
if not FileAccess.file_exists("user://nexus_forge/discourse_settings.cfg"):
push_error("Discourse config not found")
return
var cfg: ConfigFile = ConfigFile.new()
cfg.load("user://nexus_forge/discourse_settings.cfg")
if not cfg.has_section_key("Discourse", "active_scene"):
push_error("Discourse config lacks required key")
return
var path: String = cfg.get_value("Discourse", "active_scene", "")
if path.is_empty() or not FileAccess.file_exists(path):
push_error("File \"" + path + "\" not found")
return
if not NexusForge.Discourse.load_dialog(path):
push_error("Discourse couldn't load the dialog: " + path)- Default file location of DiscourseAPI:
res://addons/nexus_forge/resources/parser/discourse_api.gd.