09/10/2016

Interactive Fiction with Inform 7

I like the idea of writing Interactive Fiction. If you're here, chances are that you do, too.

Today, there are many options for writing parser-based IF. I'm a C++ programmer by trade, but perhaps surprisingly, my tool of choice isn't the C-like TADS 3. Instead, I decided to learn Inform 7, where the code you write is essentially English.

This won't be an I7 tutorial. Several excellent ones already exist online, and there's also a book on the subject. Instead, I thought I'd list a few techniques that make I7 writing easier.

When a phrase might yield "nothing", always make it an object

It's a common pattern: you write a bit of code to pick out a specific object according to certain criteria. The problem is, sometimes there is no valid result. In that case, you want "nothing."

Your bedroom is a room. The house door is a door. It is west from the bedroom and east from the Garden. The house door is locked. The key is here. The key unlocks the house door.
The Lodestone Room is west of the Garden. 

The player carries the brass compass. The description of the brass compass is "The dial points quiveringly to the [magnetic direction]." 

To decide which direction is magnetic direction:
 decide on the best route from the location to the Lodestone Room, using even locked doors.

There's a problem here. When we reach the lodestone room, the compass will generate a runtime error, because nothing is of the wrong type: not a direction, but an object.

This is easy enough to fix: just make the return type of the phrase into an object.

Your bedroom is a room. The house door is a door. It is west from the bedroom and east from the Garden. The house door is locked. The key is here. The key unlocks the house door.
The Lodestone Room is west of the Garden. 

The player carries the brass compass. The description of the brass compass is "The dial [if the magnetic direction is nothing]spins and spins, not settling on any direction[otherwise]points quiveringly to the [magnetic direction][end if]." 

To decide which object is magnetic direction:
 decide on the best route from the location to the Lodestone Room, using even locked doors.
Of course, there are phrases that should never yield nothing. For such phrases, it's prudent to retain as much type information as possible.

On changing the auto-generated prose text for supporters

One of my pet peeves in Inform 7 comes up when I want to describe a room containing a supporter. When the supporter is empty, it's okay. The problem comes when the supporter holds something.
Moldavian Grouse
A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead.

You can see a bar (on which is a shot of fine whiskey) here.

>x bar
As old and sturdy as a fallen oak. 
On the bar is a shot of fine whiskey.
There are several interrelated and unrelated issues at play here. The first is the parenthesized part after mentioning the bar. In this case, that issue easily resolved by giving the bar an initial appearance. While that won't work for a portable supporter, it does us nicely here:

The Moldavian Grouse is a room. The printed name is "The Moldavian Grouse".

The description is "A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead."

The bar is a fixed in place supporter in the Moldavian Grouse. "In the center of the room is a large, old-fashioned bar." The description of the bar is "As old and sturdy as a fallen oak." On the bar is a shot of fine whiskey.
This raises a different problem, though: now there's a tacked-on message below the bar's initial appearance, saying "On the bar is a shot of fine whiskey." How do we change that?

The Moldavian Grouse is a room. The printed name is "The Moldavian Grouse".

The description is "A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead."
The bar is a fixed in place supporter in the Moldavian Grouse. "In the center of the room is a large, old-fashioned bar[if something is on the bar], [a list of things on the bar] atop it[end if]." The description of the bar is "As old and sturdy as a fallen oak." On the bar is a shot of fine whiskey.

Interestingly, that kills the supplementary "On the bar..." message!

There's no magic to it, though. What happens is that, by printing a list of things during the room description, Inform correctly deduces that we've mentioned them. A mentioned thing is not listed again (in fact, when it automatically enumerates things in the room, that Activity is actually named "listing unmentioned things").

However, there's still one remaining problem, the generic listing of items upon the supporter. Unlike the case with room description, that listing is not suppressed by mentioning the item beforehand. What's at work here is the examine supporters rule, which looks like this:

Carry out examining (this is the examine supporters rule):
 if the noun is a supporter:
  if something described which is not scenery is on the noun and something which is not the player is on the noun:
   say "On [the noun] " (A);
   list the contents of the noun, as a sentence, tersely, not listing concealed items, prefacing with is/are, including contents, giving brief inventory information;
   say ".";
   now examine text printed is true.

That rule is easy enough to turn off, like so:

The Moldavian Grouse is a room. The printed name is "The Moldavian Grouse".

The description is "A grimy, dimly lit room. The air is heavy with cigarette smoke, lazily churned by the ceiling fans overhead."

The bar is a fixed in place supporter in the Moldavian Grouse. "In the center of the room is a large, old-fashioned bar[if something is on the bar], [a list of things on the bar] atop it[end if]." The description of the bar is "As old and sturdy as a fallen oak[if there is something on the bar], holding [the list of things on the bar][end if]." On the bar is a shot of fine whiskey.

The examine supporters rule does nothing when examining the bar.

Of course, this also lists scenery items, and it would also list the player should the player be on the bar. In this instance though, the above is perfectly adequate.

The going action allows two prepositions, both useful

This one is short and sweet. Not too long ago, I was told of a particular turn of phrase with useful properties. This is about the going action. Consider the following:

The Shadowy Forest is a room. "Gloomy pine trees surround you in the gathering mist. The haze makes it difficult to see clearly, although you can just about make out a sloping trail to the west."
The Brook Clearing is west of the Forest. "A merry brook winds its way through the turf here."

Instead of going nowhere, say "You'd just get lost."
Instead of going up in location, say "There's no way you could climb, given your back problems."

How does this work? Well, there are a few prepositions bound to the going action. First, it's "going [direction] from" and "going [direction] to". These refer to the action of going a valid direction. Then, there's "going nowhere", which refers to going (but failing to go) in any invalid direction.

Both of these wholly depend on whether the direction is valid or not. But sometimes, you don't want to do that; sometimes, you want to intercept the mere attempt to go in a given direction (no matter if it's a valid one or no). For that purpose, you can use the "going [direction] in" construction.



That concludes my first Inform 7 piece. Thank you for reading. Although I hope this post was useful, it may need improvement, and any feedback you could give would be much appreciated.