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...Attributes
Section titled “Attributes”Attributes are variables that store information about your story’s state, such as scores, inventory, player choices, and any other data that changes during gameplay.
You can set an attribute using the @set directive:
@set score = 100@set player_name = AliceAnd read it using double curly braces:
Your score is {{score}}.Hello, {{player_name}}!You can also set attributes directly from links:
Are you [[male]](start, gender=male) or [[female]](start, gender=female)?For a complete guide to attributes, including comparisons, conditionals, incrementing/decrementing values, and advanced features, see the Attributes documentation.
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 *.squiffyUser Input
Section titled “User Input”You can capture text input from players using HTML input elements. The value will be stored in an attribute that you can reference later in your story.
The data-attribute specifies which attribute will store the input value. You can then reference it using {{player_name}} or {{get "player_name"}}.
Input Validation
Section titled “Input Validation”Squiffy supports HTML5 input validation attributes. When validation attributes are present, section and passage links will be automatically disabled until all inputs pass validation.
Supported validation attributes include:
required- field must be filledminlength/maxlength- text length constraintsmin/max- numeric constraintspattern- regular expression validationtype- format validation (email, url, number, etc.)
In this example, the [[Submit]] link will be disabled (grayed out and unclickable) until:
- The name is at least 2 characters long
- The age is a number between 1 and 120
- The email is in a valid email format
Invalid inputs are highlighted with a red border, while valid inputs show a green border. As the player types, the validation updates in real-time, and links automatically become clickable once all inputs are valid.
You can use other HTML input types as well:
Custom 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.