ChatMapper Cookbook

Jump to:

Part 1. Introduction

1.1. An overview of scripting

1.1.1. Boolean operations

1.1.2. Variables and operations

1.1.3. Special variables

1.2. Dialogue and Group nodes

1.2.1. Conversation node

1.2.2. Dialogue nodes

1.2.3. Group nodes

1.2.4. False actions

1.3 Custom Asset Fields (CAFs)

1.3.1. Voice

1.3.2. Voice pitch/rate/volume

1.3.3. Autoplay

1.3.4. Location

1.3.5. Choice caption

1.4. Managing large dialogue trees

Part 2. The Cookbook

2.1. The "Start" node

2.1.1. Only showing the “Start” node the first time

2.2. The "Replay" node

2.3. Loops

2.4. Assigning and using variables

2.5. Using variables in dialogue

2.6. Random variables

2.7. User input

2.8. Hiding the language bar

2.9 Using icons in choices

Part 1. Introduction

The real power of ChatMapper can only be harnessed through the use of scripting. Specifically, Lua (for ChatMapper) and JavaScript (for HTML5 previews/online publishing).

Now, since we already hear some of you running for the nearest fire exit, let me say one thing: don’t be afraid! The building blocks of scripting in ChatMapper are really easy to learn. Sure you can use them creatively to do amazing things, but you will see from even the more advanced examples that it’s child’s play, nothing that requires arcane programming knowledge, so don’t you worry!

Before we begin, let’s take a look at the ChatMapper window as a whole, and name a few things.


Fig.1.1 – An overview of the ChatMapper interface.

  1. The main canvas. The nodes of a conversation will be displayed here. If you open more than one conversation, additional tabs will appear.
  2. Assets: Every actor, item, location and variable is saved under "Assets", while conversations are saved in the other tab, "Conversations". 
  3. Scripts and conditions: Most things related to scripting go in one of these two panels.
  4. Overview and properties: Overview shows an image of the whole conversation, with a handle which you can drag and drop to move quickly between areas of bigger conversations. The properties panel is unique for each thing you can click on (actors, dialogue nodes, conversations, items, locations, etc.), and contains – you guessed it – the selected object’s properties.
  5. Menus and shortcuts: pretty self explanatory.

We’ll be referring to these areas many times in this document, so you can use this image as a general reference.

As an aside, please keep in mind that while we will explain the basic functions of ChatMapper briefly, this is only intended as a refresher: We assume you have opened ChatMapper at least once, and played around a bit (even if you did nothing complex).

1.1. An overview of scripting

At the highest level, scripting in ChatMapper can be divided in two parts: "Scripts" and "Conditions".

  • Scripts are things you want to do. Assign or increment a variable, calculate something, anything active. When you reach a dialogue node, everything in the "Script Editor" tab will be executed. They are by default on the left side of the "Scripts and conditions" area of the interface.
  • Conditions, on the other hand, are evaluated before a node is displayed, and based on the result of that evaluation the node will be visualized, or not. They are by default on the right side of the "Scripts and conditions" area of the interface.


Fig.1.2 – The "Scripts" and "Conditions" panels, with some example expressions.

1.1.1. Boolean operations

There are a few things going on in the image. First of all, when the node is reached, the expression in Conditions is evaluated.

That type of expression, which is either TRUE or FALSE, is called a boolean expression. An example to understand this better would be:

"Are apples the same as oranges?"

Since apples and oranges are different, the answer is no. In boolean terms, the statement is false.

To test if two things are equal, you use the == operator, while the operator ~= means you’re testing if two things are different. So to recap,

apples == oranges → FALSE (it’s false that are apples the same as oranges)

apples ~= oranges → TRUE (it’s true that apples are different from oranges)

Let’s step things up a notch, with the example in the image.

Is 1+1 > 2?

2 is not higher than 2, so the answer is no. Therefore the expression evaluates to FALSE.

Is 1/2 < 3?

0.5 is lower than 3, so the answer is yes. Therefore the expression evaluates to TRUE. 

The or in the middle unites the two expressions, meaning that for the node to be visualized, either the first or the second expression must be true.

In programming this is called boolean logic. You can sum it up to two operators, and and or:

  • and: the condition is true only if both expressions are true. It’s false in all other cases.
  • or: the condition is true if one or both expressions are true. If they’re both false, it’s false.

Will the node in the image, then, be displayed? Yes, because the condition is an or, which means only one of the two expressions must be true (in this case, the second one).

The operators you use to evaluate these conditions are the usual mathematical ones: > (more than), >= (more than or equal to), < (less than), <= (less than or equal to), == (equal), ~= (different).

1.1.2. Variables and operations

The expression in the Scripting panel is straightforward too: it is assigning a variable called result the value of 1 + 1. From then on, whenever we access result its value will be 2.

How do you create a variable? You can do that by clicking the gear icon in the Assets pane under "Variables", and select "New User Variable", or by pressing CTRL + SHIFT + U.  You will then be able to add a name (result in the earlier example), an initial value, and if you want a description of what the variable does.

A type for the variable will automatically be selected based on the initial value:

  • Text if the field is left empty or if it contains a letter, a word or a sentence.
  • Number if the initial value is a number.
  • Boolean if the initial value given is true or false.

When the variable has been created, you can use it in scripts or conditions by using Variable["name"], where name is of course the name of the variable.

A few simple things you can do with variables:

  • Create a "counter" by incrementing a variable each time something happens (a note for programmers: there’s no ++ or — operator in Lua!)

Variable["counter"] = Variable["counter"] + 1

  • Check if two variables are the same

Variable["var1"] == Variable["var2"]

  • Use them in operations

Variable["result"] = Variable["operand 1"] + Variable["operand 2"]

1.1.3. Special variables

There are a few "specialized" variables, each referring to a certain type of asset:

  • Actor: Actor["name"]
  • Item: Item["name"]
  • Location: Location["name"]
  • Conversation: Conversation[id]
  • Dialog: Dialog[id]

Note that Conversation and Dialog use IDs as identifiers, not names. The ID of a conversation can be found in the "Conversations" tab, while the ID of a node is displayed on the upper left corner of each node


Fig.1.3 – Conversation ID and Dialog ID are circled in red

1.2. Dialogue and Group nodes

Dialogue and group nodes are the bread and butter of Chat Mapper. They are the main elements of a conversation: the first holding all information, the latter as an organizational aid. There is also a third type of node, a conversation node (the root node at the beginning of every conversation), but there’s just one for each conversation and it’s put there automatically, so you don’t really need to worry about it.


Fig.1.4 – Conversation, Dialogue and Group nodes

You can colour any node by clicking one of the 7 colored circles in the menu bar, right above the main canvas.

1.2.1. Conversation node

The conversation node displays the title of the conversation ("New Conversation" by default), and the name of the actor and conversant (in this case "New Player" and "New NPC").


Fig.1.5 – A conversation node

The green "plus" button ("New Child Dialog") will create a dialogue node, and parent it to the root.

The "chain" button ("Link to Dialog") will parent the next node you click on to this node, creating a link (an arrow) between them, going from the root to the new child node.

You can also fold the entire conversation tree by clicking the "-" button in the lower right of the node.

That’s it. See? We told you they were not complicated!

1.2.2. Dialogue nodes

Dialogue nodes contain all the important information in a conversation.


Fig.1.6 – A dialogue node

You can think of them as an interaction in the back-and-forth of a conversation. In the case above, the actor "New NPC" is saying "Hello!" to their conversant, "New Player".

Functionality-wise, dialogue nodes have an additional button, a folder with a green plus ("New Child Group"): this creates a new group node as a child.

There are a few standard parameters that are fundamental to every demo:

  • Actor: the actor who is speaking in the node. Their name will appear before the sentence, so you should make sure that the correct value is assigned to this field.
  • Menu Text: in the example image, "[f]Choice" is the menu text. this is the text that will appear on the buttons when the player is presented in a choice. Take the below image as an example: the text in this field appears, in the HTML5 preview, as the text on the two choice buttons.


Fig.1.7 – Representation of menu text in the HTML5 preview.

Usually, a single choice will be selected automatically. To force ChatMapper to visualize it, you can add [f] before the menu text.

  • Dialogue: the text that will be spoken by the character

Those are the main features of Dialogue nodes. There are also two small circles on the upper left corner of the node: the small pink one with an S indicates that the node contains a script, while the blue one with a C indicates that there is a condition.

1.2.3. Group nodes

Group nodes are mostly an organizational tool (to, you guessed it, group other nodes), but they also have an important function in conversations, that of giving an anchor for repeating choices.


Fig.1.8 – A group node

Any time you want the user to be given a list of choices until they get the right one, parenting all the children "choice" nodes to another dialogue node will make the text in the parent be spoken every time the user goes through it again. Moreover, the choices won’t appear before an additional click/tap is made by the user, even if the "dialogue" field is empty in the parent. For that reason, by inserting a group node between the dialogue parent and the choice children, you can link back the children to the group node, and no additional clicks will be required, the choices will just appear again, without a hitch.

As you can see in Fig. 8, group nodes have script and condition indicators similar to those in dialogue nodes (again, pink for scripts and pale blue for conditions).

1.2.4. False actions

The “False Action” of a dialogue node describes what happens if the condition in a certain node evaluates to false.

Fig.1.9 – The selector used to change the “False Action” setting of a dialogue node.

In the case of “Block”, the default, the node is blocked and the conversation will stop (or, in the case of multiple nodes at the same level, it will not show among the options the user can choose).

If “Passthrough” is chosen instead, the node will be “skipped” (i.e. the conversation will “pass through” that node), and will not be blocked. In the case of groups of nodes the same happens, and the node after the passthrough node will be evaluated to see whether it should appear in the list of choices or not (as the second node itself might have a condition with a passthrough False Action, and so on).

1.3 Custom Asset Fields (CAFs)

CAFs are a way to add functionality to your conversations and demos. They can be seen by going to Project → Project Settings → Custom Asset Fields. By selecting the correct asset tab (actors, items, locations, etc.) and clicking on "Add New Field", you will be able to create your very own!

CAFs can be of many different types, but the ones most frequently used will be:

  • Number: any numeric CAF will be, of course, of this type. It can be an integer, a decimal number, positive or negative.
  • Text: any CAF using the name of something, or that needs certain "keywords", will be of type text.
  • Boolean: like with the operations with the same name, CAFs that should be either true or false will be of type boolean. Default value is false.
  • Files: all collections of files (actor pictures, videos, etc.) are of this type. Assigning this type to a CAF (don’t forget the [] default value!) will make you able to add or remove files at will, by letting you browse your hard drive looking for a file and then saving its path when you select it.
  • Location: any field with this type will become a dropdown with a list of the Location assets in your current project. Very useful to change the background of conversations.

There are also a few "special" CAFs, which enable entirely new features in your demo. Their name and type must be exactly the one listed below, and the values you assign to them are very strict too!


Fig.1.10 – Before and after adding the Voice CAF to Actors, with a screenshot of the values used.

1.3.1. Voice

  • Tab: Actors
  • Title: Voice
  • Type: Text

The ResponsiveVoice voice that will be used in HTML5 previews and when publishing. All voice names (which are to be used as the value of this CAF) and their genre are listed here.

1.3.2. Voice pitch/rate/volume

  • Tab: Actors
  • Title: Voice_parameters
  • Type: Text

Some voices support three additional parameters: pitch, rate of speech, and volume. These vary from 0.5 to 1.5, and must be included as a single string formatted like follows (where VAL is of course the value given to that parameter). The default value of each parameter is 1.

{ rate: VAL, pitch: VAL, volume: VAL }

Not all parameters need to be included. If for instance the only parameters wanted are rate (1.3) and volume (0.9), the following can be used:

{ rate: 1.3, volume: 0.9 }

1.3.3. Autoplay

  • Tab: Conversations
  • Title: Autoplay
  • Type: Boolean

When this CAF is added to conversations, the conversation in which this is set as true (it must be only one, otherwise the conversation selector will be shown like always) will begin on its own, without having to choose which conversation to play. Especially useful if you want your conversation to begin from a specific point.

1.3.4. Location

  • Tab: Conversations
  • Title: location
  • Type: Location

This will make you able to assign a location to a conversation, so that the image of that location will automatically appear as the background of that conversation.

1.3.5. Choice caption

  • Tab: Dialogue Nodes
  • Title: choiceCaption
  • Type: Text

If you add text to this field in a node that has Menu Text, it will be visualized above the choice buttons when that part of the conversation is reached. This is useful if you want to add the text of a question above the list of choices, for example, to remind players what they’re deciding on.

1.4. Managing large dialogue trees

ChatMapper allows linking a node to an entirely different conversation, which allows simplifying large dialogue trees by splitting them in multiple conversations. This becomes useful around the ~200 node mark, as by loading a single part of the tree instead of the entire one, performance remains stable.

Once you have more than one conversation, you can link another conversation by right clicking on a node and choosing "Link to Conversation…" in the menu, which will allow you to jump from your current conversation to the one selected.

Fig.1.11 – The right-click menu, with the “Link to conversation” option highlighted.

It’s important to note that even when there are multiple conversations, ChatMapper will still load all the previously-opened ones before allowing any changes to be made, so it’s worth closing the unused ones.

Fig.1.12 – The close button on conversation tabs.

There are three things to keep in mind before deciding to go ahead with splitting a conversation:

1. The most important is that it is only possible to link to a different conversation, not to a node within that conversation. To clarify, consider the setup below:

Fig.1.13 – A sample conversation setup with multiple branches and an inter-node link.

It is not possible to "split" the conversation starting at #3, because it would be impossible to keep the existing link from #2 to #4 across conversations. In order to extract the conversation without breakages, the new tree must start at #1, so that all references are kept "internal" to that conversation

2. As with Windows files and folders, it’s possible to select multiple nodes by clicking on them while pressing the CTRL key. It is also possible to select a series of nodes by clicking on the first, and then clicking on the last while holding the SHIFT key. Once multiple nodes are selected, they can be copied and pasted in the new conversation with the usual CTRL+C and CTRL+V shortcuts.

3. It is not possible to select and copy/paste links to nodes, so when selecting a group of nodes to copy in a new conversation, any links in that group will need to be re-created. In this case having a backup copy of the original  conversation to use as reference is extremely valuable.

Our suggested approach to splitting a dialogue tree into multiple conversations is the following:

  1. Create a copy of the CMP as it exists, so that it can be used as a reference (or as a backup if any issues arise during the editing process).
  2. Analyze whether it would be possible and valuable to split the current conversation into multiple ones. For example, the effort required might not be worthwhile if the conversation is only edited very rarely, and always by the same person or group of people.
  3. Split the conversation(s).

Part 2. The Cookbook

What follows is a list of "recipes" for ChatMapper. Each one contains the instructions to create a certain kind of element or structure in a conversation, similar to the recipe for a certain dish!

2.1. The "Start" node

A starting point is very important for users. Consider a scenario in which you have Autoplay on for a conversation, and the user loads your demo for the first time: without an "anchor", the dialogue will begin without the user expecting it! This can be extremely damaging to the overall experience, and for that reason we suggest implementing the Start node.

The Start node is simply a dialogue node, at the beginning of a conversation (before anything is said by the actors of course, otherwise it would be kind of pointless!), that forces its menu text to display.


Fig. 2.1 – Properties panel of the Start node. Yes, it’s that easy!

As you can see from the image, to force the display of a choice you just need to add [f] at the beginning of its menu text. If you don’t, the node will be automatically selected (since it’s the only possible choice) and you won’t have a starting point.

With Autoplay and the Start node you can do all sorts of wonderful things. At LearnBrite, for instance, we often use it for setup to set all variables to the correct starting value (so that, when we link back to it at the end, variables are reset automatically), or to run some additional Javascript.

2.1.1. Only showing the “Start” node the first time

There are cases in which a user is free to start the same conversation multiple times, but it wouldn’t make sense for them to click on the avatar/bot/object that triggers the conversation and always be presented with the “Start” node.

If the start node has no dialogue or scripting that is always relevant to the conversation even on repeat plays (if that’s the case, those should be moved to a subsequent node), a condition should be set on the start node to only be displayed once (see image below), and the False Action of the start node should be set to “Passthrough” (see section on False Actions).

Fig. 2.1.1 – Adding the “Display This Node Only Once” condition

This way, the start node will be shown the first time the conversation is played, and its status as having been displayed (which is what the condition checks) will be saved. When the conversation is triggered again, the condition will fail and the node will not play, however because of the passthrough False Action the conversation will “skip” to the next node instead of exiting altogether.

2.2. The "Replay" node

Like the Start node, the Replay node is very useful, and we include it in almost every demo we create.

The concept is fairly similar: it’s a single node, used as both an anchor (for the player) and to execute a script behind the scenes (for the developer). In this case, the script resets every important SimStatus to "Untouched" and every variable to to their initial value. It also sets any values used to display or hide the conversations, so that the next node visualized will be either the Start node or the node from which you want players to begin the experience again.

Fig.2.2 – The key to the Replay node is the link back to a node at the beginning.Fig.2.2.jpg

To reset variables, you can include a line like this in the Replay node’s script:

Variable["name"] = initial value

Where name is the variable’s name (which has to go between quotes) and initial value is, well, the initial value of the variable.

If you set a node to only be visualized once, remember to set its SimStatus to Untouched, otherwise it won’t show up on replays! You can do so by adding this line to the Replay script:

Dialog[id] = "Untouched"

Where id is the number on the upper left corner of the node the SimStatus of which you want to reset.

2.3. Loops

A loop is a conversational structure in which you go from a node to its parent, and then back to the node. It’s very useful, for instance, if you want to ask a series of questions to an NPC, but you want to let the player decide in which order.

In the example, the player is asked to list the first five colours of the rainbow. Here is the canvas:


Fig.2.3 – A  colorful loop.

The trick here is that each of the coloured nodes is linking back to their parent group node (so that the text in node 1 is not repeated every time), and disappears from the choices after being selected once (through the condition Dialog[id] ~= "WasDisplayed", where id is each node’s ID (the number on the upper left corner of each node: red is 3, orange is 4, etc.).

Node 9, in which the NPC says "Fine, you can go!" has a different condition, which is

Dialog[3].SimStatus == "WasDisplayed" and

Dialog[4].SimStatus == "WasDisplayed" and

Dialog[5].SimStatus == "WasDisplayed" and

Dialog[6].SimStatus == "WasDisplayed" and

Dialog[7].SimStatus == "WasDisplayed"       .

That means that it will only be displayed when all the nodes listed has been displayed (which in this case means that we answered the NPC’s question).

There is one other thing going on, which is the [f] in all menu texts. We’re forcing the display of every choice, even if there is only one. If you want the last one to be picked automatically, without having to click it, you can simply forego the [f]s in your implementation.

2.4. Assigning and using variables

Now that we understand how conditions and loops work, how about we do something more interesting with them?

Fig.2.4 – A simple escape.Fig.2.4.jpg

In this example, the player has to open a door, but the door is locked; they won’t be given the possibility to unlock it until after they have searched the room and found the key.

By creating a boolean variable called hasKey (false by default), we’re already halfway done. What’s left after is to check in relevant nodes whether we have said key or not, or in the case of node 2 set hasKey to true, because we just found the key!

  • Node 3 condition, Variable["hasKey"] == false: The player can try the door an infinite number of times, but as long as they don’t have the key it won’t budge. When the player finds the key, this choice will disappear.

  • Node 2
  • Script, Variable["hasKey"] = true: we found the key, so we change the value of hasKey to true.
  • Condition, Dialog[2].SimStatus ~= "WasDisplayed": no need to search the room multiple times, so we only let the player go through this node once.

  • Node 5 condition, Variable["hasKey"] == true: when the player has found the key, we let them go through the door, and the demo ends.

To recap:

  1. First we create a boolean variable, that expresses whether or not the player has found the key.
  2. Then we set up a loop through node 3, so that the player can’t progress until they search for the key.
  3. When the player searches for the key nodes 3 and 2 disappear (as node 3 is only visualized if the player doesn’t have the key and node 2 is only visualized once), but node 5 – freedom – appears (through checking that the player has found the key).

Easy peasy!

2.5. Using variables in dialogue

Variables are not only very useful to control the flow of the conversation, you can actually include their value in the text! Say you want your player to change a number from a list of three, but you don’t know which number they’ll choose. Either every time that number comes up you create three different dialogue nodes, one for each possible choice, or you simply include the variable itself in the dialogue!

Let me illustrate: on the left the nodes in the conversation, and on the right (highlighter in black) what the dialogue is like when previewing it. Note that you can also see the line of code I included in node 2, for reference.


Fig.2.5 – The initial value, changed to 7, and then displayed again.

As you can see we have the variable magicNumber, whose default value was set to 1, mentioned in the text of two dialogue nodes. The syntax is fairly straightforward, you just insert the name of the variable in [var=name], and that will be substituted for the value itself when previewing or publishing.

2.6. Random variables

Now that we know how to assign a variable, we can step up and create a variable that will have a random value every time we start the conversation. This is really useful if you have a repetitive scenario (for instance a training scenario), and you want to change the choices the player has to make in order to succeed (e.g. the client you’re training has a random disposition towards you at the beginning of the conversation, so how you talk to them changes even if the scenario itself is the same).

To do this, we first have to go over a bit of ChatMapper’s inner workings: while ChatMapper itself and the simulator work with Lua, when previewing in HTML5 or publishing a build all the code you wrote is converted in JavaScript (otherwise it wouldn’t work online). You can exploit this to your advantage, and use the features of JavaScript (like we do in section 2.7) not native to ChatMapper; for this section, though, we will limit ourselves to analyzing the interplay between Lua and JavaScript.

If you want this randomization to work on previews and builds, you insert this in the script where you want that value to be calculated:

var jsVariable = Math.random();    .

Variable["cmVariable"] = jsVariable;

What this does is create a JavaScript variable, called jsVariable, and uses the JavaScript Math library (a collection of scripts to calculate many mathematical operations, like square roots, medians, etc.) to create a random number. This returns a floating-point, pseudo-random number in the range [0, 1]; that is, from 0 (inclusive) up to but not including 1 (exclusive)

If you want your random number to be between two inclusive numbers, you can do it like so:

window.getRandomIntInclusive = new Function('min','max','{min = Math.ceil(min);max = Math.floor(max);return Math.floor(Math.random() * (max – min + 1)) + min;}');

var jsVariable = getRandomIntInclusive(min, max);

Where min is the lower whole number value and max is the higher one. After that, we assign that to a variable we created  in ChatMapper, called cmVariable, and now you can do whatever you want with it, it’s a variable like any other. You can display it in dialogue, or use it in some other script or condition, or anything else you’d do with another variable.

If you’re working only with Lua and the simulator, you can tweak that code a bit. Since you don’t need to use Javascript, you can simply use the Lua math library and that’s that:

Variable["randomVariable"] = math.random(min, max);

"Why doesn’t this work in the preview?" We hear you ask. "Isn’t Lua code translated into JavaScript?". Well, yes and no. When it comes to variables, operations, conditionals, etc., Lua code is translated without a hitch. Unfortunately, since libraries change for each language (a library that exists in a language may be absent in another, or have a completely different name), it’s impossible to translate them. It will work if they have the same exact name, but as you can see even having different capitalization (the Lua library is math, the JavaScript library is Math) will stop this mechanism from working. Be sure to always check out the name of any library you want to use!

2.7. User input

If you’re working with HTML5 (i.e. if you are previewing and publishing your work), you can ask the user for input!

Fig.2.6 – On the right, the box displayed through prompt();Fig.2.6.jpg

You can do many different things with JavaScript, one of which is displaying the box on the right of Fig.2.6. How? It’s easy!

var name = prompt("What's your name?");

Variable["name"] = name;              .

By adding these two lines of code to a node (node 2 in the image) you can display a box with a text field. At the same time, we’re saving the contents of that text field to the JavaScript variable name when the user clicks okay, and then copying those to its Lua twin, Variable["name"], so that we can use it in the dialogue itself.

Note that if the user doesn’t input anything, the variable will be empty, and the sentence will come out like this:

Fig.2.7 – The player has not given any input.Fig.2.7.jpg

It’s fairly easy to prevent that by adding a few more lines of code (in bold), which will assign a default name in case the user leaves the field empty:

var name = prompt("What's your name?");

if (name == "") {                     .

        Variable["name"] = "Hayden";         .

}else{                                .

   Variable["name"] = name;        .

}                                     .

This structure is called an if-else: if the condition between parentheses is true (in this case name == "", i.e. name is empty), execute the instructions between the following brackets (i.e. assign "Hayden" as a name); otherwise (else) execute the instructions between the last pair of brackets (i.e. assign to the variable what the user wrote).

2.8. Hiding the language bar

While having a conversation in different languages can help immensely in expanding your audience, having to create such an amount of content is not always desirable. If that is the case, hiding the language bar from the user is important.

To auto-hide the the language bar you need to set Autoplay, and also a Start node. The structure is this:


Fig.2.8 – Node structure to hide the language bar.

Node 1 contains a line of JavaScript:


Which hides the toolbar. From its positioning, you probably already understood why both Autoplay and Start are needed: if you don’t include Autoplay, the bar will be visible (and clickable!) until the user starts the conversation from the list, and without Start the dialogue would simply begin on its own. Therefore, we use both to execute a script from an empty node (node 1) while at the same time giving a “beginning” to players.

2.9 Using icons in choices

You can include HTML in the Menu Text like you can do in the Dialogue Text, which allows adding icons to choices.

A big library can be found here: Taking the “check-square-o” icon as an example, the code to use can be found by clicking on it:

You can then paste that into the Menu Text, and the icon will appear when playing.

How useful was this article?

Click on a star to rate it!

We are sorry that this article was not useful for you!

Let us improve this article!

Tell us how we can improve this article?