Full documentation

Relationship to Twine

Twee2 is built on top of Twine 2, minus the graphical user interface. As a result, virtually all of the documentation about Twine 2 (and specifically the documentation about the different story formats) is relevant to Twee2, too. Because Twee2 is inspired by Twee, its documentation is also a valuable resource: however note that you can't use Twee 'macros' in Twee2.

Writing and compiling code

Write Twee2 code using your favourite text editor. Syntax highlighting is available via this Sublime Text plugin for Twee. By convention, Twee2 source files have the .tw2 extension.

Compile Twee2 files using the twee2 command-line tool. There are two important modes of operation:

  • twee2 build input.tw2 output.html produces output.html based on the code in input.tw2
  • twee2 watch input.tw2 output.html does the same thing, but watches input.tw2 for changes, automatically recompiling whenever it is updated (note that it's not smart enough to understand when 'included' files have been changed, though).

Because Twee2 source files are just plain text files, they're well-suited to use with source control systems: you could, for example, use Github to share your code or to collaborate with other authors, even working on the same file.

Understanding story formats

Twee2 comes with built-in support for all of the same story formats that Twine 2 does:

  • Harlowe - the default format, which includes a simplified scripting format
  • Snowman - a minimal format that uses Underscore.js templates and jQuery to provide programmers with a powerful toolset
  • SugarCube - a TiddlyWiki-powered format that comes with support for multiple save 'slots' and a Twine 1/Twee 'macro'-like scripting syntax
  • Paperthin - used when you select "View Proofing Copy" in Twine 2, this minimal skeleton isn't really an output format as it is a proofing tool

If you've having difficulty choosing between them, there's a summary of the differences in the Twine 2 documentation.

To specify which format to use during compilation, use the optional --format parameter. E.g. you might type twee2 build input.tw2 output.html --format=Snowman. You can get a list of the formats that Twee2 natively understands by running twee2 formats.

It's possible to use any story format, e.g. if you've downloaded or written your own, by specifying the path to the story format's directory (the one containing the format.js file) in your --format parameter. For example, you might run twee2 build input.tw2 output.html --format=./MyFormat.

Rather than setting the format on the command-line, it's possible to specify it within your source code itself, using build configuration options.

Twee2 syntax

Twee2 uses a syntax that's heavily inspired-by but not 100% compatible with Twee:


Each block of text in Twee2 exists in a passage. Each passage begins with a title, which is prefixed by two colons:

::My Passage Name

Passage titles may only contain letters, numbers, basic punctuation, and spaces. Some authors prefer to avoid spaces in their passage titles. Passage titles are not case-sensitive: you don't have to use the same case when referring to a passage every time. Passages titles should be unique within a story: if they're not, only the last passage with a given title will be included in the story.

Passage titles may optionally be suffixed by one or both of:

  • Any number of tags, separated by spaced, inside a pair of square brackets. E.g:
    ::My Passage Name [tagone tagtwo]
    Tags can be used by code in your story (e.g. to send the player to a randomly-selected passage from a subset). Some tags have special meanings, as described below.
  • A pair of coordinates, separated by a comma and enclosed within angle brackets. E.g.:
    ::My Passage Name <123,456>
    Coordinates have no meaning to Twee2, but they can be used to enhance compatability with Twine 2: Twine 2 uses these coordinates to decide where to show the passages in its WYSIWYG editor.

If you include both tags and coordinates after a passage, the tags must come before the coordinates, e.g.:

::My Passage Name [tagone tagtwo] <123,456>

Some passages and tags have special meanings, as described below


Each passage may contain any amount of content, most of which will be stuff that the player sees. Many story formats understand Markdown formatting in passages, which makes it possible to easily add formatting to your passages. Links to different passages are supported in any of the following syntaxes (where 'Dungeon' is the name of the passage they'll be transported if they click the link, and 'click here', where present, is the text that they'll see to click on):

  • [Dungeon]
  • [click here->Dungeon]
  • [Dungeon<-click here]
  • [click here|Dungeon]

Special passages

Some passage names and tags have special meanings. These are:


The ::Start passage will, by default, be used as the initial passage that your player sees when they start reading. You can override this using build configuration options, but it's probably easier just to follow this convention.

::StorySubtitle, ::StoryAuthor, ::StoryMenu, and ::StorySettings

These names were used for special passages in Twee 1. They're not used by Twee2, but to maintain compatability with Twee 1 they're ignored and you should avoid using them unless you're writing a story that needs to be capable of being compiled by both Twee 1 and Twee2.


Any ::StoryIncludes passages (you can have as many as you like, but you probably should avoid having more than one in any file in order to avoid confusion) are treated as lists of secondary Twee2 files to 'include' into your story. This is described in more detail below, under splitting your code into multiple files.


Any passages with the 'stylesheet' tag will not be included in your story, but their contents will be injected into the story's stylesheet. For example, you could write:

::MyCoolStylesheet [stylesheet]

body {
  background: #eee;

tw-passage tw-link {
  color: red;

It's also possible to use SASS to enhance your stylesheet. Simply add the tag 'sass' or 'scss' to specify the dialect of SASS that you want to use, e.g.:

::MyCoolStylesheet [scss stylesheet]

body {
  background: #eee;

tw-passage {
  tw-link {
    color: red;


Any passages with the 'script' tag will not be included in your story, but their contents will be injected into the resulting web page as Javascript. For example, you could write:

::SomeAwesomeCode [script]

alert('This message will appear when the adventure starts!');

It's also possible to use Coffeescript to make your Javascript development more-beautiful. Simply add the tag 'coffee' to your script block:

::SomeAwesomeCode [coffee script]

alert 'This message will appear when the adventure starts!'


Put the 'haml' tag into your regular passages in order to allow you to write HAML code into your passages. HAML is a sophisticated templating language for producing HTML output, and for some it might be preferable to writing plain old Markdown. This includes the ability to inject Javascript/CoffeeScript into particular passages. For example, you could write:

::NicksBar [haml]
  Nick's Bar is exactly the kind of nightspot that helps you remember why you quit drinking.
  A depressed-looking barman pours another beer for an equally depressed-looking drunk, while
  over in the corner a street thug plays with a knife as he eyes you up. The floor is sticky
  and the air reeks of stale alcohol.
  %strong What would you like to do?
  %li [Nick<-Talk to the bartender]
  %li [BarToilet<-Go to the bathroom]
  %li [BarSit<-Sit in a booth]

  $ ->
    alert "This message will appear when you reach Nick's Bar!"


Passages marked with the 'twee2' tag are not included in your story. However, any Ruby code in them will be executed when the passage is processed by the builder. This can be used to set build configuration options as described below.

Splitting your code into multiple files

A major benefit of Twee2 over Twine 2 is that it's possible to break apart your story into multiple files, which can be used to structure your work, to facilitate teamworking with or without source control, and to make 'reusable' components such as stylesheets and scripts which can then be injected into later stories. There are two ways to do this:

Using ::StoryIncludes

Insert a ::StoryIncludes passage into your file and list within it the names of the files to include. Each will be appended to the end of your story before compilation. For example, the following game skeleton includes the contents of four other files - the main file contains only the ::Start passage:

**Journey To The Centre Of The Earth**

by Dan Q



Using ::@include directives

You can put an ::@include directive anywhere in your code to insert the contents of another file at that point. ::@include respects your current indentation level (e.g. when using HAML), so it's safe to use at any indentation 'depth'. For example, the following passages each include a separate file that contains a description of the house in the distance: that description is shared between the two passages, and updating the file updates the description in both.

::Greenhouse [haml]
  Light shines brightly through the tall glass walls of the ornate wrought-iron greenhouse, and
  the plants are verdant and lively. The [Garden<-door] stands open and a cool breeze blows in.
  ::@include description-of-house.tw2

::Garden [haml]
  The garden winds around decorative trees betwen the [greenhouse] and the [Porch<-mansion].
  ::@include description-of-house.tw2

Note that neither method of including code works recursively (i.e. you can't include a file that in turn includes another file), but this may be fixed in a future version.

Setting build configuration options

Creating a passage with the 'twee2' tag can be used to run arbritrary Ruby code or to pass additional options to the Twee2 compiler. This expands the potential capability of Twee2 almost-limitlessly, but for now the only supported options are:

  • Twee2::build_config.story_ifid = '[your IFID]' - used to set the IFID of your story, to facilitate catologuing. If you don't include this directive, the compiler will suggest a random one to you every time you run it and explain how to add it: if you're going to publish your story publicly, you should add the line it suggests before you do so.
  • Twee2::build_config.story_format = '[a story format]' - an alternative way of specifying the story format used by your story, rather than using the --format switch to the compiler. The syntax of format names and means of specifying externally-stored formats is identical to using the --format switch.

For example:

::Configuration [twee2]
Twee2::build_config.story_ifid = '41AB7776-D198-40F5-BD54-0493D49DA58C'
Twee2::build_config.story_format = 'Snowman'

Decompiling Twine 2 stories

It's possible to convert existing (compiled) Twee2/Twine 2 story files, in HTML format, back into Twee2 source files for further editing. This can be used to convert your Twine 2 projects into Twee2 files or to easily examine the contents of somebody else's story. This feature does not work on Microsoft Windows. To use it, run:

twee2 decompile input.html output.tw2

The input HTML file can optionally be a full web URL.