WOOL Language Documentation

This is the official language documentation for the WOOL Language.

1. Basics & Terms

A WOOL dialogue definition is essentially a definition of a series of dialogue steps (that we refer to as nodes) linked together through user replies.

We define the following terms:

  • Node — A dialogue step that contains one Statement and a one or more Replies.

  • Statement — Something an agent says.

  • Reply — A possible reply that a user of the system can give.

  • Agent — A virtual speaker within a dialogue.

2. WOOL Nodes

A Node consists of two parts, a header, and a body.

2.1. Header

The header consists of a series of lines, each with a \{key: value\}-pair. The two required key-value pairs are:

  • title — a String that uniquely identifies this Node within this WOOL dialogue.

  • speaker — a String that defines the name of the Agent speaking in this Node.

This is a major difference from Yarn. In WOOL, each node represents a single step in a dialogue, and thus belongs to a single speaker (whereas Yarn allows multiple speakers and statements in the same Node).

You are free to define other key-value pairs that might serve as meta-data in your application. The WOOL Editor uses the following additional ones:

  • colorID — a number between 0 and 9 specifying a colour. This is also used by the editor’s run feature to allow multiple backgrounds, one for each colorID.

  • position — a pair of x,y-coordinates used to position the nodes in the editor.

Below is an example of what this looks like in a .wool file:

title: Start
speaker: Robin
colorID: 3
position: -416,112

2.2. Body

The body of a Node contains at least one Statement and zero or more Reply's. A very basic example is given below:

Hello, my name is Robin!

[[Nice to meet you Robin!|NodeRobin2]]
[[Goodbye.|NodeEnd]]

This Node defines a Statement "Hello, my name is Robin!", uttered by the Agent "Robin" and two possible Reply options. When a user selects "Nice to meet you Robin!" he will be forwarded to a Node labeled NodeRobin2, and when he selects "Goodbye." he will be forwarded to the Node labeled NodeEnd.

example woolnodes body

2.3. File Format

A .wool file consists of a list of concatenated Nodes separated by === markers. The header and body of the Node are separated by the --- line. For example:

title: Start
speaker: Robin
position: -416,112
color: cyan
---
Hello, my name is Robin!

[[Nice to meet you Robin!|NodeRobin2]]
[[Goodbye.|NodeEnd]]
===
title: NodeRobin2
speaker: Robin
position: -216,112
color: red
---
Nice to meet you too, how are you doing?

[[I am fine and you?|NodeRobin3]]
[[Goodbye.|NodeEnd]]
===
...

2.4. Comments

If you want to document your WOOL scripts with comments, WOOL Supports line-comments. Everything after a double-slash // is considered a comment:

Thank you very much. // Thank the user for the gift.

// If it was a nice gift...
<<if $giftNice >>
   ...

Pay attention when including hyperlinks in your text (e.g. https://www.woolplatform.eu) - in this case, the first forward-slash should be escaped, as follows:

Please visit https:\//www.woolplatform.eu for more information! // Comment goes here.
...

3. WOOL Dialogues

A series of WOOL Nodes is called a WOOL Dialogue. The following rules apply to WOOL Dialogues:

  • All Node title’s must be unique within a WOOL Dialogue.

  • There must be one Node with the title "Start" (this is the default starting point of the dialogue).

  • WOOL Dialogue files may contain letters, numbers, dashes and underscores, and end with .wool, valid examples include:

    • mydialogue.wool

    • my-dialogue.wool

    • my_dialogue-1.wool

    • 123dialogue_for-Robin.wool

3.1. Starting a Dialogue

Every WOOL Dialogue script must include a Node with title "Start". Applications that execute WOOL scripts can choose this as the default starting node for a conversation (or ignore it, and start somewhere else, it’s your party). For example:

title: Start
speaker: Robin
position: -416,112
color: cyan
---
Hello, my name is Robin!

[[Nice to meet you Robin!|NodeRobin2]]
[[Goodbye.|NodeEnd]]
===

3.2. Ending a Dialogue

There are two ways a WOOL dialogue can end:

  • The user doesn’t have any Reply options in the Node (the Agent has the last say).

  • The user chooses a Reply option that leads to a Node with title "End" (user has the last say).</li>

Example 1:

It was nice talking to you, bye!

Example 2:

Do you have any other questions?

[[I have nothing left to say.|End]]

Unlike the "Start" Node, the "End" Node is not mandatory to include in your WOOL Dialogue, as there are other ways to end the conversation. There is also nothing stopping you from creating a dialogue that can only loop indefinitely. When creating WOOL-based applications, you can also choose to provide a User Interface element that can "cancel" a dialogue at any time.

The node with the Title "End" is thus treated as a special case. When other nodes refer to it, this Node should be created in the dialogue as usual, however its contents must be empty. When the "End" node is reached in a WOOL Dialogue, the application should simply "close" the conversation. The special meaning of Nodes titled "Start" and "End" is different from Yarn, and are marked as such in the WOOL Editor.

4. WOOL Statements

Ultimately, every WOOL Node should output some text to display to the user, but WOOL Statements allow for a lot of flexibility in structuring and personalizing your dialogue.

4.1. Basic Statements

The most basic Statement is a simple line of text, that is uttered by the speaker (Agent) of the Node:

Hello, how are you?

4.2. Basic Statements with Variables

You can use variables within your Statements. Variables start with a $-sign, followed by one of A-Z a-z and then any number of a-z A-Z 0-9 or _ (underscores).

In short: variables names start with a letter, then contain letters, numbers or underscores, for example:

  • $variableName

  • $variable_name

  • $var123

These variables can be used within Statements to inject their values into a sentence, like so:

Hello $userFirstName, how are you?

4.3. Basic Statements with Special Characters

What if you actually want to include a $ character in your text? If it’s not followed by A-Z a-z, you can just type $. But otherwise you can escape it with a backslash: \$. And to include a backslash? Just escape it with another backslash: \\. In fact you can escape any character with \ and it will not be treated as a special character. Some more examples: \<< \>> \[[ \]]

4.4. Basic Statements with Markup

For the rest, WOOL doesn’t care about any markup you might want to apply, if you want to add HTML tags around text, please go ahead. The parsers will ignore it, and simply output the text including markup to your application:

Hello <b>$userFirstName</b>, how are you?

4.5. Control Statements: Setting Variables

WOOL allows you to set variables using the [set] statement.

<<set $userFirstName = "Bob">>
<<set $points = 0>>
<<set $hasReplied = true>>

The example above shows the three most common cases for setting either String, number or boolean variables. However, WOOL is much more flexible, and allows for example the set-Statements below:

<<set $points = $points + 1>>
<<set $name = $firstname + " " + $lastname>>
<<set $string = "String" + 12345>> // $string is set to "String12345"
<<set $string = 1 + 2 + "3">> // is parsed from left to right, $string = "33"
<<set $string = 1 + (2 + "3")>> // using brackets, resulting in $string = "123"

As you can see, you don’t have to define the type of the variable manually. Be careful when using more complex statements though. For example, when trying to add up numbers with Strings, WOOL will treat the result as a String.

4.6. Control Statements: Conditionals

WOOL supports if-then-else Statements. The simple example:

<<if $dayPart == "Morning" >>
   Good morning ladies and gentlemen!
<<elseif $dayPart == "Afternoon" >>
   Good afternoon peoples!
<<else>>
   Good evening everyone!
<<endif>>

Please note that “==” is treated as strictly-equals.

WOOL also supports nesting these if-statements, if needed:

<<if $dayPart == "Morning" >>
    <<if $userFriendly == true>>
        Good morning, sir! How are you today.
    <<else>>
        Mornin'.
    <<endif>>
<<elseif $dayPart == "Afternoon" >>
   ...

Note that in the case of boolean variables ($userFriendly), you can leave out the "` == true`" part. E.g. the following is valid and will work as expected if $userFriendly is an actual boolean value:

<<if $userFriendly>>

However, if $userFriendly is actually a String with value "No, he is not friendly.", this expression will evaluate to true. If the variable is empty (or "unset"), the expression will evaluate to false.

Be careful with using the short-hand form [if $variableName], because it is not strict, while for example [if $variableName == false] is strict. This means that if the variable $variableName has not been assigned a value, the following will happen:

If in your application you cannot be sure whether or not boolean variables have been assigned a value, our advice is to always use the if-equals-true-else construction:

<<if $variableName == true>>
  // The variable is a boolean, it exists, and it's value is definitely true.
<<else>>
  // The variable was either false, hasn't been set, or contains some other unexpected content.
<<endif>>

4.7. Control Statements: User Interface Actions

Sometimes you might want to couple some event or action to a statement uttered by a speaker. WOOL supports Actions of type link, image, video, or generic, all of which are shown below.

The link example:

Check out this website for an awesome dialogue platform.
<<action type="link" value="https://www.woolplatform.eu/">>

The image example:

And here you can see a picture of a dog.
<<action type="image" value="dog.png">>

The video example:

I would like to show you this cool video I found.
<<action type="video" value="https://www.youtube.com/watch?v=dQw4w9WgXcQ">>

The generic example:

Let me show you something in this book I found.
<<action type="generic" value="OPEN_RECIPE_BOOK">>

The four examples above show the four basic cases of using [action]-Statements. Every Action requires a type and a value. The type must be one of {link, image, video, generic}. The value has a specific and obvious meaning for types link, image, and video. For generic actions, you are free to assign your value tag, and write your WOOL Client to handle it however you like.

Besides the type and value parameters, an Action may have any number of additional parameters. See some examples below:

Check out this <<action type="link" value="https://www.woolplatform.eu/" text="website">> for an awesome dialogue platform.

In this example, we added the text parameter to the action of type link, so that we can tell our client to render the text, and turn it into a hyperlink.

In the example below, we extend our generic action to pass along some additional information to our recipe book widget. In this case, we want our UI to wait 2000ms, and then open the recipe book to page 42.

Let me show you something in this book I found.
<<action type="generic" value="OPEN_RECIPE_BOOK" delay="2000" page="42">>

5. WOOL Replies

Every Node can define zero or more (indefinite, but please consult your UI designer) Reply options, the different types are defined below.

5.1. Basic Replies

The standard Reply option defines a "user statement" and "Node Pointer", separated by a | (pipe).

[[Are you sure, Robin?|NodeConfirm]]

The user should be forwarded to the Node with title NodeConfirm when selecting the "Are you sure, Robin?" option.

5.2. Auto-forward Replies

In replies, you can leave out the statement, and just provide a Node Pointer, but you can only have one of these per Node.

[[NodeConfirm]]

This should allow your user to go to the NodeConfirm node when selecting e.g. a default "Continue" button, or automatically after some time (up to your UI design). You can not have two of these options in the same Node, but you can mix them with Basic replies, like so:

Would you like me to sign you up?

[[Yes, please do so!|Confirm]]
[[No, let's not.|Cancel]]
[[UserInDoubt]]

In the example above, you could for example give the user some time to choose between the "Yes, please do so!" and "No, let’s not." options, and after some time, automatically progress the dialogue to the UserInDoubt Node.

5.3. Input Replies

You can ask a user to provide various types of input using Input Reply options. The easiest way is to request some text input:

What is your first name?

[[None of your business Robin.|RobinInsulted]]
[[My name is <<input type="text" value="$userFirstName" min="2" max="30">>, why do you ask?|RobinInputGiven]]

The general format of this statement is: (optional) beforeText, inputStatement, (optional) afterText. (optional) min, (optional) max.

So, the minimum valid example is as follows:

What is your first name?

[[None of your business Robin.|RobinInsulted]]
[[<<input type="text" value="$userFirstName">>|RobinInputGiven]]

When a user chooses the Input Reply, the provided text is assigned to the value of the $userFirstName variable.

Very similar is numeric input:

[[I am <<input type="numeric" value="$userAge" min="0" max="120">> years old.|RobinInputGiven]]

In both cases the min and max parameters are optional (you can have none, either, or both).

Furthermore, WOOL supports time input in hours and minutes:</p>

[[I ate my breakfast at <<input type="time" value="$breakfastTime" granularityMinutes="15" startTime="09:00" minTime="06:00" maxTime="12:00">> this morning.|BreakfastTimeGiven]]

This results in the variable $breakfastTime being set to the provided input (e.g. "07:45"). There are four optional parameters:

  • granularityMinutes — In the example this is 15, meaning that you can enter 00, 15, 30 or 45. You can use any value between 1 and 60. The default is 1.

  • startTime — The time that the input widget should show initially. For example "09:00", but you can also write "now", or even a variable: “$breakfastTimeYesterday”. If you leave it out, then the input widget will start empty.

  • minTime — The minimum time that the user can enter. The default is "00:00".

  • maxTime — The maximum time that the user can enter. The default is "23:59".

5.4. Replies with Setting Variables

Instead of setting a variable in a single set-Statement, you can also set a variable as part of a Reply option, like in the following example:

Do you prefer meat or fish?

[[Meat please.|NodeMeat|<<set $likesMeat = true>>]]
[[Fish for me.|NodeFish|<<set $likesFish = true>>]]

5.5. Replies with Actions

Just like you are able to link a set-Statement to a Reply, you can also add action-Statements to replies, like so:

[[Please show me the recipes.|RecipesStart|<<action type="generic" value="OPEN_RECIPE_BOOK">>]]

5.6. Replies linking to other dialogues

There’s only so much you want to put into one WOOL dialogue definition before you start losing track (and/or sanity), so WOOL allows you to link between different dialogue definitions, like so:

What should we talk about now?

[[Know anything about cars?|CarsDialogue.Start]]
[[What about fishing?|FishingDialogue.Start]]

In this example, the first Reply option would take the user to the Node labeled "Start" of the Dialogue labeled "CarsDialogue". So, in this case, there should be a file named "CarsDialogue.wool" in the same folder as the current .wool script. Note that you don’t have to link to the "Start" Node of a dialogue script, and you can choose any valid Node name.