Linking inventory items

By Brian Moakley May 14, 2022
Last updated: Oct, 2024

At this point in this tutorial series, you have half of an inventory system in place. Inventory items appear on select passages. It would be nice to make each item linkable. When the user clicks on a link, they should be presented with another passage that contains a description of the item and maybe an image.

This should be easy. After all, linking passages is a key aspect of working with Twine. Or, is it? The only way to find is to start coding.

If you enjoy these articles, please support my work on Patreon. This enables me write more articles on a variety of subjects.

Patreon logo

Describing items

To get started, open your project in progress. If you don’t have it, you can download it from the following link:

The big question … how do we pass an item to our new passage. For that, we use a variable that can be accessed from any passage. Here’s how it will work:

When the player click the item name, you’ll see the $currentItem to the object that the user selected. Then, in the Item Description passage, you can use that variable.

This variable can be accessed from every passage in your story. You’ll be using it as a global variable. In most development languages, using global variables is considered a bad idea. But in Harlowe, it’s the only game in town so we roll with it.

Setting up the item description

Open up your starter project in Twine. Create a new passage. Name the passage to Item Description. This is the passage that will allow the user to examine an inventory item.

This passage will be accessible throughout the entire story. You can think of it as a global passage. Now open up the Setup passage. Add your new variable with the others.

(set: $selectedItem to (dm:))

It should look like the following:

Now open the Item Description passage. At this point, print out the item description.

(print: $selectedItem's description)

Now after the user reads the item description, they will need a way to return back to the referring passage. Remember, this passage is a global passage that can be accessed from anywhere in the story. You could use another variable, but there is another way.

Using (history: ) and (link: )

You could create another global variable, but an easier solution is to use the (history :) macro. This is an array of passages in the order that the player has visited.

You want to use the previous passage. In the Item Description passage, add the following at the end of the passage.

(set: $previous to (history:)'s last)

It should look like the following:

This shows the Item Description passage with the previous code added to the bottom of it.

This sets the $previous variable to the last passage. Now, you want to send the user to passage. For this, you use the (goto :) macro. Yet, you need to call this when the user taps a link. For this, you use the (link :) macro.

The (link :) macro will run additional macros when the player clicks on the link. In your case, you’re going to call the (go-to: ) macro to send the user back to the previous passage. But you can use it with any tags. Add the following:

(link: "Back") [
    (set: $previous to (history:)'s last)
    (go-to: $previous)
]

It should look like the following:

This shows the Item Description passage with the previous code added to it.

In this code, you set the previous passage in a variable. You don’t actually need to do that. You can actually just assign it like the following:

(go-to: (history:)'s last)

While this approach is more concise, I find it a little clunky due to Harwlowe’s language syntax. Ultimately, when it’s your code, it’s your choice. Use what works best for you.

Linking the inventory items

At this point, you have everything you need to link your inventory items. You loop through each item in the inventory, add a (link: ) macro, and in the (link :) macro, you set the selected item.

Open the Inventory passage. Update it to the following:

<br>
{ (if: (passage:)'s tags contains "Inventory") [
You are carrying: (for: each _item, ...$inventory) [
  (link: _item's name) [
  (set: $selectedItem to _item)
  (go-to: "Item Description")
  ](if: $inventory's last is not _item)[, ]
]]}

It should look like the following:

This screenshot shows the Inventory passage showing the updated code passage.

Here’s the breakdown. If the current page contains an inventory tag, then the rest of the code will be evaluated. It creates a new link using the item’s name as the link text. When the user clicks the link, the code sets the $selectedItem. It then sends the user to the description.

Unfortunately, the code organization is deliberate. It makes sure the spaces are consistent. This results in very hard-to-read code. It’s also brittle, meaning, small adjustments may cause spacing problems.

Now run the story. This time, you get linked inventory items.

And clicking on an item leads to the description:

And now you have a working inventory. When you click the backlink, you find yourself back where you started. Nice work

Where to go from here

Well done! Feel free to download the completed project:

At this point in the series, you can wander a fictional campground and examine inventory items, but you can’t actually pick something up. Also, it would be nice to place all the items on the map. To do that, you’ll need to learn how to get random.

In the meantime, see the Harlowe documentation of the (link: ) and (click :) macros to see what other things you can do. Then, see me in the next tutorial.


Discover more from Jezner Blog

Subscribe to get the latest posts sent to your email.

By Brian Moakley

Brian Moakley is a writer and editor who lives amongst the quiet hills in New England. When not reading tales of high adventure, he is often telling such stories to all who will listen.

Related Post

Leave a Reply