Recommended resources
The freely available resources this lesson will direct you to.
Hello! Welcome back to building our JRPG engine.
In the last two lessons, we built the two fundamental pillars of a dialogue system. First, we designed the model: a flexible JSON data format for our dialogue trees. Then, we implemented the view: a DialogueUI component that can render dialogue with a typewriter effect and display choices.
Today, we'll build the bridge between them. This lesson addresses the learning outcome: Integrate the dialogue system with the event system to show text and handle choice-based branching. We are going to create the "controller" in our architecture—a DialogueManager that loads the data, drives the UI, and, most importantly, plugs into the main event system we built in Module 3. This will finally let us trigger a fully interactive conversation from a simple event command.
1. The DialogueManager: Our System's Conductor
Think of our dialogue JSON as a script and the DialogueUI as an actor. We need a director to tell the actor which lines to say and to listen for their responses. This is the role of the DialogueManager.
Its primary responsibilities are:
- Loading Dialogue: Given an ID (e.g.,
"TownGuardMeeting"), it will fetch the corresponding dialogue data from our asset manager. - State Management: It keeps track of the current node in the dialogue tree.
- UI Control: It tells the
DialogueUIwhat text and choices to display. - Input Processing: It receives the player's choice from the
DialogueUIand navigates to the next part of the conversation. - Event System Communication: It tells the main
EventInterpreterwhen the conversation is over, so the story can proceed.
This structure allows us to separate concerns cleanly: the event system only needs to know that a dialogue should happen, not how it happens.
The data structure we're navigating is essentially a directed graph, or a tree. A choice is simply a fork in the path.

2. Pausing the Event System
A crucial architectural challenge is that a dialogue is an interactive, asynchronous process. The player might take seconds or minutes to read and make choices. The EventInterpreter, which processes commands sequentially, cannot simply move to the next command while the player is in a conversation. It must pause.
Given your background in front-end development, this is analogous to making an API call with async/await in JavaScript. The EventInterpreter "awaits" the result of the dialogue before continuing its execution.
Here’s how we can architect this:
- We'll add a new command to our event system,
ShowDialogue, which takes adialogueId. - When the
EventInterpreterencounters this command, it will:
a. Callthis.dialogueManager.start(dialogueId, onCompleteCallback).
b. Set an internal flag, likethis.isPaused = true, to stop processing further commands. - The
onCompleteCallbackis a function we pass to theDialogueManager. When the dialogue ends, the manager will call this function. - The callback function will set
this.isPaused = falsein theEventInterpreterand tell it to advance to the next command.
This creates a clean, non-blocking handshake between our two major systems.
3. Implementing Choice-Based Branching
This is where the integration comes to life. A choice isn't just text; it's a link to another part of the story.
Here's the flow:
- The
DialogueManagertells theDialogueUIto display a set of choices from the current dialogue node. - The player uses the arrow keys and confirm button to make a selection. The
DialogueUIhandles rendering the cursor and detecting the final choice. - The
DialogueUInotifies theDialogueManagerof the chosen index (e.g.,onChoice(1)). - The
DialogueManagerlooks at its current dialogue data:data.choices[1]. - It retrieves the
targetID from that choice (e.g.,"GuardAngryResponse"). - It then sets its internal pointer to this new
targetID and loads the corresponding dialogue node, continuing the conversation from there.

But choices can do more than just change the text. They can change the game world itself.
4. Making Choices Matter: Conditional Logic
A powerful dialogue system connects choices to the game's state. A choice might give the player an item, set a flag that an important event has occurred, or unlock a new area.
RPG Maker provides a great visual model for how these concepts are linked. Let's see how it connects choices to game state changes using flags (called "switches") and conditional logic.
RPG Maker MV Branching Dialog Tutorial
To see a practical example of how choices can have real consequences, let's watch this tutorial from Driftwood Gaming on branching dialogue in RPG Maker MV.
Please watch from 3:39 to 7:53. Pay close attention to these three concepts: 'Show Choices' (3:39 - 5:00): This is RPG Maker's command for presenting a choice menu, equivalent to our DialogueUI displaying the choices array. 'Control Self Switch' (5:00 - 6:10): A 'Self Switch' is a flag specific to one event. Notice how it's turned 'ON' after a choice is made. This is a crucial pattern to ensure the choice is permanent and the NPC's dialogue changes on subsequent interactions. 'Conditional Branch' (6:10 - 7:53): This is the event system's IF/ELSE block. It checks the game's state (e.g., 'Does the player have the Tower Key?') to determine what happens next. This is how choices create lasting effects.
To implement this in our engine, we can expand our dialogue data format. A dialogue node could include an actions array that our DialogueManager executes when that node is reached:
"GuardGivesKey": {
"text": "Fine, take the key. But don't cause any trouble.",
"actions": [
{ "type": "giveItem", "itemId": "dungeonKey", "quantity": 1 },
{ "type": "setFlag", "flagId": "hasDungeonKey", "value": true }
],
"target": "GuardIdle"
}
When the DialogueManager processes the GuardGivesKey node, it would first execute these actions (calling methods on the player's inventory and the game's flag manager) and then display the text. This elegantly integrates dialogue flow with game state modification.
5. Common Narrative Structures in JRPGs
Now that we know how to implement branching, let's briefly discuss the narrative design patterns behind it. The structure of your choices dramatically affects the player's experience and the complexity of your game.
Most classic JRPGs don't have wildly branching stories that lead to completely different endings based on minor conversations. Instead, they use a pattern known as Branch and Bottleneck.
Standard Patterns in Choice-Based Games
The article 'Standard Patterns in Choice-Based Games' from Heterogeneous Tasks offers an excellent high-level taxonomy of narrative structures. It helps us put a name to the design patterns we intuitively recognize in games.
Please read the section on 'Branch and Bottleneck'. This is the quintessential structure for JRPGs. The key idea is that the story allows for small deviations and player expression (the branches), but it always guides the player back to key plot points (the bottlenecks). This keeps the main narrative focused while still making choices feel meaningful in the short term.
This pattern is a pragmatic compromise. It gives the player a sense of agency without forcing the developers to create dozens of parallel storylines. A choice might determine whether you get a Potion or an Ether, or which NPC gives you the next piece of information, but ultimately, everyone arrives at the next town to continue the main quest.
6. Validating Our Data-Driven Architecture
Our approach—defining dialogue in a separate data file (JSON) and using an engine to interpret it—is a standard, robust industry practice. It separates content creation from programming, which is vital for larger projects. This Stack Overflow discussion confirms the validity of our architecture.
RPG dialogue engine / structure
It's always good to know that the path we're on aligns with established software engineering practices. This Stack Overflow discussion features various developers sharing their solutions for this exact problem.
Quickly read through a few of the top-voted answers. You'll notice familiar ideas: Embedding conditions in the data: The first answer shows an XML example with a condition attribute, just like our conditions array. Using scripts or commands: Another answer shows pseudocode where game state (hero.inventory) is checked. Our event system and flag manager provide this functionality. Using JSON: One answer explicitly mentions moving from XML to JSON for dialogue trees, confirming our choice of data format.
Test your understanding!
In the Branch and Bottleneck pattern, what is the primary role of the "bottleneck"? And why is this pattern so common in story-driven JRPGs?
Show answer
The "bottleneck" is a key event or point in the story that all players must experience, regardless of the choices they made in the preceding "branch." It serves to merge the different short-term narrative paths back into the main, central plotline.
This pattern is common in JRPGs because it allows developers to maintain a strong, cohesive central narrative (which is a hallmark of the genre) while still providing moments of player agency and personalization. It prevents the story from becoming unmanageably complex and ensures that crucial plot developments are seen by everyone, making it much easier to design and write a long-form game.
Conclusion
We have now fully integrated our dialogue system! We created a DialogueManager that acts as the central controller, bridging our data model (JSON) and our view (DialogueUI). We've engineered a clean way for it to interact with the EventInterpreter by pausing and resuming execution, and we've established how choices can not only navigate conversations but also alter the game's state through flags and items.
Key Takeaways:
- The
DialogueManageris a controller that orchestrates the flow of a conversation, interpreting dialogue data and controlling the UI. - Integrating with the event system requires an asynchronous hand-off, where the
EventInterpreterpauses until theDialogueManagersignals completion. - Meaningful choices are implemented by having dialogue nodes trigger actions (like
setFlagorgiveItem) that modify the global game state. - The Branch and Bottleneck is the dominant narrative design pattern for JRPGs, balancing player agency with a strong central plot.
Preview of the next lesson:
Now that we have a robust system for handling text and choices, we can make our events even more dynamic. In the next lesson, "Implement event commands for controlling character and camera movement to create simple cutscenes," we'll expand our event command library. This will allow us to script sequences where characters walk to specific points, turn to face each other, and have conversations, laying the foundation for cinematic cutscenes.