“How can I use Twine with Unity?”

As someone who has produced dozens of videos on doing things with Twine and wrote most of the Twine Cookbook, a pretty common question I get from people is some version of the following: “How can I use Twine with Unity?”

The short answer is this: you can’t easily do it. Unity is not a web browser.

The long answer is much more complicated than I think some people who ask the question realize. It has to do with how Twine works and why Unity, by itself, is not designed to handle HTML.

How Twine Works

Something to realize when using the term Twine is that there is not a single “Twine”, but several story formats. Twine itself is the editor. It packages a story for use with a web browser, but does not “run” the data contained within the HTML itself. When running a story in a web browser, the different story formats act as a “runtime” and transform the data the Twine editor packaged into a presentation for the user to interact with when playing it.

Representation and Runtimes

HTML is a “markup” language. This is part of the acronym itself: HyperText Markup Language. This means it gives structure to a document and “marks up” where certain parts are within a text. For example, it “marks” where certain parts should have emphasis or be represented by strong emphasis. It does this through using tags.

An opening tag marks the beginning of some markup. It then contains some content, and the end of the content is signaled using an ending tag. A common example for “marking up” a document might look like the following:

Emphasis Example

<em>This would have emphasis!</em>

In the above example, the opening tag is <em>, its content is “This would have emphasis!”, and the closing tag is </em>. The use of the tags “mark up” the existing content, “This would have emphasis!”, and explains how to present its structure.

HTML is a representational language. It “represents” some data through a combination of text and its “mark up” to define the structure and other details for another program to read. In the case of a HTML file and a web browser, the HTML is the representation of some data and the web browser is a runtime. It “runs” the representation of the data.

Web browsers “run” HTML, a representation of data.

Enter JavaScript

JavaScript is a scripting language primarily used with web browsers. When a HTML file is read by a web browser, it creates an internal object of the document and allows code, JavaScript, to change this object based on things like user input. For example, when the user click on a link, something may change as a result.

In a web browser, JavaScript uses a concept called the Document-Object Model (DOM). This is the object form of the document as understood by the web browser. This transforms the text of the HTML file into a form the web browser, through using JavaScript, can change. In programming terminology, an object is simply a collection of values where any individual value is called a property and the ways in which these properties are accessed or used for certain actions are called methods. JavaScript code uses different methods to change the properties of the document-object created by the web browser.

JavaScript “sits between” the user and the internal document-object based on the HTML created by the web browser. Depending on the instructions included in the code, this could be something as simple as to change the color of some text on the screen or as complex as changing how links work in the HTML. Depending on the amount of code involved, JavaScript can do very powerful things. Online services like Google Drive are accessed using JavaScript as it translates managing files using a webpage, for example. Developers can also create dynamic and responsive experiences for a user.

Web browsers create an internal object based on HTML structures and allow JavaScript to change the object while running.

Story Formats are JavaScript and Stories are HTML

When using the Twine editor, the “Publish” action combines a story format with the HTML representation of a Twine story. As just a HTML file, this published file holds both the representation, the data of the story, and its runtime, the story format, needed to “run” it. When a web browser reads the file, it prepares the structures based on HTML and then runs the JavaScript, the story format, and allows it to change the internal object representation.

Story formats also have their own code. Harlowe, for example, uses functionality called macros to allow authors to make interactive or advanced stories in Twine. However, as its “own code,” this means the JavaScript of the story format Harlowe has to “run” this additional code as part of stories as well, converting it from what the author wrote in the story into something JavaScript can understand. When running a Harlowe story, the web browser would set up the initial structure and the story format would read the story data and work with its own code, interpreting what the author wrote and presenting to the user a combination of what the web browser initial saw, what Harlowe presents, and any use of “Harlowe code” (macros) included in the story itself by an author.

A Twine story only exists when run. Because of the combination of an author writing code the story format understands, and the story format itself being based on JavaScript, a Twine story does not really “exist” unless it is being run by the progressive layers of a web browser having read the HTML file, creating an internal object, and then the JavaScript of the story format performing its own actions based on its instructions and those as included by the story author before the HTML file was published.

Unity is not a Web Browser

Unity is a game engine. It uses the programming language C# to allow developers to change some internal values while the engine is “running.” In much the same way a web browser creates an internal object based on a HTML file, Unity does the same thing on a larger scale. It makes assumptions about common systems a developer might want to use including rendering (drawing things to a screen) and physics (testing if one or more things overlap with their positions within a space). Unity then allows developers to “script” different things using the C# programming language.

Unity is not a web browser. It does not understand HTML nor know how to run a story format based in JavaScript. However, this does not mean it is not possible to use Twine stories with Unity, merely that Twine HTML files are not made to be used with anything other than web browsers. While not updated in a few years, the project Cradle, for example, used Twine stories converted into a plain-text format called Twee and then created a different internal runtime for reading and understanding stories. It bypassed the JavaScript and story format problem through focusing only on the story data itself.

Yarn and YarnSpinner are based on Twee-like code. Using similar functionality to the macros existing in some story formats as part of Twine, Yarn and YarnSpinner use a single “story format” for creating narrative projects. This eliminates the problem Cradle ran into of needing to support multiple story formats and any changes introduced between versions. Because Yarn is a different project than Twine, this also means it is not beholden to any changes a story format used with Twine might introduce or a need to follow the Twee specification. As YarnSpinner is designed to work with Unity via its plugin, this makes creating projects using code like, but different than, Twine possible without needing to use the Twine editor or its story formats to interpret HTML story data.

“Will Twine ever work with Unity?”

No, probably not.

Twine is an editor. What is run when playing a Twine story is a combination of the JavaScript of a story format and the data as stored by the editor itself. A Twine story only “exists” when a web browser combines the representation of the HTML with the runtime JavaScript of the story format. The HTML file published by Twine is the instructions for running the story (JavaScript) and what data to use (story data). This is further complicated by each story format having its own “programming language” in the form of macros and other functionality. As this additional code must be converted by the story format into something JavaScript understands, a Twine story only exists when its data is being run by the story format within a web browser.

It is possible to embed a web browser within Unity and send instructions to it and receive output from it to use Twine HTML within Unity. However, such a solution introduces many more problems than it solves. Other Twine-like solutions exist for working with Unity like YarnSpinner. For the purpose of creating interactive narrative or dialogue systems, Ink + Unity plugin or Fugus exist to solve those problems, too. These do not have the same problems of needing to read HTML nor keep up with potential story format changes for trying to read Twee code written in the “language” of different story formats.

“Could someone write a Twine story format that understood Yarn?”

Someone should, if they haven’t already.

YarnSpinner uses a text format very similar to Twee. This should make it possible to create a story format for reading “Yarn stories” as they exist in a Twine HTML format and allow the story data to also be converted into Yarn for use with YarnSpinner. I am not aware of a project doing this, but would not be surprised if it was under development. This would not solve the problem of working with Twine in Unity, of course, but it would open a path for writing a “story” capable of being understood, with some minor changes, across both Twine and YarnSpinner projects.