Table of Contents
The Dialogue Tree extension
I would rather see the Dialogue Tree example! Please take me there now.
The Dialogue Tree extension can be used to quickly create a dynamic dialogue tree behaviour. It comes with actions, conditions and expressions that make it extremely easy to set such a system with text scrolling, animated avatars and conditional dialogues. The example demo project does that in only 16 events.
If you want to make a game that is heavy on the story - be it an RPG, a Visual Novel or something else altogether, this extension will help you get there very fast and let you focus on your story.
GDevelop not only provides the extension but it also gets bundled with a popular story editor called YARN to author the data the extension uses.
Yarn has been battle-tested on a number of commercial and indie games. If you come from Ren'Py, RPG Maker, AGS or some other engine focused on story-heavy games, you will feel right at home with GDevelop. Just keep reading ;)
-
Getting started
Yarn uses a special JSON file format to store its dialogue data. To create or edit an existing yarn JSON file, you need to first add an action to the event sheet in GD that requires it. That action is called “Load dialogue data from JSON file”. Under the resource dropdown - regardless if you have any JSON resources yet - you will find a little brush button, which will let you open yarn and create/edit one.
Yarn - the anatomy of interactive story syntax
The Dialogue Tree extension is built on top of a javascript library called bondagejs. Yarn and that library follow a syntax that is similar to twine. It has a very easy to learn, but also very powerful syntax which can be used to create complex story events based on user choices or other events the user has visited.
Yarn Dialogue syntax is designed to be accessible to writers who have little or no programming knowledge. It makes no assumptions about how your game presents dialogue to the player, or about how the player chooses their responses.
Yarn files are built of nodes - those little square notes that are connected by arrows between them. When you have a bunch of them linked with arrows - that forms a dialogue tree. We refer to each node of that tree as a branch. You can have more than one tree in a single file and for example have the dialogues of an entire village worth of NPCs laid down in front of you, with each villager being one of the trees. To edit a node in Yarn, you just double click on it. To close and save it, just click outside of its editor area.
When you edit a node, you are writing in Yarn syntax. Writing stories in Yarn is just like writing dialogue, but also sprinkling it with behind the scenes hidden to the player instructions wrapped in special tags. These instructions can be used to drive what happens in the game. Depending on «the» [[wrapping]] tags, there are three types of data that yarn understands - these three types are called “Dialogue line types” in my extension:
1. Text line type
The text is what the user will see displayed when they reach the dialogue branch it is on. If you don't put any special wrappers of the other type around your text - it will remain ordinary text. Yarn will give you a hint when that is not the case by changing its colour.
2. <<Command>> line type
Remember the magic Yarn syntax we mentioned earlier - the words we place between the ordinary text the player reads to make things happen in the game? We call them commands. They are wrapped between « and ». Anything you place between these two symbols is a «hidden message» that the player will not see, but the Gdevelop will. These messages can be used to trigger events for you. If you are using the extension's built in scrolling logic, these commands will be triggered whenever the text scrolling has reached the «command».
Commands can also take parameters that the engine can use to decide on how to trigger something. To pass parameters to a command, just type them after the first word which is the command, using spaces like this:
«mycommand parameter0 parameter1 parameter2» and so on.
An example of that in the demo project is the way the animated avatar is changed:
«avatar ant» when the command avatar is triggered, the avatar's sprite object is set to change its animation to the word after it - CommandParameter(0) (ant)
Apart of the commands you can set up for yourself, and the ones built into the extension, yarn's parser library - bondagejs comes with a few very cool built in ones that can be used to store information and use it to conditionally show text to the user. So lets say your player visits a dialogue branch of an item once and has read it. Then having that information, the player starts a conversation with a npc.
This lets you tell Yarn that if the player has seen that item, the npc will say one thing - if not- they will say another thing. The syntax to do it is incredibly simple:
(1) «set $myYarnVariable to aValue» will tell yarn to store your value in $myYarnVariable. You can put that after the player reads that the item has been seen or taken or whatever the story requires.
(2) «if $myYarnVariable == aValue»
blah blah blah
«elseif $myYarnVariable == anotherValue»
more blah
«else»
other blah
«endif»
- will tell yarn to check «if $myYarnVariable is equal to aValue, if so, blah blah blah will be shown
- if not, it will check if the «elseif… is true, if so more blah will be shown
- if all fails, the «else» will trigger other blah to happen. The «elseif …» and «else» are optional. Don't forget to close it with the «endif»
You found a weird rock «set $hasRandomRock to true»
There is a strange well. Peering down, you can only see darkness…
«if $hasRandomRock == true»
Would you like throw the weird rock you found in the well?
[[yes do it|putRockNode]]
[[I rather not|otherNode]]
«endif»
Don't forget that you can put anything inside this «if …»…«endif» block - be it other commands or dialogue choices leading to other branches.
3. [[Option]] line type
This is the type that creates arrows between the nodes. It is what yarn uses to display to the user what choices they can make. The syntax is as follows:
[[player choice|otherNodeTitle]]
[[another choice|anotherNodeTitle]]
The text of the left side of the | is what the player will see. The text on the right side is what you use to tell yarn the title of the node that the player will be sent to if they take that choice.
You can also do
[[anotherNodeTitle]]
This will simply tell yarn to continue to that node, without any user input. Useful when nested in an if statement..
Gotchas to watch out for: If you try to do conditional options like this:
Ok kids we're gonna go with... [[Actually, I'm not sure yet...|NotSure]] <<if $robot_head_0_done == 1>> [[Frog Head|PickRobotMascot0]] <<endif>>
Yarn will send the player to “NotSure” instead of displaying this as two options, even when the if is true. The correct way to do this would be:
Ok kids we're gonna go with... <<if $robot_head_0_done == 1>> [[Actually, I'm not sure yet...|NotSure]] [[Frog Head|PickRobotMascot0]] <<else>> [[Actually, I'm not sure yet...|NotSure]] [[Bird Head|PickBirdMascot0]] <<endif>>
If you want to just send the player to another node (PickRobotMascot0) without displaying any options when the if statement is true, you can do:
Ok kids we're gonna go with... <<if $robot_head_0_done == 1>> [[Frog|PickRobotMascot0]] <<else>> [[Actually, I'm not sure yet...|NotSure]] [[Bird Head|PickBirdMascot0]] <<endif>>
Known issues:
- Using a → shortcut crashes my game - This is a known bug in bondage.js - the library that the dialogue tree extension is using to parse yarn files. See https://github.com/hylyh/bondage.js/issues/31 to check if that has been fixed. The reason it happens is that bondagejs expects you to indent any linked text with tabs, otherwise its seen as a syntax error. If you want to use the shortcut syntax, please refer to this example json file as to howto do it without crashing the parser https://github.com/hylyh/bondage.js/blob/master/tests/yarn_files/shortcuts.json
- an empty space is clipped from text that comes after «command» - this is a known bug in bondagejs https://github.com/hylyh/bondage.js/issues/61
- I encountered a problem while using Yarn to edit my dialogue - If that happens, unless you have encountered the problem when opening or saving your dialogue - it's likely a bug in Yarn, not Gdevelop.
- I encountered a problem with the styling of the text coming from the Dialogue Tree - If that happens, it's likely a bug with another extension. If you are using the BBcode extension, and for example underlined text style does not work or some combination of styles does not work, the problem more than likely lies with the pixi-multistyle-text library that it is using. It is also worth noting that pixi currently does not support text underlining style in general. So while you can see it in Yarn editor, it will not work in your game.
Setting up the event sheet in Gdevelop
The best thing to do to get started really is to open the demo project for the dialogue tree extension. From there on you can build your own functionality on top or even your own extensions. If you look at the event sheet, you will find that the entire logic fits on a single screenshot
The demo does not use the entire capability of the extension and is aiming to provide the functionality in the simplest/quickest way. The extension contains many more actions, conditions and expressions which can be used to build very customisable presentations to the player.
The basic life cycle of a dialogue
- Load the dialogue tree data at the beginning of the game or the level
- Set when a dialogue gets triggered - using the “Start Dialogue from branch…” action, and passing as a parameter the name of the node title where it will start from. That is typically the root of a tree. In my example the npc object's dialogueBranch variable is used. That makes it easy to make many npcs and just change that in their properties
- Tell the game engine how you want the dialogue data to be displayed to the player and used by the engine - for each of the three types
- Set reusable commands to be triggered by yarn - such as changing of avatars, playing of sound effects and any other game events to help tell your story.
API documentation
Actions
- Load dialogue Tree from a Json File:
Load a dialogue data object - Yarn json format, stored in a Json file. Use this command to load all the Dialogue data at the beginning of the game.
Parameters
jsonResource - The Json file that holds the Yarn Json data
- Load dialogue Tree from a Scene Variable:
Load a dialogue data object - in Yarn json format, stored in a scene variable. Use this command to load all the Dialogue data at the beginning of the game - in the case of storing it inside a scene variable instead of a yarn file.
Parameters
scenevar - Scene variable that holds the Yarn Json data
- Start dialogue from branch:
Start dialogue from branch. Use this to initiate the dialogue from a specified branch.
parameters:
Dialogue branch- The name of the branch (node) you want to start parsing from
- Stop running dialogue:
Stop the running dialogue. Use this to interrupt dialogue parsing.
- Go to the next dialogue line:
Go to the next dialogue line. Use this to advance to the next dialogue line when the player presses a button.
- Confirm selected Option:
Set the selected option as confirmed, which will validate it and go forward to the next node. Use other actions to select options (see “select next option” and “Select previous option”
- Select next Option:
Select next Option (add 1 to selected option number). Use this when the dialogue line is of type “options” and the player has pressed a button to change selected option.
- Select previous Option:
Select previous Option (subtract 1 from selected option number). Use this when the dialogue line is of type “options” and the player has pressed a button to change selected option.
- Select option by number:
Select option by number. Use this when the dialogue line is of type “options” and the player has pressed a button to change selected option.
parameters:
Option index number - the index of the option you want selected
- Scroll clipped text:
Scroll clipped text. Use this with a timer and “get clipped text” when you want to create a typewriter effect. Every time the action runs, a new character appears from the text.
- Complete clipped text scrolling:
Complete the clipped text scrolling. Use this action whenever you want to skip scrolling.
- Set dialogue state variable:
Set dialogue state variable. Use this to set a variable that the dialogue data is using.
parameters
State Variable Name- The name of the dialogue state variable you want to set
Variable Value- The value you want to assign to it
- Save dialogue state:
Save dialogue state. Use this to store the dialogue state into a variable, which can later be used for saving the game. That way player choices can become part of the game save.
parameters
Global Variable- The global GD variable that is used to keep the dialogue state of the game (player choices and other things set by yarn when the user made a choice or visited a node)
- Load dialogue state:
Load dialogue state. Use this to restore dialogue state, if you have stored in a variable before with the “Save state” action
parameters:
Global Variable- The global GD variable that is used to keep the dialogue state of the game (player choices and other things set by yarn when the user made a choice or visited a node)
Conditions
- Command is called
Check if a specific Command is called. If it is a «command withParameter», you can even get the parameter with the CommandParameter expression
Parameters
Command String - The name of the command to check for
- Dialogue line type
Check if the the current dialogue line line is one of the three existing types. Use this to set what logic is executed for each type. The three types are as follows:
- text: when displaying dialogue text
- options: when displaying options for dialogue choices.
-command: when «commands» are triggered by the dialogue data.'
Parameters
type - The dialogue line type to check for (one of the three listed above)
- Dialogue is running
Check if the dialogue is running. Use this to for things like locking the player movement while speaking with a non player character.
* Dialogue has branch
Check if the dialogue has a branch with specified name. Use this to check if a dialogue branch exists in the loaded dialogue data.
Parameters
Branch name - The branch name to check for
- Has selected option changed Check if a selected option has changed when the current dialogue line type is options. Use this to detect when the player has selected another option, so you can re-draw where the selection arrow is.
- Current dialogue branch title
Check if the current dialogue branch title is equal to a string. Use this to trigger game events when the player has visited a specific dialogue branch.
Parameters
title name -The dialogue branch title which when visited by a player will trigger this condition to be true.
- Current dialogue branch contains a tag
Check if the current dialogue branch contains a specific tag. Tags are an alternative useful way to «commands» to drive game logic with the dialogue data.
Parameters
tag name - The tag name to check for
- Branch title has been visited
Check if a branch title has been visited by the player in the past. This becomes true upon that node's visitation. Use this to trigger events in your game, based on what the player has read without the need to set and get yarn state variables.
Parameters
branch title - The branch title to check for being visited before.
- Compare dialogue state variable
Use this to trigger game events via dialogue variables. So for example when the player visits a node that triggers the setting of a yarn dialogue state variable like this «set $myDog to isSleeping» , you can use this condition with state variable condition “myDog” and equal to “isSleeping” to change the animation of the dog npc's sprite to sleeping.
Parameters
State variable - The name of the variable to check for (like myDog)
Equal to - The value of the variable to check for (isSleeping)
- Clipped text has completed scrolling
Check if the clipped text scrolling has completed. Use this to prevent the player from going to the next dialogue line before the typing effect has revealed the entire text. This is useful when you set up input with using a scrolling effect for the text.
Expressions
- ClippedLineText
Get dialogue line text clipped by the typewriter effect. Use the “Scroll clipped text” action to control the typewriter effect.
- LineText
Get the current dialogue line text without the typewriter effect (in case you are not using the scroll clipped text action)
- HorizontalOptionsList
Get the text of all available options from an Options line type as a horizontal list. You can also pass the selected option's cursor string, which by default is →“
Parameters
Options Selection Cursor- The selected option's cursor string - displayed before the text of the option
- VerticalOptionsList
Get the text of all available options from an Options line type as a vertical list. You can also pass the selected option's cursor string, which by default is →”
Parameters
Options Selection Cursor- The selected option's cursor string - displayed before the text of the option
- SelectedOptionIndex
Get the number of the currently selected option. Use this to help you render the option selection marker at the right place.
- OptionsCount
Get the number of options in an options line type
- Option
Get the text of an option from an Options line type, using the option's Number. The numbers start from 0.
Parameters
Option Index Number- the number of the option you want the text of
- BranchTitle
Get the title of the current branch of the running dialogue
- BranchTags
Get the tags of the current branch of the running dialogue as a text list
- BranchTag
Get a tag of the current branch of the running dialogue via its index
Parameters
Tag Index Number- the number of the tag
- CommandParameter
Get the parameters of a command call - «command withParameter anotherParameter». Use in combination with the command is called condition
Parameters
parameter Index Number- The index number of the parameter you want to get, where for example «command withParameter anotherParameter» to get withParameter you would use 1, anotherParameter would be 2
- CommandParametersCount
Get the number of parameters in the currently passed command
- TagParameter
Get parameter from a Tag found by the branch contains tag condition.
Parameters
parameter Index Number- the index number of the parameter you want to get. If you have a tag mytag(echo,beta), echo is 1 and beta is 2, mytag is the tag.
- VisitedBranchTitles
Get a list of all visited branches
- BranchText
Get the full raw text of the current branch
- Variable
Get dialogue state value
Parameters
Variable Name- The name of the Dialogue state variable which value you want to get
For a detailed list of ALL Conditions, Actions and Expressions that come with the extension, you can literally just open the extension.js file and read it