Creating a dialogue tree is essential for immersive storytelling in games, allowing for dynamic conversations between players and NPCs. Coherent Gameface, with its powerful UI system, offers a robust way to build and display these dialogue systems. In this tutorial, we’ll walk through how to create a dialogue tree from scratch using Gameface, helping you bring more interactive experiences into your game.
Where to find the working example
You can find the whole project source in the ${Gameface package}/Samples/uiresources/UITutorials/DialogueTree folder.
Creating our dialogue tree
The first thing we need to do is create our dialogue tree. For this example we’ll be creating a dialogue tree that has 2 to 3 options per dialogue and will be at least 5 levels deep.
Once we have that we need to present it in a format that will benefit us the most. This is why for this particular example we’ll make it into a JavaScript object in the following format
Where text is the guild master question, and responses are the possible choices that the player would have. In the responses dialogueNumber refers to the guild master question that will be shown when the response is chosen and it’s index in the array.
For this example we’ve added the dialogue tree as JavaScript array as we are mocking the interactions, but in a game it should come from the backend/game.
Setting up our dialogue UI
Before we make the logic for the dialogues we first need to set up the visual part. That would include creating our HTML and styling using the CSS.
In our HTML we have two major containers - the .npc-dialogue-container and the .player-options-container which will be inside the npc-dialogue-container
Here you can see in this HTML snippet, that we are using the first question and responses from the dialogue tree array. The reason is that we want it to be availabe when you load the sample, but in a real use-case scenario you can add the data using JavaScript.
Something else that we need to note here is that we add to the player-options an id that will be the dialogueNumber from the responses.
Once that is done we’ll simply style or UI by adding the following style.css
Selecting an option
Creating the typing effect
In many games where you have dialogues the text appears as if it was typed on screen. To mimic this we’ll create a function called writeText and add the following code
Here we return a Promise so that when the text finishes typing out, we can show the options for a response. We then set an interval and on each iteration we add a letter to the guildMaster element text content. Once all of the letters are typed out we clear the interval and resolve the promise.
We’ll also use a flag skipText, which will stop the interval and resolve the promise. This will allow us later to skip the text typing out if we want.
Creating the response options
To create the response options we’ll first set a template
where we set the id and the text.
Then we create a function to add the options
And finally we set the guild master dialogue along with the options
Adding interactions
For this example we’ll be using both the keyboard and the mouse to select a response. This is why we’ll add two event listeners - for click and for keydown
In our click event we need to check if the item that we are clicking is a response option and if the text is being typed out we want to skip it.
First we’ll create a function that handles the option selection.
Where we get the id that we’ve set to correspond to the correct dialogue index and trigger an event in our game with it.
Now in the click event handler we do the following:
We check if the clicked element is an option and then run the function we’ve created. And we also check if the interval is set. If it is we change the skipText flag to true and it will resolve the promise in the writeText function.
Now we can do the same in the keydown handler
We check if the user pressed enter, then we check if the current focused item is from the options and we select it.
Since we don’t have the ability to choose which option, we’ll also add the following logic to our keydown handler:
Here we check if the arrow up or down keys are pressed and if they are we focus on the next or previous sibling, depending on the key. If there is no sibling, meaning that the element is the first or last we just focus the last or first element so we can loop it around.
Tying everything together
We’ve added all of our logic, but even if we try to select an option nothing will happen as we haven’t “hooked it up to the game” yet. In this scenario we would listen for the "selectDialogue" event on our backend and then trigger an event from the game that will send us the correct text.
Since we don’t have a game we’ll mock that by listening for said event and getting the data from the dialogueTree array like so:
We wait for the engine object to be available, then we get the text from the dialogueTree when the event is triggered, here we need to check if the dialogueNumber is null and if it is we go back to the first text. And finally we trigger another event that will be listening on the frontend to change the text.
In conclusion
By following this guide, you’ve now learned how to create a functional dialogue tree using Coherent Gameface. With this system in place, your games can have branching conversations that enhance player immersion and choice. As you get more comfortable with Gameface, you can expand and customize your dialogue trees to meet the narrative needs of your game. Stay creative and keep exploring the possibilities Gameface brings to UI design!