Dialogue System Setup
A step-by-step lesson for setting up a working dialogue system with the Dialogue Editor, UI components, and runtime playback.
Dialogue System Setup — Tutorial
This lesson walks through setting up a complete dialogue system in a GS_Play project: creating a dialogue database, authoring a branching conversation, wiring up the runtime components, and displaying dialogue in-game with a typewriter effect.
What You Will Build
By the end of this lesson you will have:
- A dialogue database with multiple sequences
- Branching dialogue with player choices
- Performer definitions for your characters
- Runtime entities with the sequencer, manager, and UI bridge components
- A working in-game dialogue display with typewriter text reveal
Prerequisites
- A GS_Play project with GS_Core and GS_Cinematics gems enabled
- Familiarity with the O3DE Editor (placing entities, adding components)
- Basic understanding of prefabs and spawning
Pages
- Create the Database
- Author a Conversation
- Wire Up the Runtime
- Display Dialogue In-Game
- Add Player Choices
- Conditions and Effects
Overview
The GS_Cinematics dialogue system has three layers:
- Editor — The Dialogue Editor where you visually author conversations as node graphs
- Runtime — The DialogueSequencerComponent that executes the graph at runtime
- UI — DialogueUIComponent and SelectionUIComponent that display text and choices to the player
This tutorial connects all three layers into a working pipeline.
1 - Step 1: Create the Database
Create a dialogue database and define performers.
Step 1 — Create the Database
Open the Dialogue Editor
From the O3DE Editor menu bar, go to GS Tools > Dialogue Editor. The editor opens with three page tabs at the top: Sequences, Performers, and System.
Create a New Database
- Go to File > New
- Choose a save location in your project’s assets folder (e.g.,
Assets/Dialogue/) - Name the file (e.g.,
town_npcs.dialoguedatabase) - The editor opens with an empty database
Switch to the Performers page by clicking the tab at the top.
Performers represent the characters who speak in your dialogues. Add one performer for each character:
- Click Add Performer
- Set the Name — this is the identifier you will reference in Text nodes (e.g.,
"Merchant", "Guard") - Optionally configure:
- Portrait — Reference to a UI image asset shown during dialogue
- Voice — Audio configuration for this character’s voice
Add at least two performers for this tutorial (e.g., "Player" and "Merchant").
Create Your First Sequence
Switch back to the Sequences page.
- In the Sequence Sidebar (left dock), click Add
- Name the sequence (e.g.,
"MerchantGreeting") - The sequence opens as a graph tab with a single Start node
Your database now has one empty sequence ready for authoring. Save the database with File > Save (Ctrl+S).
What You Have So Far
town_npcs.dialoguedatabase
├── Performers: Player, Merchant
└── Sequences: MerchantGreeting (empty)
Next: Author a Conversation
2 - Step 2: Author a Conversation
Build a simple linear dialogue sequence using Text and End nodes.
Step 2 — Author a Conversation
Build a Linear Sequence
With the MerchantGreeting sequence open, you have a Start node on the canvas. Now add dialogue nodes:
- From the Node Palette (right dock), drag a Text node onto the canvas
- Connect the Start node’s FlowOut slot to the Text node’s FlowIn slot by clicking and dragging between the slots
- Select the Text node and set its properties in the Inspector:
- Speaker:
"Merchant" (matches your performer name) - Text:
"Welcome to my shop! Looking for something special?"
Add More Lines
Repeat the process to add a second Text node for the player’s response:
- Drag another Text node onto the canvas
- Connect the first Text node’s FlowOut to this new node’s FlowIn
- Set properties:
- Speaker:
"Player" - Text:
"Just browsing, thanks."
End the Sequence
- Drag an End node from the palette
- Connect the last Text node’s FlowOut to the End node’s FlowIn
Your sequence now reads:
Start → [Merchant: "Welcome to my shop!"] → [Player: "Just browsing."] → End
Test the Flow
The node footers preview each line of dialogue, making it easy to read through the conversation visually on the canvas. Verify the flow makes sense by following the connections from Start to End.
Save the database (Ctrl+S).
Tips
- Undo/Redo: Ctrl+Z / Ctrl+Y work on all graph operations
- Node selection: Click a node to see its full properties in the Inspector
- Moving nodes: Drag nodes to rearrange the layout for readability
- Copy/Paste: Select nodes and use Ctrl+C / Ctrl+V to duplicate sections
Next: Wire Up the Runtime
3 - Step 3: Wire Up the Runtime
Place the runtime components needed to play dialogue sequences in-game.
Step 3 — Wire Up the Runtime
The Dialogue Editor is for authoring. To play dialogue at runtime, you need three components on entities in your level.
The Dialogue Manager
The Dialogue Manager is a GS_Play manager that owns the active dialogue database and provides the top-level API.
- Your Game Manager prefab should already spawn a GS_DialogueManager (it is part of the GS_Cinematics manager set)
- If not, create a manager entity and add the
GS_DialogueManagerComponent - In the component properties, set the Dialogue Database field to your
.dialoguedatabase asset
The manager provides the entry point API: StartDialogueSequenceByName("MerchantGreeting").
The Dialogue Sequencer
The sequencer is the component that actually executes the graph — stepping through nodes, waiting for text display, and handling player choices.
- On your NPC entity (or a dedicated dialogue entity), add a
DialogueSequencerComponent - No configuration needed — the sequencer receives commands from the manager
The Dialogue UI Bridge
The UI Bridge connects the sequencer to your UI display components. It routes dialogue text to the correct UI panel and relays player choices back.
- On the same entity as the sequencer (or a shared UI entity), add a
DialogueUIBridgeComponent - It will automatically discover registered UI components in the scene
Triggering Dialogue
To start dialogue from gameplay code or ScriptCanvas:
// C++ via EBus
DialogueManagerRequestBus::Broadcast(
&DialogueManagerRequests::StartDialogueSequenceByName,
"MerchantGreeting"
);
Or connect it to an interaction trigger — when the player interacts with the merchant entity, fire StartDialogueSequenceByName.
Component Summary
| Component | Entity | Purpose |
|---|
GS_DialogueManagerComponent | Manager entity | Owns database, provides start/stop API |
DialogueSequencerComponent | NPC or dialogue entity | Executes the graph step by step |
DialogueUIBridgeComponent | Same or shared entity | Routes text/choices between sequencer and UI |
Next: Display Dialogue In-Game
4 - Step 4: Display Dialogue In-Game
Set up dialogue UI components for text display and typewriter effect.
Step 4 — Display Dialogue In-Game
Dialogue UI Component
The DialogueUIComponent handles displaying dialogue text on screen. It receives text from the UI Bridge and shows it in a UI element.
- Create a UI canvas with a text panel for dialogue display (speaker name label + dialogue text area)
- On the UI entity, add a
DialogueUIComponent - Register the UI entity with the bridge by calling
RegisterDialogueUI(panelType, entityId) or by placing it where the bridge can discover it
When a Text node executes, the sequencer sends the speaker name and dialogue text through the bridge to the UI component, which updates the display.
Typewriter Effect
The TypewriterComponent reveals text character by character for a classic RPG dialogue feel:
- On the same entity as the DialogueUIComponent, add a
TypewriterComponent - Set the Default Speed — letters per second (e.g., 30 for moderate speed)
- The typewriter automatically hooks into the dialogue display
When text arrives, the typewriter reveals it gradually. The player can press a button to call ForceComplete() for instant reveal.
World-Space Dialogue (Speech Bubbles)
For dialogue that appears above characters in the 3D world:
- Use
WorldDialogueUIComponent instead of DialogueUIComponent - Configure a spawnable prefab for the speech bubble UI
- The component tracks the speaking entity’s position and places the UI above them
Flow
Sequencer executes Text node
→ UIBridge.RunDialogue(text, speakerName)
→ DialogueUIComponent.DoDialogue(text, performerData)
→ TypewriterComponent.StartTypewriter(text)
→ Text reveals character by character
→ Player presses button → ForceComplete()
→ Sequencer advances to next node
Next: Add Player Choices
5 - Step 5: Add Player Choices
Add branching dialogue with Selection nodes and choice UI.
Step 5 — Add Player Choices
Add a Selection Node
Go back to the Dialogue Editor and open your MerchantGreeting sequence.
- Delete the connection between the merchant’s greeting and the player’s response
- Drag a Selection node from the palette and place it between them
- Connect the merchant’s Text node FlowOut to the Selection node’s FlowIn
Select the Selection node. In the Inspector:
- Set Question Text to
"What would you like to do?" (optional — displayed above the choices) - Add options in the Selection Options list:
- Option 1:
"Browse your wares" - Option 2:
"Tell me about the town" - Option 3:
"Goodbye"
Each option creates a dynamic FlowOut slot on the node.
Branch the Conversation
Now connect each output to different dialogue paths:
- “Browse your wares” FlowOut → New Text node (
Merchant: "Take a look around!") → End - “Tell me about the town” FlowOut → New Text node (
Merchant: "This town was founded...") → End - “Goodbye” FlowOut → New Text node (
Merchant: "Safe travels!") → End
Your graph now branches based on the player’s choice and each branch leads to a different response.
Selection UI Component
On the UI side, the DialogueUISelectionComponent displays the choices to the player:
- On a UI entity, add a
DialogueUISelectionComponent - Configure it with a button prefab for spawning choice options
- Register it with the UI Bridge
When the sequencer hits a Selection node:
Sequencer reaches Selection node
→ UIBridge.RunSelection(options)
→ DialogueUISelectionComponent.DoSelection(options, performerData)
→ Spawns choice buttons
→ Player clicks a choice
→ OnSelection(index) fires
→ Sequencer follows the chosen FlowOut
Random Branching
For variety without player choice, use a Random node instead. It picks a random output each time the sequence reaches it. Optionally configure weights to make some branches more likely.
Next: Conditions and Effects
6 - Step 6: Conditions and Effects
Gate dialogue branches with conditions and trigger game effects from dialogue.
Step 6 — Conditions and Effects
Using Variables
Declare variables in the Variable Panel to track dialogue state:
- Open the Variable Panel dock
- Click Add and create a boolean variable:
"hasVisitedMerchant" (default: false)
Conditions on Nodes
Any dialogue node can have conditions that gate whether it executes. If conditions fail, the evaluator skips that node and tries the next connection.
- Select a Text node in the inspector
- In the Conditions section, click the type picker dropdown
- Add a
Boolean_DialogueCondition - Set:
- Variable Name:
"hasVisitedMerchant" - Expected Value:
true
Now that Text node only executes if the player has visited before. You can create two branches from a single output — one with hasVisitedMerchant = true and one without conditions as a fallback.
Effects Nodes
Effects nodes trigger game actions during dialogue. They are the bridge between conversation and gameplay.
- Drag an Effects node from the palette
- Place it in the flow where you want the effect to happen
- Select it and use the type picker in the Inspector to add effect types
For example, after the merchant’s greeting, add an Effects node that sets hasVisitedMerchant = true so subsequent visits show different dialogue.
Performance nodes trigger character actions — animations, movement, posing:
- Drag a Performance node into the flow
- Add performance types via the Inspector type picker:
MoveTo_DialoguePerformance — Move a character to a positionPathTo_DialoguePerformance — Move along a path
- Enable Wait to Continue if the dialogue should pause until the performance finishes
Creating Custom Types
The polymorphic extension system makes it simple to add project-specific conditions, effects, and performances:
- Create a subclass of
DialogueCondition, DialogueEffect, or DialoguePerformance - Add
AZ_RTTI and implement Reflect() with SerializeContext and EditContext - Include and reflect it in
DialogueSequencerComponent::Reflect()
The inspector automatically discovers your new type — no registry code needed.
Complete Example
Here is a complete branching dialogue with conditions and effects:
Start
→ [Merchant greeting (no condition): "Welcome, stranger!"]
→ [Merchant greeting (hasVisitedMerchant=true): "Welcome back, friend!"]
→ Selection: "Buy" / "Sell" / "Leave"
→ "Buy" → Effects(OpenShopUI) → End
→ "Sell" → Effects(OpenSellUI) → End
→ "Leave" → [Merchant: "Come again!"] → Effects(Set hasVisitedMerchant=true) → End
Summary
You now have a complete dialogue pipeline:
- Database with performers and multiple sequences
- Visual authoring with Text, Selection, Random, Effects, and Performance nodes
- Runtime components (Manager, Sequencer, UI Bridge) executing the graphs
- UI display with typewriter text reveal and player choice buttons
- Conditions for dynamic branching based on game state
- Effects for triggering gameplay from within dialogue
For the full API reference, see the Dialogue Editor documentation.