Twine for Beginners: Adding Local Images

Twine 2 lets you do a whole lot with simple text and hyperlinks, and it couldn’t be easier to get started. If you want to take things a step further and add images as well, that’s not hard either! There are actually a few different methods of doing this, each with their own strengths and weaknesses. I’d recommend adding images as Base64 where possible, but there are times when it’s handy to simply display a picture stored in the same place as your game, whether that’s on a website somewhere or on your computer.

About Local Images:

When I talk about “local images,” I’m referring to image files that are stored in the same place as the HTML file containing the actual Twine game. Your overall setup should look something like this:

This is a directory (which Windows refers to as a folder) containing the HTML Twine game itself – Visual Vera and the Three PNGs.html – as well as an image, bananas.png. When the player encounters the passage in which the banana image is supposed to appear, the game will look for a PNG named “bananas.png” in the same folder as itself and, if it’s there, display it in the appropriate place in the game.

Benefits of local images:

  • Images do not have to be hosted on an external site (which may not always be available).
  • Images do not require an internet connection.
  • Images should load quickly, even if they’re very large.
  • Code to include local images is short and neat in the Twine 2 editor.
  • Images are easy to edit: you can make changes in Photoshop, GIMP, etc. without needing to change anything in the game itself.

Drawbacks of local images:

  • Game is made up of multiple files, making it harder to keep organised and distribute.
  • Not suitable for, which only allows a single HTML file to be uploaded. (You can still upload your HTML game, but there’s nowhere for the image files and so they will not appear.)
  • Increases the overall size of the game. The HTML file will not be any larger, but you’ll have to make the images available along with it.
  • Not foolproof. A player who moves the HTML file away from the images before playing it will not see them.
  • Images will not appear when previewing the game using Twine 2.

Local images are in some ways an ideal option. If you intend to make your game available somewhere such as which allows you to upload the necessary images along with it, this method will ensure they load promptly (where Base64 encoded images may not) without having to depend on an external website.

However, there are also some pretty serious drawbacks. It simply isn’t possible to include images on in this way, and it’ll make the game harder to send directly via email etc. (since you’ll have to compress the game and images into an appropriately structured zip file rather than send the usual single HTML file). On top of that, you won’t be able to preview the images in Twine 2. If you want to see how they look, you’ll have to export the game as HTML, place it alongside the appropriate image files, then open it in your web browser.

How to do it:

The basic code to include a local image looks like this:


The portions in bold are things I’ve stuck in just to illustrate what should go there. Here’s a specific example:

This is a 100×100 pixel PNG of some bananas. A JPEG or GIF would be equally suitable. To include them in a Twine game, I would write this:

<img alt=”bananas” src=”bananas.png” />

That’s it. That’s all there is to it. As long as the HTML game is sitting next to a file called “bananas.png” then the player will see something like this:

However, if that file isn’t available – most likely because the game is stored somewhere like that simply doesn’t allow anything stored alongside it – then the player will see something like this instead:

This is one reason I recommend always including the optional description. Without it, the space that says “bananas” would be completely blank.

This example is from Visual Vera and the Three PNGs, a game I put together just to illustrate how to include images in Twine. The version on won’t display the local banana image for the reasons outlined above, but if you’d like to test it for yourself you can download bananas.png from this page (simply right click it, select “Save Image As…”, and name it “bananas.png” if that’s not the default) and download Visual Vera by following the instructions in this other tutorial.

Some extra tips:

Although the code to include local images is far neater than the code to include Base64 strings, you may still want to put the image in its own passage and then simply use the (display:) macro to display that passage where appropriate. If nothing else, (display: “banana image”) involves less typing than <img alt=”bananas” src=”bananas.png” />. It’ll also make it easier to make changes later on if you decide you want to do things differently. For more information on the (display:) macro, check out its entry in the Harlowe manual. For examples on how it’s used, have a look at my tutorial on displaying random text, which covers this extensively.

If you intend to send a game with local images for someone else to play, you may wish to rename the HTML file something along the lines of “GAME.html” “DOUBLE CLICK ME.html” so that it’s clear exactly what they have to do to run it. (This is not a concern if the game is hosted on or similar.)

Bear in mind that the pictures in your game will likely be visible as thumbnail images when the player goes to play it (though again, only if you’ve sent it to them rather than made it available somewhere online). If there are a lot of them then this may make it difficult to locate the HTML file necessary to actually play the thing, and if any of them give away elements of the plot then you’re essentially sending spoilers with the game. If you’d like to avoid this, you can put the images in their own directory/folder called “images” or similar, and include that alongside the HTML game. If you do this, you’ll need to make a small change to the code to display them:

<img alt=”bananas” src=”images/bananas.png” />

This tells the game that the file it’s looking for is located in “images” which should be in the same  as itself. Your setup should look something like this:

If you’re dealing with a particularly large number of images, this can also help you keep things organised. For example, you might decide to put bananas.png in a directory called fruit, which in turn is inside a directory called food inside images. To display it, you would write:

<img alt=”bananas” src=”images/food/fruit/bananas.png” />

There’s no right or wrong way to organise the images used in your game. If you’re sending it to someone, want them to have an easy time finding the HTML file they actually need to open, and would like to avoid the thumbnail previews giving away what’s inside (unless your player goes looking for them), then tucking everything inside an “images” directory is probably wise. If you’re just experimenting and don’t want the hassle of dealing with directories it all, simply keeping all the files in one place is absolutely fine.

There’s also no need to commit to one particular method before you start. Again, it’s very simple to move the images around later on provided you use (display:) to show them within the game: this means you only need to re-type their location once for each image, rather than once for every time that image appears.

To get a better idea of how this all fits together, you might like to try importing this example game by following the instructions laid out in this tutorial.

As always, if you make anything with the help of this tutorial, please leave a link in the comments below! You don’t need an account or even an email address – just leave your name and message and I’ll approve it as soon as I can.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.