Twee will (probably) outlive Twine

In my role as an educator and (now former) co-author of the Twee 3 specification along with many other members of the Twine Committee, I pay close attention to new interaction fiction tools and especially those using a Twee-like format. Imagine my surprise, having worked hard — seriously, it took nearly two years of research, internal debate, and lots of compatibility testing to finally get the Twee 3 specification out in 2019! — to try to make sure that Twee 3 is compatible with Twine 2, only to find out other tools have borrowed the format and ran it with over the last several years while I was focused internally.

In both cases, these projects have leap-frogged Twine in compatibility with other tools and address specific problems it cannot solve.

Twee (2006)

Unless you have been paying very close attention to a specific sub-group of the larger Twine community over the last several years, you are probably not aware of Twee. Or, even if you were, you maybe know it as something only used with Twine 1. Twee (2006), in fact, predates Twine 1 (2009) by almost three years.

[Side note: See my An Oral History of Twee from two years ago for a detailed breakdown of this history.]

With the move to Twine 2 in 2014, Twee was dropped was an import and export format. This did not stop people using it, however. Tweego (2013) and later Twee2 (2015) became popular tools for those with command-line experience and wanting to use the format. In fact, Yarn (2015), which now goes by Yarn Spinner (2018), also started using the format as part of the dialogue system that was later used for Night in the Woods (2017).

Twee represents nodes within a project using two colons (what the Twee 3 spec calls the start token) and the name of the passage. This is called its header. Content, what is called the body of the passage, then follows after the header and until the next header or the end of the file. Specific to Twee 3, information about the story is also encoded in JSON as part of a special header name called StoryData.

Twee shares with Twine its usage of the link syntax. Connections between nodes are written using two opening square brackets ([[) and two closing square brackets (]]). Between the two sets is a word or phrase. If a passage in the current story matches this word or phrase, a link is made between the nodes in the Twine 2 editor:

Example of Link Syntax usage in Twine 2 editor

[Side note: Twine 2 does not use the term link syntax. In fact, the Twine Cookbook uses the phrasing “link to another passage,” which I wrote. This one of the many problems with trying to document things in Twine, where there does not exist standardized names for things because they appear under multiple names such as Harlowe calling them “link text”, SugarCube calling them “link markup”, Snowman calling them “links”, and Chapbook calling them “simple links.”]

Depending on the story format used, additional code might appear in each passage. Beyond the use of the link syntax, each core story format in Twine 2 defines its own functionality. In Harlowe (the default story format) and SugarCube, this functionality is called macros. (Chapbook calls them modifiers and Snowman calls them templating.) These macros define additional programming support for the story format:

Example of Twee 3:


:: StoryTitle
Link Syntax Example

:: StoryData
 {
  "ifid": "BB8E54D7-E177-449B-B3F5-70B369109374",
  "format": "Harlowe",
  "formatVersion": "3.2.2",
  "zoom": "1",
  "start": "1"
}

:: Untitled Passage {"position":"203.5,98.5","size":"100,100"}
This is a passage in Twine.

[[Make a link]]

:: Make a link {"position":"401.5,100.5","size":"100,100"}
This is another passage.


Yarn Spinner (2018)

Yarn Spinner solves a specific problem Twine cannot: it can be written in a plain-text format and used with Unity. In fact, by side-stepping the story-format problem, Yarn Spinner presents a far better solution to creating a dialogue system for Unity by using specific functionality tied to its API than Twine can hope to ever do. It is also designed as part of a dialogue system and understands characters speaking through having their name, a colon, and the text for them to speak or use.

Yarn Spinner functionality is based on something it calls a command. (In Twine 1 and into the SugarCube story-format for Twine 2, this same functionality would be called a macro.) By using two less-than (<<) and two greater-than symbols (>>), a specific keyword can be used. Depending on the functionality, this can have different effects such as using the built-in conditionals (<<if>>), creating a new command (<<wait>>, <<move>>, etc), and other examples.

The use of two opening and two closing square brackets is called a jump in Yarn Spinner. It ‘jumps’ to another node when it is encountered. Twine does not have a name for the various forms of its link syntax. However, Yarn Spinner does. The use of the vertical bar within a jump is called an option and an arrow (hyphen and less-than sign) is called a shortcut option.

Unlike Twee 3 for Twine, which has to support all possible story formats in Twine 2, Yarn Spinner breaks up the header and body of a node using different symbols. Three hyphens (—) end the header section and the use of three equal signs (===) end the content of the node. Within the header, Yarn Spinner defines variables in a key:value pattern. The body then contains all of the dialogue for the node:

Example of YarnSpinner

title: Start
tags: 
colorID: 0
position: 535,183
---
Dan: See, it starts here.
Dan: And then this line would follow.
[[Scene2]]
===
title: Scene2
tags: 
colorID: 0
position: 846,178
---
Jesse: Here is the next scene.
Jesse: We arrived here via a jump, what Twine calls a link.
===

WOOL Platform (2019)

WOOL is based on Yarn Spinner. (Check out the Yarn Spinner online editor and WOOL online editor to see the similarities in design patterns.) In fact, digging into the documentation of WOOL, there are references to Yarn (Spinner) and how it is different:

Specific mention of Yarn in WOOL documentation (Screenshot taken on 21 May 2021)

Like Yarn Spinner, WOOL uses nodes with a header and body. However, unlike Yarn Spinner and its design around dialogue, WOOL is focused on a single speaker. It is also designed specifically for agents (nonhuman actors) interacting primarily with humans. Instead of using jumps, WOOL calls its link syntax replies.

WOOL also has command-like functionality. However, it calls them statements. These are used to control nodes using conditionals or create user-interface actions.

While the plain-text formatting syntax is generally the same between WOOL and Yarn Spinners, they differ the most at the interpretation layer. Yarn Spinner works with a C# API and for working within the Unity game engine. WOOL runs and is based on a Java API.

WOOL Platform Example:

title: Start
tags: 
speaker: Example
colorID: 0
position: 831,445
---
Hi, there!
I'm based on Yarn Spinner, but designed for agents!
[[ReplyOne]]
===
title: ReplyOne
tags: 
speaker: Example
colorID: 0
position: 1280,685
---
This is another reply!
We arrived here via what Yarn Spinner calls a jump and most Twine story formats call a link!
===

What’s next?

I cannot speak for the Yarn Spinner community and its connection to the WOOL Platform, but the hope in creating the Twee 3 specification by members of the Twine Committee was that it would be used to help spread better compatibility between other tools. To my knowledge, since being published late 2019, that was not happened. Part of the reason it has not is because, to be blunt, Twine missed the boat by several years.

By not defining a standard, or even creating documentation, on Twee until starting in late 2017, it allowed Tweego, Twee2, and even the now-defunct Cradle to fill this gap. Yarn (2015) and then Yarn Spinner (2018) was the result. They fill that compatibility with the Unity game engine Twine 2, with its schism between wildly different story formats, each with their own programming dialect, will never be able to fill.

While Yarn Spinner is not specifically mentioned by Chris Klimas (creator and maintainer of the Chapbook story format for Twine 2) as part of the design influences for Chapbook, its Vars Section of each passage is remarkably similar to the header of nodes in Yarn Spinner. If nothing else, it shows a re-convergence of variables syntax into YAML-like key: value patterns:

Example Chapbook Passages Represented in Twee 3:

:: StoryTitle
Chapbook Example

:: StoryData
 {
  "ifid": "568601B8-B817-41CC-A345-4AA1660AA0FF",
  "format": "Chapbook",
  "formatVersion": "1.2.1",
  "zoom": "1",
  "start": "1"
}

:: Untitled Passage {"position":"297,98.5","size":"100,100"}
variableExample: 5
--
This is the body of the passage.

[[LinkToAnotherPassage]]

:: LinkToAnotherPassage {"position":"296,248.5","size":"100,100"}
variableExample: true
--
The value of {variableExample} has been changed by the header of this passage.

Example Yarn Spinner Nodes:

title: Start
tags: 
colorID: 0
position: 524,189
variableExample: 5
---
Dan: This is the body of a node.

[[JumpToAnotherNode]]
===
title: JumpToAnotherNode
tags: 
colorID: 0
position: 888,186
variableExample: true
---
Dan: The value of {$variableExample} has been changed by the header of this node.
===

While Yarn Spinner (and the WOOL Platform by extension) are not, perhaps, completely indicative of where hypertext fiction is going in the coming years, they both represent the filling of a gap left by another tool. By existing as closed-source and usable only on Macs, Storyspace created a significant gap Twine, as open source and usable on Windows (and later fully online) was able to step in and fill. By rejecting Twee in the move to Twine 2, Yarn Spinner was able to step into the choice-based format gap created by Twine 2 and its use of HTML only import and export. If the creation of the WOOL Platform based on the Yarn Spinner format is any indication, the revised Twee format now known as Yarn might very well outlive Twine itself.