Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Learn about nodes and lines in Yarn Spinner scripts.
Yarn Spinner Scripts are built up out of nodes. Nodes are where you put your dialogue. You can have as many nodes as you want in a file.
title: Start
---
Narrator: Hi, I'm the narrator for the documentation!
===Each node has, at the very minimum, a collection of headers, and a body. All nodes have at least one header, which is the title. The title is the name of the node, and the body contains the Yarn script that contains your game's dialogue.
Nodes are used to separate out parts of the story, and make it easier to manage longer stories and branching.
The title of a node is important, because your game uses node titles to tell Yarn Spinner which node to start running. You also use the title of a node when you want to jump to another node. Node titles are not shown to the player.
Node titles must start with a letter, and can contain letters, numbers and underscores. Node names cannot contain a . (period).
For example, FirstNode, First_Node and Node1 are valid, but First Node, First.Node and 1stNode
The --- marker indicates where the body begins. After this point, you can put all of your Yarn script.
The === marker indicates where the node ends; after this point, you can begin another node.
The body of a node (that is, the content between the node start marker --- and the node end marker ===) is made up of three different kinds of content: lines, commands, and options.
When you write Yarn Spinner dialogue, just about every line of text that you write in a node is a line. When a node is run, it runs each line, one at a time, and sends it to your game.
A line of dialogue is just the thing you want some entity or character to say, usually beginning with the name of the entity speaking.
For example, consider the following Yarn Spinner script snippet from Night in the Woods:
When this code is run in the game, it looks like this:
Yarn Spinner sends each of these lines, one at a time, to the game. The game is responsible for taking the text, and presenting it to the player; in the case of Night in the Woods, this means drawing the speech bubble, animating each letter in, and waiting for the user to press a key to advance to the next line.
Lines of dialogue can contain just about any text, except for some special characters that Yarn Spinner uses to add extra information to a line.
If there is a set of characters without spaces before a colon (:) at the beginning of the line, Yarn Spinner will mark that as the name of the character. This information will then be passed to your game, so that you can change the way that lines are shown based on the character who's saying them. For example:
Nodes can also have a color: and a group: in their header, which specifies what colour the bar at the top a node is shown in, and the group they're gathered in, in the Graph View of the :
You can also set nodes to be Sticky Notes by adding style: note to the node header. This will render the nodes differently in the Graph View of the . The color: of the node will be respected too, if one is set, otherwise the Sticky Note will default to yellow:
You can learn more about in the section.
Write a story inside a single node using Try Yarn Spinner.
Use VS Code to write a tiny story of 5 to 10 lines, inside one node.
Here's our story, if you couldn't think of an idea:
Play your story the Preview mode inside VS Code
Use the Command Pallette to Preview your tiny story.
Mae: Well, this is great.
Mae: I mean I didn't expect a party or anything
Mae: but I figured *someone* would be here.
Mae: ...
Mae: Welcome home, Mae.This is a line of dialogue, without a character name.
Speaker: This is another line of dialogue said by a character called "Speaker".title: Start
---
Navigator: The quantum fluctuations are intensifying. We need to jump now.
Captain: But the calculations aren't complete. We could end up anywhere.
Navigator: The wormhole is collapsing. It's now or never.
Captain: Fine. Initiate jump sequence.
Navigator: Something's wrong. We're being pulled backward...
Captain: That's impossible. Unless...
Navigator: We're arriving before we left. We've become our own rescue mission.
===


Get started with Yarn Spinner Scripting by working through the fundamentals in detail.
If you're here, you've worked through the , and setup the , and you're ready to dive into the details of writing dialogue with Yarn Spinner.
This section of the documentation will take you through the scripting fundamentals:
combining Nodes, Lines, Options, and Jumps for simple interactive narratives
using Detours, Variables, and Yarn Spinner's Flow Control features for more complex interactions
running options Once, and Line Groups for flexibility and control
Once you've completed it, you can move to .
Learn about using line groups, which allow Yarn Spinner to choose which content to run, depending on conditions.
To give your dialogue more life and variety, you can also provide lines in a line group. When lines are in a line group, Yarn Spinner will choose one of them for you.
Line groups are collections of lines that begin with a => symbol:
In this example, the Captain will say "Navigator, fire the glitter torpedoes! That'll confuse the enemy ships!", and then Yarn Spinner will choose one of the subsequent lines to respond with.
You can attach conditions to lines in a line group, to ensure that they only run when it’s appropriate to do so. Conditions can be any true or false expression, and can also be combined with the once keyword to ensure that a line can only run once:
A line in a line group can also have additional lines belonging to it, which will run if the item is selected.
title: Start
---
Captain: Navigator, fire the glitter torpedoes! That'll confuse the enemy ships!
=> Navigator: *sighs deeply* Sir, we don't have 'glitter torpedoes.' Those were in your dream last night.
=> Navigator: *eyes roll skyward* Captain, weaponizing craft supplies is not part of standard space combat protocol.
=> Navigator: *Slumps shoulders in defeat* I'll... make a note in the log that you suggested tactical glitter, sir.
====> Guard: Greetings, citizen.
=> Guard: Hello, traveller.
Guard: Stay vigilant. // runs after 'Hello, traveller.'
=> Guard: Hail, adventurer! <<if $player_is_adventurer>>
=> Guard: I used to be an adventurer like you, but then I took an arrow in the knee. <<once if $player_is_adventurer>>Learn about using smart variables that determine their value at run-time.
Smart variables in Yarn Spinner are a powerful way to improve your dialogue and narrative flows. Unlike regular variables that only change when explicitly set, smart variables recalculate their value every time they're accessed, based on the expression that defines them.
Code Readability: They make your dialogue scripts more readable by using meaningful names instead of complex conditions.
Centralised Logic: Define a condition once and use it throughout your game.
Maintenance: When game mechanics change, you only need to update the smart variable declaration, not every place it's used.
Abstraction: They hide complex game state checks behind simple, descriptive names.
Creating a smart variable in Yarn Spinner is straightforward: <<declare>> command followed by a variable name (with the $ prefix) and assign it an rather than a static value. The expression can use , or even reference other variables.
For example: <<declare $is_powerful = $strength > 50 && $magic_ability >= 20>>.
This smart variable will automatically update whenever the values of $strength or $magic_ability change, making your dialogue able to dynamically respond to the player's stats without additional code.
Smart variables shine when you have conditions that you check frequently or that combine multiple factors. They're especially useful for:
Tracking complex character states
Monitoring game world conditions
Representing player achievements or quest status
Creating dynamic dialogue that responds to multiple game systems
By using smart variables, you make your dialogue scripts more intuitive and maintainable while keeping your game logic organised.
Learn about creating enums, which allow you to create variables that are constrained to a specific set of values.
In Yarn Spinner, enums let you create variables whose value is constrained to a pre-defined list of possibilities.
To define an enum you must provide a name, and some cases for it. Here's a new enum called Food with the cases Apple, Orange, and Pear:
<<enum Food>>
<<case Apple>>
<<case Orange>>
<<case Pear>>
<<endenum>>Once you've created an enum, you can use it just like any other variable:
// Declare a new variable with the default value Food.Apple
<<declare $favouriteFood = Food.Apple>>
// You can set $favouriteFood to the 'apple', 'orange' or 'pear'
// cases, but nothing else!
<<set $favouriteFood to Food.Orange>>
// You can use enums in if statements, like any other type of value:
<<if $favouriteFood == Food.Apple>>
I love apples!
<<endif>>
// You can even skip the name of the enum if Yarn Spinner can
// figure it out from context!
<<set $favouriteFood = .Pear>>Learn about once statements, which let you specify content that only runs once.
Sometimes it's useful to create lines of dialogue that can only ever be displayed once.
In Yarn Spinner Scripts, you can use a once statement to denote content that can only be run one single time. When the script reaches a once statement, it checks to see if it’s run before. If it has, it skips over it! Magic.
There are two main ways you can use a once statement, which we'll explore below.
<<once>> and <<endonce>>:<<once>>
// The guard will introduce herself to the player only once.
Guard: Hail, traveller! Well met.
Guard: I am Alys, the guard!
<<endonce>>You can also use an <<else>> clause within the <<once>> statement, which will be run if the relevant <<once>> content has already been seen:
You can also add an if to the once to run content a single time, but only when a certain condition is true. In all other cases, it will be skipped (or the else content will be run, if there is any):
If you add once (or once if) to a line, that line will only appear once, and will be skipped over every other time it’s encountered:
Similarly, if you add it to an option, that option will only be selectable once, and will be marked as unavailable after it’s been selected.
once statements are really useful when you want to show long, detailed content the first time it’s encountered, but you don’t want to show it every time. This means that players don’t need to mash the ‘skip line’ button over and over when they realise that they’re starting to see a long run of lines they’ve already seen:
Learn about using Commands in Yarn Spinner.
In Yarn Spinner, you can send instructions to your game through commands. Commands look like this:
<<wait 2>>
<<setsprite ShipName happy>>
<<fade_out 1.5>>Commands are sent to your game's Dialogue Runner, just like lines and options are. Commands are not shown to the player directly; instead, they're used for things like stage directions.
Yarn Spinner comes with some built-in commands; however, to get the most usefulness out of them, you'll want to define your own custom commands that make your game do what you need to.
There are two built-in commands in Yarn Spinner: wait, and stop.
waitThe wait command pauses the dialogue for a specified number of seconds, and then resumes. You can use integers (whole numbers), or decimals.
// Wait for 2 seconds
<<wait 2>>
// Wait for half a second
<<wait 0.5>>stopThe stop command immediately ends the dialogue, as though the game had reached the end of a node. Use this if you need to leave a conversation in the middle of an if statement, or a shortcut option.
You can create your own commands, so that your scripts can send directions to your game. For more information on how to create them in Unity games, see , in the Yarn Spinner for Unity section of the documentation, and equivalents for other engines.
Learn to use the jump command to move the narrative between nodes.
The <<jump>> command lets you move the dialogue between nodes. It is used by writing << then the word jump, a space, and then the full title of the node you want to jump the narrative to, then another >>.
To jump to a node with the title Rescue_the_Kitten , for example, you would write the line <<jump Rescue_the_Kitten>>.
Jump commands should always be placed on their own line, indented as appropriate.
For example, consider the following conversation, which could be structured inside one node, using nested options, or split over several nodes using options and jump commands. The before version is inside a single node, and works fine, but the after version is structured across multiple nodes, and is a lot easier to make sense of.
We recommend that you only move into the Yarn Spinner for Unity documentation after learning the fundamentals of Yarn Spinner Scripting.
<<declare $player_is_friends_with_sam = $sam_relationship_score > 50>>
<<if $player_is_friends_with_sam>>
Sam: Hey buddy! Good to see you again.
<<else>>
Sam: Oh, it's you. What do you want?
<<endif>><<declare $has_enough_materials = $wood >= 5 && $nails >= 10>>
<<declare $has_required_skill = $carpentry_level >= 3>>
<<declare $can_build_chair = $has_enough_materials && $has_required_skill>>
<<if $can_build_chair>>
Craftsman: You've got everything you need to build that chair now.
<<else>>
<<if !$has_enough_materials>>
Craftsman: You'll need more materials first.
<<else>>
Craftsman: Your carpentry skills aren't quite there yet.
<<endif>>
<<endif>><<declare $is_evening = $game_hour >= 18 && $game_hour < 22>>
<<declare $town_shops_open = !$is_holiday && $game_hour >= 9 && $game_hour < 18>>
<<if $is_evening && !$town_shops_open>>
Innkeeper: Most shops are closed now, but you're welcome to stay here for the night.
<<endif>>// Leave the dialogue now
<<stop>>
// Leave the dialogue if we don't have enough money
<<if $money < 50>>
Shopkeeper: You can't afford my pies!
<<stop>>
<<endif>>title: Start
---
Navigator: Where to, Captain?
-> Captain: I want to go back to earth!
Navigator: Earth it is sir.
Navigator: This jump will take us 10 hours.
Navigator: Permission to jump, sir?
-> Captain: Granted, let's go!
Navigator: On it, sir.
-> Captain: Not yet. Just wait a moment.
title: Start
---
Navigator: Where to, Captain?
-> Captain: I want to go back to earth!
<<jump Earth>>
-> Captain: Second star to the left!
<<jump SecondStar>>
Navigator: Being a Navigator sure is hard work!
===
title: Earth
---
Navigator: Earth it is sir.
Navigator: This jump will take us 10 hours.
Navigator: Permission to jump, sir?
-> Captain: Granted, let's go!
Navigator: On it, sir.
-> Captain: Not yet. Just wait a moment.
Navigator: Standing by, sir.
<<jump Done>>
===
title: SecondStar
---
Navigator: Can you be more specific?
-> Captain: I cannot, no.
Navigator: Right away, sir.
-> Captain: ... that one *gestures*
Navigator: Very good, sir.
<<jump Done>>
===
title: Done
---
Navigator: Being a Navigator sure is hard work!
===Separating dialogue segments into nodes can aid in writing neater files that are easier to edit as they grow.
When you use <<jump>> command, they'll be shown in the Graph View in Yarn Spinner for Visual Studio Code as an line with an arrow leading to the node that's being jumped to:
<<jump>> command being visualised in the Graph View.If you use the <<jump>> command to jump to a node that's in a different .yarn file, it will be visualised as a line leading to a small circle:
Write a simple story with several nodes.
Spread your story out over the nodes in a sensible manner.
Use the <<jump>> command to move between nodes in your story.
Make sure you specify the name of the node you want to jump to inside each <<jump>> command.
Run your story using Preview.
Play through it, and make sure the jumps behave as you'd expect.
Next up, learn about the Jump Command's close relative, the Detour Command.
<<once>>
Guard: Hail, traveller! Well met.
<<else>>
Guard: Welcome back.
<<endonce>><<once if $player_is_adventurer>>
// The guard knows the player is an adventurer, so say this line,
// but only ever once!
Guard: I used to be an adventurer like you, but then I took an arrow in the knee.
<<else>>
// Either the player is not an adventurer, or we already saw the
// 'arrow in the knee' line.
Guard: Greetings.
<<endonce>>Guard: Who are you? <<once>> // Show this line only one time
Guard: Go on, get lost!-> What's going on? <<once>>
Guard: The kingdom is under seige!
-> Where can I park my horse? <<once if $has_horse>>
Guard: Over by the tavern.
-> Lovely day today!
Guard: Uh huh.
-> I should go.
Guard: Please do.<<once>>
// Show long, character-establishing lines the first time
Guard: There's nothing new to report!
Guard: I've been at this post for hours, and I'm so bored.
Guard: I can't wait for the end of my watch.
<<else>>
// Show a more condensed version all other times
Guard: Nothing to report!
<<endonce>>Learn about Yarn Spinner's built-in functions.
A function is a block of code that provides a value to your Yarn scripts, which you can use in if statements, or store in variables.
In Yarn Spinner scripts, functions perform two main kinds of task:
Functions let you get values that change over time, or that depend on other values. For example, the random function returns a different random number every time you call it.
Functions let you get data from your game back into your scripts.
You call a function inside an expression. For example:
Yarn Spinner comes with several built-in functions for you to use.
visited returns a boolean value of true if the node with the title of node_name has been entered and exited at least once before, otherwise returns false. Will return false if node_name doesn't match a node in project.
visted_count returns a number value of the number of times the node with the title of node_name has been entered and exited, otherwise returns 0. Will return 0 if node_name doesn't match a node in project.
format_invariant returns a string representation of n, formatted using the invariant culture. This is useful for embedding numbers in commands, where the command expects the number to be formatted using the invariant culture. For example, <<give_gold {$gold}>>, which might end up as give_gold 4,51 in German, but give_gold 4.51 in English, can now be <<give_gold {format_invariant($gold)}>>, which will always be give_gold 4.51.
random returns a random number between 0 and 1 each time you call it.
random_range returns a random number between a and b, inclusive.
dice returns a random integer between 1 and sides, inclusive.
For example, dice(6) returns a number between 1 and 6, just like rolling a six-sided die.
min compares a and b, and returns the smaller of the two.
max compares a and b, and returns the larger of the two.
round rounds n to the nearest integer.
round_places rounds n to the nearest number with places decimal points.
floor rounds n down to the nearest integer, towards negative infinity.
ceil rounds n up to the nearest integer, towards positive infinity.
inc rounds n up to the nearest integer. If n is already an integer, inc returns n+1.
dec rounds n down to the nearest integer. If n is already an integer, dec returns n-1.
decimal returns the decimal portion of n. This will always be a number between 0 and 1. For example, decimal(4.51) will return 0.51.
int rounds n down to the nearest integer, towards zero.
You can create your own commands, so that your scripts can send directions to your game. For more information on how to create them in Unity games, see , in the Yarn Spinner for Unity section of the documentation, and equivalents for other engines.
Learn to use options, which allow your players to choose lines of dialogue.
When you want to let the player decide what to say, you use an option. Options let you show multiple potential lines of dialogue to the player, and let the player select one.
Options are lines prefixed with a ->. You write as many options as you'd like the player to see, and the player chooses one of them. The content of the option is like any other line of dialogue.
For example, consider the following code:
In this example, the line Navigator: We're arriving before we left. We've become our own rescue mission. will run.
The player will then be given the choice for the Captain to say either Let's alter our trajectory and break this temporal loop!, or We must complete the cycle. Our past selves depend on it.
Learn about detour and return, which let you temporarily move to another node, then return.
In addition to using the to move between nodes, you can also use a detour command.
A detour command looks very similar to jump: it takes a single parameter with the title of the node you want to move to, but unlike the jump command the detour command will return to the node that called it afterwards.
The detour command works much like the jump command, except it will return to the node it detoured from after that node is done. Here’s an example of it in action:
If the player replies No? to the guard’s question, Yarn Spinner will detour to the node titled Guard_Backstory and run its contents.
When the end of the Guard_Backstory


We recommend that you only move into the Yarn Spinner for Unity documentation after learning the fundamentals of Yarn Spinner Scripting.
Functions are not intended to be a way for you to send instructions to your game. For that purpose, you should use commands.
As much as possible, custom functions should be pure functions, and have no side effects besides returning a value based on parameters.
// Inside an if statement:
<<if dice(6) == 6>>
You rolled a six!
<<endif>>
// Inside a line:
Gambler: My lucky number is {random_range(1,10)}!In this example script these two options will be delivered together:
As will these, separately:
Options can have their own lines, which are run when the option is selected. If a different option is selected, they won't run. To write this, indent the lines that belong to an option.
In the following code, different lines will run based on which of the two shortcut options are selected.
When the player has the choice of saying either "Let's alter our trajectory and break this temporal loop!", or "We must complete the cycle. Our past selves depend on it."
Depending on their choice, the Navigator will say "Risky, Captain. We'd be writing ourselves out of existence." or "Then we're doomed to repeat this moment... forever.". Finally, no matter what was selected, the line "Sounds good!" will run.
You can also nest options below other options. For example, consider the following snippet of Yarn Spinner Script:
In this example script, the following options will be delivered together:
And then, depending on which one was chosen, another set of options will be delivered together.
For example, if the player chooses Captain: Let's alter our trajectory and break this temporal loop! , then the line from the Navigator will be delivered (Navigator: Risky, Captain. We'd be writing ourselves out of existence. ) and then two options for the Captain will be provided:
And if the player chooses Captain: We must complete the cycle. Our past selves depend on it. , then the line from the Navigator will be delivered (Navigator: Then we're doomed to repeat this moment... forever.) and then three options for the Captain will be provided:
Add options to your tiny narrative.
Consider adding some lines that belong to the options below them, too.
Run your single-node narrative using Preview
title: Start
---
Navigator: The quantum fluctuations are intensifying. We need to jump now.
Captain: But the calculations aren't complete. We could end up anywhere.
Navigator: The wormhole is collapsing. It's now or never.
Captain: Fine. Initiate jump sequence.
Navigator: Something's wrong. We're being pulled backward...
Captain: That's impossible. Unless...
Navigator: We're arriving before we left. We've become our own rescue mission.
-> Captain: Let's alter our trajectory and break this temporal loop!
-> Captain: We must complete the cycle. Our past selves depend on it.
===title: Start
---
Navigator: The quantum fluctuations are intensifying. We need to jump now.
Captain: But the calculations aren't complete. We could end up anywhere.
Navigator: The wormhole is collapsing. It's now or never.
Captain: Fine. Initiate jump sequence.
Navigator: Something's wrong. We're being pulled backward...
Captain: That's impossible. Unless...
Navigator: We're arriving before we left. We've become our own rescue mission.
-> Captain: Let's alter our trajectory and break this temporal loop!
-> Captain: We must complete the cycle. Our past selves depend on it.
Navigator: Ayee! We're all going to die!
-> Captain: Nonsense! Keep yourself together!
-> Captain: AHHHH! We're all going to die!
===-> Captain: Let's alter our trajectory and break this temporal loop!
-> Captain: We must complete the cycle. Our past selves depend on it.-> Captain: Nonsense! Keep yourself together!
-> Captain: AHHHH! We're all going to die!title: Start
---
Navigator: The quantum fluctuations are intensifying. We need to jump now.
Captain: But the calculations aren't complete. We could end up anywhere.
Navigator: The wormhole is collapsing. It's now or never.
Captain: Fine. Initiate jump sequence.
Navigator: Something's wrong. We're being pulled backward...
Captain: That's impossible. Unless...
Navigator: We're arriving before we left. We've become our own rescue mission.
-> Captain: Let's alter our trajectory and break this temporal loop!
Navigator: Risky, Captain. We'd be writing ourselves out of existence.
-> Captain: We must complete the cycle. Our past selves depend on it.
Navigator: Then we're doomed to repeat this moment... forever.
===title: Start
---
Navigator: The quantum fluctuations are intensifying. We need to jump now.
Captain: But the calculations aren't complete. We could end up anywhere.
Navigator: The wormhole is collapsing. It's now or never.
Captain: Fine. Initiate jump sequence.
Navigator: Something's wrong. We're being pulled backward...
Captain: That's impossible. Unless...
Navigator: We're arriving before we left. We've become our own rescue mission.
-> Captain: Let's alter our trajectory and break this temporal loop!
Navigator: Risky, Captain. We'd be writing ourselves out of existence.
-> Captain: Damnit, Navigator! Nothing can stop me existing!
Navigator: *sigh* Very well, Captain.
-> Captain: By gods! You're right!
Navigator: But it's only solution, I fear.
-> Captain: We must complete the cycle. Our past selves depend on it.
Navigator: Then we're doomed to repeat this moment... forever.
-> Captain: If we're doomed, at least we'll be remembered as heroes.
Navigator: .. if anyone remembers us at all
-> Captain: Forever... forever... forever...
Navigator: Sir?
-> Captain: We must do it!
Navigator: As always, sir, you're right.
===-> Captain: Let's alter our trajectory and break this temporal loop!
-> Captain: We must complete the cycle. Our past selves depend on it.-> Captain: Damnit, Navigator! Nothing can stop me existing!
-> Captain: By gods! You're right!-> Captain: If we're doomed, at least we'll be remembered as heroes.
-> Captain: Forever... forever... forever...
-> Captain: We must do it!GuarddetourWhen you detour into a node, Yarn Spinner runs the content from that node just as if you’d used a jump statement. When you reach the end of the node, or reach a return command, Yarn Spinner will return to just after the detour command. A return command looks like <<return>>. There are no parameters.
You can return early from a detoured node by using the return command. Doing so will return to just after the detour command as though the end of the node had been reached, for example:
When you detour into a node, that node can itself detour into other nodes. If a detoured node uses a jump command to run another node, the return stack is cleared. If you detour into a node, and that node jumps to another node, Yarn Spinner won’t return to your original detour site.
When you use <<detour>> command, they'll be shown in the Graph View in Yarn Spinner for Visual Studio Code as an line with an arrow at each end, from the node that's being detoured to the node that's being detoured to:
<<detour>> command being visualised in the Graph View.Write a simple story with several nodes.
Spread your story out over the nodes in a sensible manner.
Use the <<detour>> command to move between nodes in your story.
Make sure you specify the name of the node you want to jump to inside each <<detour>> command.
Run your story using Preview.
Play through it, and make sure the detours behave as you'd expect.
Next up, learn about Variables in Yarn Spinner Scripts.
title: Guard
---
Guard: Have I told you my backstory?
-> Yes.
Guard: Oh. Well, then.
-> No?
<<detour Guard_Backstory>>
Guard: Anyway, you can't come in.
===
title: Guard_Backstory
---
Guard: It all started when I was a mere recruit.
// (five minutes of exposition omitted)
===title: Guard
---
Guard: Have I told you my backstory?
-> Yes.
Guard: Oh. Well, then.
-> No?
<<detour Guard_Backstory>>
Guard: Anyway, you can't come in.
===
title: Guard_Backstory
---
Guard: Do you want the detailed version or the short version?
-> Detailed.
<<detour Guard_Detailed_Backstory>>
Guard: I hope you enjoyed learning all that.. Anyway...
-> Short.
Guard: Right, well, I was a recruit, then I wasn't.
===
title: Guard_Detailed_Backstory
---
Guard: It all started when I was a mere recruit.
// (five minutes of exposition omitted)
// (other stuff happens)
Guard: Want to hear more?
-> Yes.
-> No.
<<return>>
Guard: (speaks more garbage)
===Learn how to use logic and flow control in your Yarn Spinner Scripts.
So far, you've learned how to use Nodes and Lines, Options, the Jump Command, the Detour Command, and Variables to write Yarn Spinner Scripts.
Because it's actually a full programming language of its own, Yarn Spinner also supports flow control.
Flow control takes several forms, including if statements, and conditional options.
if statementsIn addition to storing information, variables are useful for controlling what's lines of dialogue are presented to the player. To do this, you can use if statements.
An if statement allows you to control whether a collection of content is shown or not.
When you write an if statement, you provide an expression, which is checked; if that expression evaluates to a true value, then all of the content in between the <<if>> and <<endif>> statements are run.
For example, consider the following Yarn Spinner Script:
This script will:
set a variable, $gold_amount, to 5;
show the line Player: I'd like to buy a pie!
use an if statement to see if $gold_amount is less than 10, and if that is the case, which it will be in this example, show the line Baker: Well, you can't afford one!
You can use the elseif and else statements to handle different situations in an if statement.
An elseif statement has an expression that gets checked if the if statement, or any previous elseif statements, don't run.
An else statement doesn't have an expression, and runs if the if and any elseif don't run.
For example, consider the following Yarn Spinner Script:
This script will:
set a variable, $gold_amount, to 5;
show the line Player: I'd like to buy a pie!
use an if statement to see if $gold_amount is less than 10, and if that is the case, show the line Baker: Well, you can't afford one!
You can have as many elseif statements as you want inside an if statement block, and you can use whatever you want inside, for example:
In this example:
there are two variables, $gold_amount for tracking the player's currency, and $reputation for their reputation in town
an if statement first checks if their $gold_amount is greater than or equal to 5 and whether their reputation is greater than or equal to 8, if both of these are true, then the line
When presenting to the player using the -> syntax, you may want to make some options not available. You can do this by adding a condition to the option, making it a conditional option.
For example, if you have a variable that tracks your player's reputation points, called $reputation, you might want to make certain options only available if the value of $reputation is high enough.
Conditions on options are done by adding an if statement to the end of the option. They look like this:
When Yarn Spinner runs this collection of options, it will check the expression inside the if statement. If the expression is false, then the option will be marked as unavailable.
If every option in a group is marked as unavailable, the game is allowed to tell Yarn Spinner that no option was selected. When this happens, Yarn Spinner will skip the options group, and run the next piece of content after the options.
Learn about storing data using variables in Yarn Spinner Scripts.
Sometimes it makes sense for the options presented or the outcomes of selecting different options to vary based on other things the player has done or said up until this point. This requires the use of logic and variables, which we'll discuss in this section.
Yarn Spinner Script is a full programming language, which means it has support for writing code that let you control how the dialogue in your game works. In this section, you'll learn how to use variables to control your dialogue.
Variables store information. Variables can store one of three types of information: numbers, strings, and booleans.
Every variable has a name. In Yarn Spinner, all variable names start with a dollar sign ($).
Declaring a variable means telling Yarn Spinner that a variable exists, what it's meant to be used for, and what initial value it has.
To declare a variable, you use the





otherwise use a elseif statement to see if $gold_amount is less than 15, and if that is the case, show the line Baker: You can almost afford one!
otherwise use a else statement to provide a fallback, which will show the line Baker: You can afford a pie!
end the if statement block with an endif statement.
Merchant: You're rich enough and popular enough for me to serve you!otherwise the elseif statement checks if their $gold_amount is greater than or equal to 10 (making them very rich), or their $reputation is greater than or equal to 10 (making them very well regarded), and if either of these are true the line Merchant: I wouldn't normally, but I'll serve you! is shown
if neither set of conditions is true, then the else statement means the line Merchant: You're neither rich enough nor important enough for me to serve! will be shown
<<set $gold_amount to 5>>
Player: I'd like to buy a pie!
<<if $gold_amount < 10>>
Baker: Well, you can't afford one!
<<endif>>
<<set $gold_amount to 5>>
Player: I'd like to buy a pie!
<<if $gold_amount < 10>>
Baker: Well, you can't afford one!
<<elseif $gold_amount < 15>>
Baker: You can almost afford one!
<<else>>
Baker: You can afford a pie!
<<endif>><<set $gold_amount to 5>>
<<set $reputation to 10>>
<<if $gold_amount >= 5 and $reputation >= 8>>
// The player is both rich and popular
Merchant: You're rich enough and popular enough for me to serve you!
<<elseif $gold_amount >= 10 or $reputation >= 10>>
// The player is either rich enough or popular enough to serve
Merchant: I wouldn't normally, but I'll serve you!
<<else>>
// The player is dirt
Merchant: You're neither rich enough nor important enough for me to serve!
<<endif>>Guard: You're not allowed in!
-> Sure I am! The boss knows me! <<if $reputation > 10>>
-> Please?
-> I'll come back later.Guard: Who goes there?
// If the player is a thief, a royal visitor, or a merchant, then
// go run the appropriate conversation for that. The player might be
// some combination of the three, so let them choose.
-> A thief! <<if $player_is_thief>>
<<jump Guard_Thief_Conversation>>
-> A royal visitor! <<if $player_is_royal_visitor>>
<<jump Guard_RoyalVisitor_Conversation>>
-> A merchant! <<if $player_is_merchant>>
<<jump Guard_Merchant_Conversation>>
// But if the player is NONE of those, then none of the options would have
// been available. We'll fall through to here.
Player: I'm nobody!
<<jump Guard_Nobody_Conversation>><<declare>>You may find it useful to create a special node (for example, titled Setup, or similar) that is used solely to <<declare>> all the variables your narrative uses. You don't need to run this node for the declarations to take effect.
You put information into a variable by using the <<set>> command. For example, the following Yarn Spinner Script puts a string, "Hello, Yarn!", into a variable called $greeting:
Variables in Yarn Spinner can store one of three types of information: numbers, strings, and booleans:
Number
Any whole or decimal number
1, 2.5, 3468900, -500
String
Any sequence of letters, numbers and other characters, enclosed in quotes.
Each variable can only store one type of value. Variables can change their value at any time, but they can never change their type.
For example, the following Yarn Spinner Script will work:
This works because while the value of each of the variable changes, the type doesn't change.
However, the following Yarn Spinner Script will not work:
This will not work because when they are declared, $myCoolNumber is set to a number, and $myFantasticString is set to a string, so they can only ever store that type of information.
You can work with the values stored in variables.
For example, numbers can be multiplied, strings can be combined, and boolean values can have logical operations (like and and or) applied to them. When values are used together like this, it's called an expression:
An expression needs to be a single type. You can't work with values of different types in a single expression.
For example, the following code will not work:
Yarn Spinner provides built-in functions for converting between certain types:
The string() function converts values of any type into a string.
The number() function converts values of any type into a number (if it can be interpreted as one.)
The bool() function converts values of any type into a boolean value (if it can be interpreted as one.)
These functions work within Yarn Spinner Scripts. They all work by passing in, between the ( and ), a value of any time, either directly or by referring to another variable, and they return the same value, converted to the appropriate type.
For example, consider the following:
In this snippet, we declare the variable $aNumber and assign it the default value of 42, so $aNumber will always store a number, and we declare the variable $aString and assign it the default value of "This is a string", so $aString will always store a string.
Then, we use the <<set>> command to upate the value stored in $aString, and assign it the value of $aNumber (which is a number, and can't be assigned directly to a string) converted to a string using the string() function. Thus, $aString will then contain the string "42".
Yarn Spinner supports the following logical operators. Most of these have multiple ways being written:
Equality: eq or is or ==
Inequality: neq or !
Greater than: gt or >
Less than: lt or <
Less than or equal to: lte or <=
Greater than or equal to: gte or >=
Boolean 'or'': or or ||
Boolean 'xor': xor or ^
Boolean 'not': not or !
Boolean 'and': and or &&
Yarn Spinner also supports the following maths operators:
Addition: +
Subtraction: -
Multiplication: *
Division: /
Truncating Remainder Division: %
Brackets: ( to open the brackets and ) to close them.
Yarn Spinner follows a fairly standard order of operations, and falls back to using left to right when operators are of equivalent priority.
The order of operations is as follows:
Brackets
Boolean Negation
Multiplication, Division, and Truncating Remainder Division
Addition, Subtraction
Less than or equals, Greater than or equals, Less than, Greater than
Equality, Inequality
Boolean AND, Boolean OR, Boolean XOR
To show the contents of a variable, you put it inside braces ({ }) inside a line. The value of that variable will appear in its place. For example:
<<set $variableName to "a string value">>
The value of variableName is {$variableName}.The value of variableName is a string value.Create a Yarn Spinner Script that uses variables.
Create a new narrative that uses two variables that track a player name, and an amount of currency. Make sure you declare them.
Use the <<set>> command to update the value of the variables appropriately
Make sure you remember the types!
You should always declare a variable before you first use it.
/// The name of the player.
<<declare $playerName = "Reginald the Wizard">>
/// The number of gold pieces that the player has.
<<declare $gold = 42>>
/// Is the door to the dungeon unlocked?
<<declare $doorUnlocked = false>><<set $greeting to "Hello, Yarn!">>// Set some initial values in some variables
<<declare $myCoolNumber = 7>>
<<declare $myFantasticString = "wow, text!">>
// Now change them!
<<set $myCoolNumber to 8>>
<<set $myFantasticString to "incredible!">>// Set some initial values in some variables
<<declare $myCoolNumber = 7>>
<<declare $myFantasticString = "wow, text!">>
// This will NOT work, because you can't change types!
<<set $myCoolNumber to "eight">>
<<set $myFantasticString to 42>>// Stores 3 inside $numberOfSidesInATriangle
<<set $numberOfSidesInATriangle = 2 + 1>>
// Store 4 inside $numberOfSidesInASquare
<<set $numberOfSidesInASquare = $numberOfSidesInATriangle + 1>>// This will NOT work, because you can't add a string and a number:
<<set $broken = "hello" + 1>><<declare $aNumber = 42>>
<<declare $aString = "This is my string.">>
<<set $aString = string($aNumber)>>If you use a variable without declaring it, Yarn Spinner will try to figure out what type it should have based on how it's being used in your scripts, as well as what initial value it should have - zero for numbers, false for booleans, and blank text for strings. When a variable is not declared, we call that an implicit declaration.
If you declare a variable, you can make sure that the type of the variable is what you intend it to be. Declaring a variable also lets you control what the variable's initial value is, and lets you add descriptive comments that explain the purpose of the variable to other people (or to your future self!)
As with node titles, variable names must not contain spaces. While they can contain a range of different characters the first character must be a letter. In general your variables will be made up of only letters, numbers and underscores.
Variables cannot be empty. All variables are required to have a value.
"Hello", "✓", "A whole sentence."
Boolean
Either the value true or the value false.
true, false