In this tutorial, you'll learn how to define custom objects using Twine data maps.

Your story is starting to grow complex. What started as a simple choose your own adventure story now has a difficulty setting and a homegrown inventory system.

Alas, the difficulty setting doesn’t work (just yet) and the inventory system only works with one passage. It’d be nice for the inventory system to work with every passage.

For this to work, it’s time to meet data maps.

Meet the Data Map

Data maps are an incredibly useful tool for creating interactive fiction, but they are very scary sounding. Believe me, they aren’t scary at all. You use them all the time.

Have you ever used a dictionary? Congrats! You’ve used a data map. Ever read a table of contents? You used a data map. Data maps are everywhere but in Harlowe, they have a fancy name.

A dictionary is the best example of a data map. It contains two important pieces of information: a key and a value. In the case of the dictionary, the key is the word you are looking up. The value is the definition of that word.

In the case of a dictionary, the key is text and the results are text. Sometimes, the keys and values may be different types. For example, you may look up the baseball standings using the team name. The key is a string and the value is a number.

Looking up the team of Boston returns a value of 55.

Creating a Data Map

Oftentimes, your objects will have lots of different properties such as weight, name, description, and other things.

At this point, it is time to put your knowledge of data maps to use. You’ll use your data maps to define your objects. In your case, you’ll define a name, a description, and an id for each object.

Why an id? Oftentimes, it’s just easier working with numbers. It’s far easier to make a typo when working with text.

Now you can use separate variables for each object property but it is far better to bundle all of those properties into a single data map.

You create a data map by using the (dm:) macro. Inside the data map, you add your keys and values. Here’s an example of an item.

(dm: "name", "Sword of Eros")

This creates a data map with a name key. The value is “Sword of Eros”. Alas, the data map isn’t stored anywhere. You need to save it in a variable.

(set: $sword to (dm: "name", "Sword of Eros"))

There creates a new data map and assigns it to the sword variable. To access it, you simply refer to the data map’s key like so:

(print: $sword's name)

Now to put this to use.

Creating car keys

To get started, open up your Twine story in progress, or you can download the starter story for this tutorial.

You’re going to create a new set of keys. This data map will contain three values. One value is for the id. The next value is for the name. The final value is the description.

Open the Startup passage. Currently, there are two variables being set in it. This is a good place to define your car keys objects.

Underneath the code, define a new variable to the following.

(set $carKeys to (dm: ))

In your story, you will be using a variety of objects. You already have been using a set of keys. You’ll also be using a pot of chili, a gallon of gas, and some other objects.

You’ve created an empty data map and assigned to the keys variable. Now to add the keys and values.

(set: $carKeys to (dm:
  "id", 1,
  "name", "keys",
  "description", "These look like Bernie's keys to his pickup.",

It should look like the following:

Here you’ve defined an object containing the three properties. Notice, that each property was defined on its own line. This makes it easier to understand the data map at a glance.

All that you need to do is add your keys to your story.

Describing your keys

Now that you defined your car keys, it’s time to put them to use. Open up the keys passage. Now, we can refer to the key’s description instead of printing it out.

Remove the first line and replace it with the description.

(print: $carKeys's description)

It should look like the following:

Now run the story, and you’ll see that when you select the keys, you see the description, except this time, it’s stored in a data map.

Picking up the keys

Right now, you are storing all the information about your keys in a single data map. This is convenient because you now store it in an array. In an earlier tutorial, you used an array just to store the object’s name. Now, you’ll store the object itself.

This will seem like a minor upgrade, but in the next tutorial, you’ll turbocharge your inventory by using just data maps and arrays. For now, you’ll take it one step at a time.

Open up the pickup passage. In the first line, you set the keys to the inventory. Change it to the following:

(set: $inventory to $inventory + (a: $carKeys))

It should look like the following:

Now, you need to update the actual inventory checking logic. Open up the Camp Entrance passage. Update the inventory to the following:

(if: $inventory does not contain $carKeys) [
  <br>On the ground, you see a set of [[keys]].<br>

It should look like the following:

The code works exactly as before, except this time, you are seeing if the array contains a data map versus a plain old string.

Play the story and you should be able to examine and pick up the keys. Nice work!

Where to Go From Here?

Congrats on making it this far. You’ve gone ahead and added some complexity to your story. Yet the complexity doesn’t improve your story in any way. At least, not yet.

In the next tutorial, you’ll take your story to the next level by creating a fully complete inventory system that not only works with a variety of different objects but works in every passage without you having to copy and paste everything.

So take a break, and catch me in the next tutorial.

Leave a Reply