Basic concepts
You can write Hello World with no markup at all:
You can format text using Markdown, and also use HTML.
To create interactive stories, you’ll need to add some links. There are two types of text block you can use in Squiffy:
- Sections are the main units of text.
- Passages are smaller units which exist within sections.
Taking the player to a new section will deactivate all previous links, so use a new section when the player has taken some action to move the story forward.
Within a section, you can link to passages. After the player clicks a link to a passage, links to other passages in the same section will remain active.
Sections
Section titled “Sections”Section names must be unique within a story. Set up a section using double square brackets, followed by a colon. To link to a section, use double square brackets.
To use different link text, put the name of the section in brackets afterwards.
This is [[how to use custom link text]](section2).Passages
Section titled “Passages”Set up a passage using single square brackets, followed by a colon. Passages can link to further passages. After the player clicks a link to a passage, that link is deactivated, so the player can only click it once. To link to a passage, use single square brackets.
Passage links can be explored in any order - in the example above, the player might look at the book first, then look at the TV, then open the book. Only after clicking a link to another section will any remaining passage links be deactivated.
Passage names must be unique within their section.
To use different link text, put the name of the passage in brackets afterwards.
This is [how to use custom link text](passage1).Continue links
Section titled “Continue links”When you want a simple link that moves to the next part of your story, use +++ followed by the link text. This creates both the link and a new section in one step.
The +++ syntax is a shorthand. Instead of writing:
This is the first part.
[[Continue...]](second part)
[[second part]]:This is the second part.You can simply write:
This is the first part.
+++Continue...
This is the second part.Everything after +++Continue... until the next +++ or [[section]]: becomes the content of the new section.
You can use directives like @clear or @set immediately after the +++ line:
+++Next chapter...@clear
The screen clears and this text appears fresh.Section dividers and next-section links
Section titled “Section dividers and next-section links”Sometimes you need to link to the next section from inside a block helper like {{#animate}}. The +++ syntax won’t work there because it would split the section before the closing {{/animate}}.
For these cases, use --- to start a new anonymous section, and [[text>]] to create a link that points to whatever section comes next.
The > at the end of the link text means “link to the next section”. This is equivalent to:
{{#animate "fadeIn"}}Welcome to the story!
[[Begin]](section2){{/animate}}
[[section2]]:The adventure starts here.
[[Continue]](section3)
[[section3]]:And the story continues...You can also use the explicit form [[link text]](>) if you prefer, or if you need to set attributes:
[[Begin]](>, score=10)JavaScript
Section titled “JavaScript”Any section or passage can call some JavaScript when it is displayed. Simply indent with four spaces or a tab, before the text.
Turn counting
Section titled “Turn counting”You can trigger a passage after the player has made a certain number of clicks within a section. For example, you can display some extra text, to indicate the passage of time. Or, the passage might run some JavaScript to automatically move the player to another section.
In the example below, the text “We’re nearly here. The train is pulling into the platform.” is always written after the first passage click. After the second passage click, we are moved into the next section.
You can also trigger a passage to be written only after all the passages in that section have been clicked on.
See the example below where after all passage links have been clicked the text “You have examined every item.” will display.
Clear the screen
Section titled “Clear the screen”Any section or passage can clear the screen using @clear on a line on its own:
[[Chapter 2]]:@clearMy first reaction to the explosion was...Set attributes
Section titled “Set attributes”You can set an attribute within a section or passage like this:
@set score = 1000If the value is a number, it will be stored as a number. Otherwise, it will be stored as a string.
For boolean (true/false) values, to set as true:
@set my_true_valueand to set as false:
@set not my_false_valueor alternatively:
@unset my_false_valueFor number values, you can increase or decrease the value by 1:
@inc score@dec healthOr to increase or decrease by other amounts:
@inc score 100@dec health 5Conditional attribute changes
Section titled “Conditional attribute changes”The @set, @inc, @dec, and @unset directives run when a section or passage loads—they always execute regardless of any {{#if}} conditions in the text.
If you want to change an attribute conditionally (only when an {{#if}} condition is true), use the helper versions instead:
{{#if (seen "helped the wizard")}}{{inc "reputation"}}The wizard remembers your kindness.{{else}}The wizard eyes you suspiciously.{{/if}}The available helpers are:
{{set "attribute" value}}— set an attribute to a value{{unset "attribute"}}— set an attribute to false{{inc "attribute"}}— increase a number attribute by 1{{inc "attribute" 5}}— increase by a specific amount{{dec "attribute"}}— decrease by 1{{dec "attribute" 3}}— decrease by a specific amount
These helpers produce no visible output—they only modify the attribute. The key difference from the @ directives is that they execute at render time, so they respect {{#if}} conditions.
You can also set an attribute value from a link:
Are you [[male]](start, gender=male) or [[female]](start, gender=female)?
[[start]]:Your choice has been recorded.And you can also set a value in JavaScript:
squiffy.set("gender", "female");Read attributes
Section titled “Read attributes”You can display the value of an attribute using {{name}} (if the attribute name is all one word), or {{get "attribute name"}}.
You chose {{gender}}.You can also read a value using JavaScript:
var gender = squiffy.get("gender");You can conditionally display text depending on the value of a boolean attribute using {{#if (get "attribute name")}}.
{if gender=male:You are a man.}{else:You are a woman.}To compare two attributes, add an @ before the second attribute name:
{if a=@b:attribute value a and attribute value b are equal.}{else:They are different.}Embed text
Section titled “Embed text”You can embed text from another section, or from a passage in the current section, using {{embed "section or passage name"}}.
Track which sections and passages have been seen
Section titled “Track which sections and passages have been seen”You can tell if the player has seen a passage or section using JavaScript:
if (squiffy.story.seen("passage3")) alert ("You have seen passage3!");You can also conditionally display text. Here we’re using {{#if}} with the
seen helper to check if the passage “open” has been seen.
Try clicking the “cupboard” link first, to see the description of the closed
cupboard. Then, Restart the game, and now click “open” first, then “cupboard”,
to see the difference.
Set the start section
Section titled “Set the start section”By default, the story begins in the first section. You can choose a different section like this:
Set the title
Section titled “Set the title”Set the title like this:
@title My Amazing Interactive StoryMaster sections and passages
Section titled “Master sections and passages”An empty name for a section or passage creates a “master”, which is triggered for every section or passage in the game. (A master passage defined in a named section will only be triggered for every passage in that section)
e.g. to clear the screen before every section, and to increase a global turn counter:
[[]]:@clear@inc turns if (squiffy.get("turns") > 5) ...Importing files
Section titled “Importing files”Importing files only works in the command-line version of Squiffy
You can split your script up into multiple files and import them:
@import other_file.squiffyYou can also use the same syntax to import external JavaScript files:
@import my_script.jsThis syntax also accepts wildcards, so you can include all .squiffy files in a directory:
@import *.squiffyCustom HTML and CSS
Section titled “Custom HTML and CSS”The index.template.html and story.template.css files are customisable. It is better not to edit the ones in your Squiffy directory - you can copy them to the same directory as your .squiffy story script file, and make edits there instead.