Last updated: Oct, 2024
A common question for many new Twine authors is creating an inventory system. There are many different ways to create inventory, but for this story, you’re going to start easy and later, scale up to advanced.
In this story, players need to collect certain items. First, they need to find Bernie’s chili recipe to turn it over to the authorities. Next they need to find pickup keys and the gasoline to escape. Optionally, they can try to find a flashlight to pass through a dark area in the campground.
In easy mode, the objects start in the same location every time. On hard mode, the locations are randomized. You’ll get started by adding objects in easy mode.
Your basic basic inventory system
The easiest way to create an inventory system is to simply create a variable for each object in the story. For example:
(set: $hasFlashlight to false)
Later, you can check if the user has the flashlight and then branch your story based on that value. You’ll learn about branching stories in the next tutorial.
This inventory method works well for small stories that contain only a few items, but as you add more items, this approach becomes tedious and error-prone.
A better approach is to create a container and put items in it. You can assign this container to the player and even create containers for each passage. One such container is an array.
Meet the array (for your inventory)
An array is a container that holds things. You can have it hold numbers, text, and even other arrays! The best example of an array is a pill container.

The pill container contains pills for each day of the week. An array is just like a pill container except it can only contain one item. Instead of labeling each slot by the day, the array labels each slot by number.

When a player picks up an item, you’ll put that item into the array.

If the player drops an item, you’ll remove that item from the array.

If you wanted rooms to contain items, you could remove the object from the player’s inventory and put it in the room’s inventory. You won’t be implementing dropping behavior but consider it a personal challenge once you complete the tutorial series.
Just a side note here. When working with arrays, we have the concept of the index. For instance, the recipe in the previous diagram is located in the first index. That is, index 1.
When working with other languages, indexes are almost always zero-based. This means, in SugarCube, the first element in the array is stored at index 0 versus index 1. Harlowe is very much the outlier.
Implementing an array
To get started, you’ll define a new story-wide variable. Open your project in progress, or you can download the starter project for this tutorial:
Open the Setup passage. Create a new variable $inventory and create an array, using the (a:) macro.
(set: $inventory to (a:))
The Setup passage should look like the following:

This creates an empty array but by declaring this in the Setup passage, every passage has access to the array.
Now to add your first object. You’ll add a set of keys. Open the Camp Entrance passage and at the bottom of the passage, add the following:
On the ground, you see a set of [[keys]].
The passage should look like the following:

This creates a new Keys passage. This is going to be a temporary passage that you’ll delete in a later tutorial.
Open the Keys passage and add the following:
These looks like Bernie's keys to his pickup. <br><br>[[Pick them up->pickup]] or [[leave them->Camp Entrance]]
It should look like the following:

If the player leaves the keys, they’ll be sent to the Camp Entrance. If they decide to pick up the keys, they’ll be sent to the Pickup passage. You’ll notice this approach causes some problems.
First, the keys are “hardcoded” to the Camp Entrance. This means the keys will always be located in the Camp Entrance. Remember, on hard difficulty, object placement is supposed to be randomized.
The next issue is you are going to do this for every object in the story which is going to get old pretty fast.
Adding to an array
Arrays in Harlowe are somewhat confusing coming from another language. Typically, you directly set an item in an array. With Harlowe, you add arrays together to combine them. For instance, imagine you had a single smelly show in an array and you wanted add a smelly sock to go with it. You would need to put the sock in an array and then combine them together.
You add things together with plus sign just like you add two numbers together:
(a: "smelly shoe") + (a: "smelly sock")
This creates an array that looks like the following:
(a: "smelly sock", "smelly shoe")
Now you need to store the result. Can you guess which macro you’ll use? If you guessed (set:), give yourself a prize. Open the Pickup passage and add the following:
(set: $inventory to $inventory + (a: "keys"))
It should look like the following:

Uggh – that little bit of code that isn’t exactly obvious. This is a common pain point of Harlowe. As you add logic, your code will look like gobbly gook.
I’ve written lots of code in my time, including Objective-C that is a notorious ugly coding language. For me, Harlowe takes the ugly prize. Especially when you do complex things like writing your own macros (which won’t be covered)
Now to break down your code. Start on the right side. You’ll see the following code:
(a: "keys")
This creates a new array that contains the string, “keys”. You can also add other strings by separating them with commas.
(a: "keys", "flashlight", "recipe")
That creates an array containing three different text items. Now check out this code:
$inventory + (a: "keys")
The $inventory variable is an empty array and you are adding an existing array, so this combines the keys to the empty $inventory array. If you had existing items in the array, it would combine all those elements.
(set: $inventory to $inventory + (a: "keys"))
This code simply takes the combined $inventory and sets it to the old $inventory array. Now redirect the user. Add the following:
(go-to: "Camp Entrance")
The entire passage should look like the following:

Now run your story. If you select Easy mode and pick up the keys, you’ll be redirected back to the Camp Entrance like nothing happened.

Something did happen! You picked up the keys. You just don’t know it yet.
Printing from the array
This is where things start to get fun. You have two tasks to complete but unfortunately, you’ll only be able to complete one of them in this tutorial. Don’t worry, it’s coming up in the next tutorial!
First, you have to show the inventory. Once the user picks up the keys, you need to hide the keys from the passage’s description.
To print out the inventory, add the following to the bottom of the Camp Entrance:
You are carrying:
Now to write the code to get the first item in the array. Remember, array’s contain items so you want to get the first item. Add the following:
You are carrying: (print: $inventory's 1st)
That’s all it takes. Your code should look like the following:

You are printing out the first element. If you wanted the second, you’d write: (print: $inventory’s 2nd) and so forth. This is a weird syntax, especially if you are coming from another programming language.
Run your story. Select easy mode and right away, you’ll run into an error.

This is an error message. You are trying to print out the first item in an inventory, but the inventory is empty. Harlowe doesn’t know what to do, so it prints an error message to let you know.
Expand the disclosure triangle and you’ll see an error message:

This is reads, “the array is empty.” There’s nothing in it because you didn’t pick anything up.
Now with the story still running, go ahead and pick up the keys. When you return back to the Camp Entrance, the error message is gone. In its place is your first inventory item.

Congratulations! You’ve implemented a very rudimentary inventory system.
Where to go from here
Congratulations! You made it. You can download the completed story here:
Some of you may be scratching your head. Why did you have to write such complex code to get a basic inventory system? Why didn’t Twine come with such a system out of the box?
Twine is an interactive fiction engine. Even though many people use it to create games, Twine is not a game engine. It’s designed for create branching narratives like Choose Your Own Adventure stories.
There are other systems like Inform or TADS that have game concepts built into them from the ground up since they build interactive fiction games. For example, Inform allows you to create objects in one sentence. These objects can be carried by the player, dropped and manipulated.
Twine has a much broader scope. It’s meant to tell interactive stories and lots of those stories don’t have concepts of inventories or hit points. Thankfully, with some code, you can add your own.
You have your basic inventory in place but there’s a lot to do to build on it. In the next tutorial, you’ll clear up all those bugs and add new objects with a very helpful macro that poses a simple question: if.
See you then!
Discover more from Jezner Books
Subscribe to get the latest posts sent to your email.
Is there a way to hide the initial error message? (apologies if this comes up later, I’m just a bit confused)
Hey Rose, you can set the first inventory item to ‘nothing’. Makes it easy.
Thanks for the tutorial. Much appreciated.
[…] Next, you use the (a 🙂 macro to create an array. Remember, an array allows you to store multiple values in a list. If you’ve forgotten about arrays then do yourself a favor and reread this tutorial. […]