Using Twine as a Game Narrative Engine: Getting Started
A quick primer in using Twine as a game narrative engine with the Sugarcube story format.
These days we have so many tools at our disposal to create interactive content and numerous tools now for developing interactive narratives but if you want something that’s beginner-friendly yet has some powerful features, a good place to start is to learn Twine.
Twine is a great starting place for writing narrative passages and if you never used it for anything other than organising your sections of narrative, it would still be pretty useful, but it allows you to do a lot more than writing stories. Through its different story writing formats i.e. Chapman, Harlowe, Snowman and Sugarcube, it allows you to format and code your stories with Macros or code directly within the story passages and publish the results as an HTML page that runs in the browser.
In my own experience, I have found the Sugarcube story format to be most flexible for my needs as it allows for a mixture of HTML, CSS and JavaScript, and other Twine-specific macros. I found Sugarcube interesting also because it challenged me to use more HTML, CSS, and JavaScript in fun ways and makes a creative departure from commercial web design projects when you feel like doing something different.
The additional code and functionality become more focussed on advancing the story or introducing interesting mechanics, instead of understanding how to better utilise responsive web design techniques, although if you wanted to use bootstrap or other web design frameworks or libraries and utilise other tools to the design of your story this can certainly be integrated. It makes it refreshing to concentrate your efforts on designing a GUI for the player, focussed around the story as opposed to designing a with a website visitor in mind.
Twine is really a storytelling engine that allows you to build interactive narratives using branches that can follow a linear or non-linear structure. It would certainly be possible to create an open-world narrative with Twine, even an emergent one if you have the skills to build something like that. It is a deceptively powerful engine that works on simple narrative branches to build up a story and if you add HTML for structure, CSS for style, and JavaScript for behavior, you can create some very advanced and visually creative digital stories.
In this post, I will attempt to give you some simple instructions on getting set up with Twine and some simple approaches to get started creating more visual Twine stories.
Once you practiced some of these approaches, you can start to set yourself some challenges for making your Twine stories more engaging and immersive.
Create a more compelling narrative that engages the player
Aim to develop a visual digital story by creating pages in Twine and use HTML/CSS/Javascript so that the player is further immersed. If you just stick to the standard text-based input and hyperlink style, it can get a little monotonous really quickly.
Incorporate multimedia assets such as images, audio, and animations or videos to enhance the story.
Publish your story on the following platforms. A website or Github.io portfolio page is a good place to showcase your creations which you will build or you could publish them on a dedicated game platform such as https://itch.io
Twine Functionality
In this article, I’m not going to get go deep with code, but I will introduce you to ways to get started by adding HTML, CSS and JavaScript to your pages.
In the next few articles, I will explore more specific elements and mechanics.
Download Twine
Twine can either be run in the browser by visiting Twinery.org using the link below or you can download it. I suggest downloading it for what we will be doing in this article as it is easier to follow if you have it installed on your computer. It’s open source and free, so that’s a bonus.
Twine / An open-source tool for telling interactive, nonlinear stories
You don't need to write any code to create a simple story with Twine, but you can extend your stories with variables…twinery.org
Install Twine
To install twine on your computer, download the latest version for your system and click the install icon. The installation process should be pretty painless, once the software has been installed you can launch Twine from windows explorer or mac finder.
Open Twine
When you open Twine for the first time, you will see an empty screen similar to this.
Then if you don’t want to start reading about Twine’s capabilities, click skip, you will arrive at an empty screen that will allow you to create your first story. Click New to create your first story
To create your first story select the + button.
Call it something catchy, or choose a working title for now. I chose Escape Story as I am going to start building a story around escaping from some location as yet undecided.
This will launch an empty-looking screen which is where you can create Passages which are blocks of narrative and code that you build. The first one is called “Untitled Passage” box by default.
As the box suggests, double-click the passage to edit it.
When you click the box, the passage will open so you can edit it.
You can edit the title. Each title should be unique but you can call it something simple like Intro for now.
Next, it says “tag” this can be left blank for the time being but can be useful to style and add scripting elements to specific passages.
Underneath the different options, you will see a minimal visual editor, similar to this.
If you don’t see it, if you only see the words “Edit the body text of your passage here . . .” then you are probably using an older version of Twine which might suggest you need to upgrade your version of Twine.
So before we go further, we need to set up a couple of things to get the story in the right format for editing with and styling the story.
Story Formats
Twine includes a number of Story Formats and there are pros and cons of using each of them. You can even create your own. In this series of posts I am going to be using Sugarcube.
By default, Twine uses Harlowe, so we need to “Change Story Format” to SugarCube before we start editing our story. You need to choose the most recent SugarCube version in your list of formats, in my case, this is version 2.62 as of the time of writing, but your actual version may differ. Select the lates version of SugarCube you have available. To do this choose the Story tab from the menu and then select Details. This will enable you to switch from Harlowe to Sugarcube in the drop down menu.
Once you have set the Story Format to be used, we are ready to use HTML formatting but we need to know where to put our HTML and CSS next.
Create a story style sheet
CSS stands for Cascading Style Sheets and whilst HTML is used for formatting and structure of the story, CSS is used to style the story, and because CSS is really powerful, you can pretty much style your story however you want.
To add CSS to your document you should click Edit Story Stylesheet from the Story menu.
Then copy and paste any CSS styles as and when you create them. We will explore this later in this post. The syntax of CSS needs to be strict, therefore all curly braces, semicolons, and colons need to be in the right place, otherwise, the styles will not work. To begin with, visit sites like W3Schools to learn how CSS works. As you become more familiar with CSS, you can try to be more experimental. Sites like CSS Tricks and Codepen.io can really help you experiment with interesting CSS effects. These can be as simple as button highlighting, but you can use CSS to explore animation, glitchy text effects, interactive elements to really develop the style of interacting with the GUI elements of your story.
Create a StoryInit file
A StoryInit file can be used to load scripts and add specific functionality at run time. You don’t necessarily need one but it’s good to have it in place in case you do.
It is equivalent to an On Start () Method that you might see in other engines or frameworks, and it is used to load defaults for your story as and when they are needed.
In the image below, click new and create a new passage called StoryInit
By default, you should now have two passages. One called Intro and one called StoryInit
The Intro passage will be the first passage you use to build your story and this will be the passage you edit first. Leave the StoryInit where it is for now until you need to use it.
Editing your first (Intro) passage.
You can use this like a word document and just start writing a story into it. But if you want to go somewhere else in your story, you need to start creating branching passages from this page.
Creating branching passages
A branching narrative needs branches. Luckily in Twine, this is really easy to do.
For our scenario lets imagine we have just walked up some stairs in an old house which we decided to explore in our story. At the top of the stairs you are faced with two doors
Feel free to change the examples below to something more relevant if you wish. This example will create a passage that has some text and two branches to a left door and a right door. Copy or write the following in your Intro Passage
You are at the top of an old staircase and in front of you, you can see two doors [[leftdoor]] or [[rightdoor]]
You will see that its created two new passages below from the links you have placed in the text above. No prizes for guessing that you can now edit these two passages for what might happen if you went inside the left door, or right door.
Create branches with specific names
If you wanted to make this a bit more descriptive, Twine allows you to change the name of the doors and the passage names to be different if you prefer.
You are at the top of an old staircase and in front of you, you can see two doors [[the open door on the left|leftdoor]] or [[the locked door on the right|rightdoor]]
Change the passage to match the above and you can then click the Test From Here button to preview
The result shows the descriptive name, not the passage name.
Add a sprinkling of HTML
Now that we have a descriptive passage with two branches lets try to make it look a little less default.
You can spend hours learning HTML and CSS and there are plenty of free and paid courses to get you up to speed as a web designer or developer. My approach has always been to use what you need for whatever you are working on right now.
If you want a couple of comprehensive and free web skills resources, these will really help you get up to speed.
Learn to style HTML using CSS - Learn web development | MDN (mozilla.org)
So for this task we don’t need to make the code too complicated. At this point we only need to add a heading and some paragraph elements.
<h1>Intro</h1>
<p>You are at the top of an old staircase and in front of you, you can see two doors.</p>
<p>[[the open door on the left|leftdoor]]</p>
<p>[[the locked door on the right|rightdoor]]</p>
Add base CSS styles in your Story Stylesheet
To alter the visual style of the story, lets include some base styles. Open the blank story stylesheet you created earlier and add the following CSS styles
body {
background: #ffffff;
color: #000000;
font-family: Arial, Helvetica, sans-serif;
}
h1 {
font-family: 'Times New Roman', Times, serif;
color: #000000;
font-style:italic;
}
p {
font-family: Georgia, 'Times New Roman', Times, serif;
}
a {
font-size: 1.2em;
color: #333333;
}
a:hover {
color: #cccccc;
text-decoration: none;
}
Getting creative with HTML and CSS
You can create almost any effect you can imagine with HTML and CSS. But this is outside the scope of this post. In this series of posts, I am going to experiment more with HTML, CSS and Javascript in an attempt to create a more immersive visual story.
The following links are good places to try to develop visual style within your stories using CSS.
CSS Tutorial
CSS is the language we use to style an HTML document. CSS describes how HTML elements should be displayed. This…www.w3schools.com
15 Inspiring Examples of CSS Animation on CodePen
CodePen is unquestionably the go-to place to show off what we can do with our web creations. Here's a list of some of…webdesign.tutsplus.com
Making your story more engaging
You are probably thinking that branching passages with text is quite interesting but your readers are going to get tired of clicking links to different passages. No matter how much you branch your narratives, you are going to put off your readers by expecting them to just aimlessly clicking passage after passage. So you are going to need to experiment to make this more of an experience for the player. Try to think about how you can get creative with HTML and CSS to add atmosphere to the visual aspects of the story to help the player feel more immersed as the story unfolds.
Adding Images
This is probably a good time to talk about folder structure and web pages. Although Twine does a pretty good job of previewing your story when you just click Play within the Twine interface itself, you are going to have to eventually understand a few things about folder structures including how images (or any linked file for that matter) need to be linked to your Twine story, if you are going to host this story on the internet. The first thing to address is file location. You can link to the absolute URL of an image from another web page but this creates two problems, firstly the load on the server and the time it takes to go and retrieve the image, and secondly, what if the owner moves or deletes the image or the page that it was on, then your Twine game is going to have a missing image.
A better approach is to use relative paths from the site root. For example, if you had your Twine story in a folder called “escaperoom” and you had created a subfolder inside that folder called images and an image called twodoors.jpg within that folder, the path to this would be images/twodoors.jpg
Right-click (windows) or CTRL-click (mac) to download this image or find a picture of two doors that you can use.
You can download the image from here
https://github.com/the-shedtronic-workshop/Twine_Escape_Room/blob/main/images/twodoors.jpg
The corresponding HTML code for this would be something like this.
<img class="passageimage" src="images/twodoors.jpg" alt="image of the two doors to enter">
This means that as long as you create a folder structure for your story and don’t change the location of the image files or the Twine passages, your story will always show the images within the story.
When you view it in your browser, you’ll probably notice that the image looks a little on the large side.
We can fix that in the style sheet
Add the following to your style sheet.
img.passageimage
{
width:500px;
border-width:3px;
border: solid #333333;
}
Now to rearrange the page so that it makes a little more sense visually.
<h1>Intro</h1>
<img class="passageimage" src="images/twodoors.jpg" alt="image of the two doors to enter">
<p>You are at the top of an old staircase and in front of you, you can see two doors.</p>
<p>[[the open door on the left|leftdoor]]</p>
<p>[[the locked door on the right|rightdoor]]</p>
The link below gives you more information about images, absolute and relative paths
Images in HTML — Learn web development | MDN
In the beginning, the Web was just text, and it was really quite boring. Fortunately, it wasn’t too long before the…developer.mozilla.org
Adding buttons with custom classes
The text of the links could be turned into clickable buttons with CSS. First change the paragraph elements for the two links and replace them with div tags. By adding a custom class to the divs you can then style them however you want with CSS.
<h1>Intro</h1>
<p>You are at the top of an old staircase and in front of you, you can see two doors.</p>
<img class="passageimage" src="images/twodoors.jpg" alt="image of the two doors to enter">
<div class="links">[[the open door on the left|leftdoor]]</div>
<div class="links">[[the locked door on the right|rightdoor]]</div>
In the story stylesheet you can then add the following
.links {
text-align:center;
border-width: 5px;
border: solid #333333;
background-color: #cccccc;
width:500px;
font-size:0.8em;
}
You can also hide the sidebar at this point, if its getting in the way.
#ui-bar {
display: none;
}
Publishing your story
Preview your story by publishing it to a file
When you click Publish to File, create a folder and rename the twine html file to index.html
This will make sure that the file opens up automatically if you publish your story online.
Double check that you have an images folder in there and make sure you have your twodoors.jpg file inside the images folder.
The HTML file should now look like this
<h1>Intro</h1>
<p>You are at the top of an old staircase and in front of you, you can see two doors.</p>
<img class="passageimage" src="images/twodoors.jpg" alt="image of the two doors to enter">
<div class="links">[[the open door on the left|leftdoor]]</div>
<div class="links">[[the locked door on the right|rightdoor]]</div>
and the CSS file should look like this.
body {
background: #ffffff;
color: #000000;
font-family: Arial, Helvetica, sans-serif;
}
h1 {
font-family: 'Times New Roman', Times, serif;
color: #000000;
font-style:italic;
}
p {
font-family: Georgia, 'Times New Roman', Times, serif;
}
a {
font-size: 1.2em;
color: #333333;
}
a:hover {
color: #cccccc;
text-decoration: none;
}
img.passageimage
{
width:500px;
border-width:3px;
border: solid #333333;
}
.links {
text-align:center;
border-width: 5px;
border: solid #333333;
background-color: #cccccc;
width:500px;
font-size:0.8em;
}
#ui-bar {
display: none;
}
Adding Sound
One way to add sound to a Twine story using the StoryInit passage
In this example I used a free sound from freesound.org https://freesound.org/people/SoundsForHim/sounds/399665/
Download this file, you might need to create an account on Freesound to do this.
Rename the file doorknock.mp3 and place it in a new folder called sounds
You can use the cacheaudio
macro provided by the SugarCube story format to preload audio files in a Twine story. This can be helpful if you want to ensure that the audio is ready to play when the reader reaches a specific point in the story.
To use the cacheaudio
macro, you can include it in a "StoryInit" passage and pass in the URL of the audio file you want to preload. For example:
<<cacheaudio "doorknock" "sounds/doorknock.mp3">>
This will preload the audio file and store it in the cache. You can then use the Audio
object or other methods to play the sound at a specific point in your story.
Keep in mind that the cacheaudio
macro is specific to the SugarCube story format and may not be available in other Twine story formats. If you are using a different story format, you may need to use a different method to preload audio files.
To make the audio file play, place the following code on the Right door file. Then it should play when you click on the Right Door link in the Intro passage.
<<audio doorknock play>>
Adding JavaScript
Twine uses an implementation of JavaScript called TwineScript
To assign JavaScript code to a variable in a SugarCube story, you can use the <<set>>
macro. This macro allows you to assign a value to a variable, which can then be used later in the story.
For example, let’s say you want to create a variable called message
that contains a string of text. You could do this like this:
<<set $message to "Hello, reader!">>
Then, you can use the $message
variable later in your story by referencing it like this:
<<$message>>
You can also join together variables as in the following example
<<set $greeting to "Hello">>
<<set $name to "world">>
<<print $greeting + ", " + $name + "!">>
You could set also set a variable to true or false and then check if something is true or false.
For example, if you wanted to pick up a key behind the left door and make it unlock the room on the right, this could be written in Twine Script.
First, you need to set a variable to have a true value. You can do this with a boolean variable using the Set macro.
<h1>Left Door</h1>
<p>You find a key and you pick it up</p>
<<set $has_key to true>>
[[Intro]]
Then on the Right Door passage you need to use a conditional statement in this case an IF/Else statement to check if the player has gone through the left door and picked up the key. If they go straight to the Right Door passage they will get a sound effect of the door knocking and a message to say they can’t enter.
If they have gone to the left door first and picked up the key, then they will get the sound of a key turning and an extra room to visit.
<<if $has_key is true>>
<<audio unlockdoor play>>
You insert the key into the lock and turn it. The door clicks open, revealing a room beyond.
[[Enter Room]]
<<elseif $has_key is false>>
<<audio doorknock play>>
You don't seem to have a key. You knock on the door in desperation.
Maybe there is a key around here some place . . . .
[[Intro]]
<</if>>
To make sure this all works properly, you will need to add an additional sound effect of a key turning.
You can access a suitable sound effect here.
https://github.com/the-shedtronic-workshop/Twine_Escape_Room/blob/main/sounds/unlock_door.mp3
Don’t forget to add the new sound effect to the StoryInit file as well
<<cacheaudio "unlockdoor" "sounds/unlock_door.mp3">>
When you click Enter Room you will arrive at the exit and this will end the game.
Through the following passage
<p>You enter the room which contains a secret door to the outside. You step through and you are free at last . . . </p>
<div class="links">[[play again|Intro]]</div>
If you want to play through the game but test that the Right Door is locked and won’t let you pass, you can change the Set $has_key to false on the Left Door passage
<<set $has_key to false>>
So there you have it, whilst this Escape the room game isn’t going to win any awards, it hopefully shows how you can start to experiment with Twine to create more immersive experiences.
If you want to just download the complete version of what I have created here, visit
https://github.com/the-shedtronic-workshop/Twine_Escape_Room
In the following posts, I am going to experiment further with different techniques to hopefully build a more immersive experience for the player. It will become a progress update series as opposed to a series of how-to posts. But hopefully there will be something useful for you in the posts to come.