hoowl

Physicist, Emacser, Digitales Spielkind

Getting started writing interactive fiction with Inform7 on the command line
Published on Apr 30, 2022.

Although I have fond memories of playing the text adventure Hexuma (and some similar titles) in the 90s, I only started to get interested in interactive fiction as a story-telling medium a little while ago. I really enjoy short stories and the way they create entire worlds for the purpose of a short-lived, pointed narrative. And interactive fiction can add a whole explorative dimension to story telling. At least in principle, the barrier of entry for new IF authors is relatively low, at least compared to many other types of games.

There exist a large variety of languages to create IF in and the choice of language will influence what type of story or interactivity what can hope to achieve. Inform is one of the more flexible ones but also intriguing as it draws from ideas in literal programming and linguistics.

As Inform has recently been released as free and open software, I was eager to try it out on my reform2 laptop which runs Debian GNU/Linux on an NXP i.MX8MQ processor with 4x ARM Cortex-A53 cores. To my pleasant surprise, it worked right out of the box!

The instructions below are for Inform version 10.1.0 released on April 28th 2022 and are using the command-line interface (CLI) only. If that is not your cup of tea, there are also various graphical development environments out there, for example inform7-ide.

Installing Inform

The instructions below are the summary of what is provided on Inform’s git repository pages. You will likely need the typical prerequisites for compiling code packaged for your flavor of distribution, e.g. build-essential on Debian-based systems1. On my system, I already had everything installed that Inform needed. If you run into errors during the build process, you might have to look into missing dependencies.

To build Inform, we also need Inweb and Intest. Both are installed in similar fashion:

1: git clone https://github.com/ganelson/inweb.git
2: bash inweb/scripts/first.sh linux
3: inweb/Tangled/inweb -help
4: git clone https://github.com/ganelson/intest.git
5: bash intest/scripts/first.sh

The call to inweb on line 3 is just to test the compilation – if everything worked, you should see the help message of the Inweb CLI.

Once these two are in place, we can install Inform itself:

1: git clone https://github.com/ganelson/inform.git
2: cd inform/
3: bash scripts/first.sh
4: inblorb/Tangled/inblorb -help
5: ../intest/Tangled/intest inform7 -show Acidity

Again, the last lines are only for testing the installation. If everything went smoothly, we are ready to create our first project!

The Story’s source code

Let’s use one of the examples from the Inform documentation: A pot of petunias!

"Pot of Petunias"

Wide Open Field is a room. "A big field under a big sky. The clouds are puffy, the trees are handsome."

Some clouds and some trees are scenery in Wide Open Field. The description of the clouds is "That one looks like Yoda's head." The description of the trees is "You've never been much good at botany, so it's anyone's guess what kind they are."

A rock is in Wide Open Field. The description of the rock is "It looks like it's been here from the dawn of time."

The broken flower pot is a thing. The description of the broken flower pot is "It contains the remains of some abused petunias."

At 9:01 am:
    move the broken flower pot to the location;
    say "Quite unexpectedly, a flower pot falls from the sky and breaks open on the ground. Good thing you weren't standing six inches to the left.";
    set pronouns from the broken flower pot.

Test me with "x it / x it / x it".

Inform uses projects to store each story, its resources and build files in. In the following, I create the simple directory structure for the first project and set up some environmental variables to make it easier to adjust paths and such:

GAME_PROJECT="petunias"
GAME_PROJECT_DIR="$HOME/src/$GAME_PROJECT"

mkdir -p "$GAME_PROJECT_DIR/Source"

This creates a directory ~/src/petunias with a subfolder Source. Save the above story into a file story.ni in the Source folder.

Please note: If you want to use the project with a graphical user interface such as inform7-ide you should choose a project folder ending in .inform, for example petunias.inform, as this is the typical format expected by Inform IDEs. Inform itself, however, does not care.

As a last detail, each project should have a unique identifier. Create one using the uuid utility2 (or use a python one-liner3) and store it in ~/src/petunias/uuid.txt:

UUID="$(uuid)"
echo -n $UUID > "$GAME_PROJECT_DIR/uuid.txt"
echo $UUID

03f452f8-c955-11ec-bd44-0019b808dd97

When editing manually, be sure that the uuid.txt file does not end in a line break or some parsers will break when reading the file!

Compiling our story

Now we are ready to compile our story using Inform. The compilation will in fact consist of two steps: first, inform7 will translate the story’s source into Inform6 code. Then inform6 will be used to compile into one of the standard virtual machine codes used in interactive fiction: Glulx or Z-machine. The choice depends on which interpreter you (or your players) want to use.

This post is rather brief; a lot more details can be found in this very thorough description of the process on the interactive fiction forum. Despite some of the information there being slightly outdated, you will learn a lot about the different formats and options of the process reading it!

For convenience and slightly shorter commands, I define a variable to keep the path to the Inform source code:

ISRC="$HOME/src/inform"

Now compile the project with inform7:

"$ISRC/inform7/Tangled/inform7" -no-progress -external "$HOME/Inform" -project "$GAME_PROJECT_DIR/"
Inform 7 v10.1.0 has started.
I've now read your source text, which is 170 words long.
I've also read Basic Inform by Graham Nelson, which is 7691 words long.
I've also read English Language by Graham Nelson, which is 2328 words long.
I've also read Standard Rules by Graham Nelson, which is 32130 words long.

  The 170-word source text has successfully been translated. There were 1 room
    and 5 things.
Inform 7 has finished.

The -external switch is optional. The directory specified here is the default for additional external extensions and is it being created automatically when running Inform on a project (as we just did). If you’d rather see extensions stored elsewhere, simply adjust that path.

For a release version, add the -release switch. You can also add -debug for additional debugging features. For a full list of CLI options, run

"$ISRC/inform7/Tangled/inform7" --help

Check out the project’s folder: inform7 has just generated a bunch of files and folders.

Next step is the compilation of the just generated Inform6 code to (gl)ulx:

"$ISRC/inform6/Tangled/inform6" -E2wSDG "$GAME_PROJECT_DIR/Build/auto.inf" "$GAME_PROJECT_DIR/Build/output.ulx"
Inform 6.36 for Linux (24th January 2022)
In:  1 source code files             94387 syntactic lines
 81099 textual lines               2394870 characters (ISO 8859-1 Latin1)
Allocated:
  8818 symbols                     2885088 bytes of memory
Out:   Glulx story file 1.220501 (665K long):
    20 classes                          42 objects
   232 global vars                   86156 variable/array space
    96 verbs                           322 dictionary entries
   179 grammar lines (version 2)       251 grammar tokens (unlimited)
   101 actions                          37 attributes (maximum 56)
    39 common props (maximum 253)       18 individual props (unlimited)
133667 characters used in text      104309 bytes compressed (rate 0.780)
     0 abbreviations (maximum 64)     3230 routines (unlimited)
 81298 instructions of code          45940 sequence points
110080 bytes writable memory used   570368 bytes read-only memory used
680448 bytes used in machine    1073061376 bytes free in machine
Compiled with 3236 suppressed warnings
Completed in 2.00 seconds

The format is specified through the command line switches -E2wSDG; Change these to -E2w~S~DG for release version where debugging and strict testing is explicitly disabled (through the ~ character). Replacing G with v8 would compile to z8 instead for glulx. For a full list of options, run inform6 with --help or -h2 for general help or a compilation switch overview, respectively.

This created the file $GAME_PROJECT_DIR/Build/output.ulx. The next and final step is to package everything up into a standard IF game file.

Packaging the game

Now it is time to combine the compiled game, meta information and potential media assets into one game file that can be easily distributed. The process is controlled by the file $GAME_PROJECT_DIR/Release.blurb and performed by inblorb which is part of the inform7 installation.

"$ISRC/inblorb/Tangled/inblorb" "$GAME_PROJECT_DIR/Release.blurb" "$GAME_PROJECT_DIR/Build/output.gblorb"
cp "$GAME_PROJECT_DIR/Build/output.gblorb" "$GAME_PROJECT_DIR/Release/Pot of Petunias.gblorb"
! inblorb 4 [executing on Sunday 1 May 2022 at 16:11.45]
! The blorb spell (safely protect a small object as though in a strong box).
Copy blorb to: [[/home/hanno/src/petunias/Release/Pot of Petunias.gblorb]]
! Completed: wrote blorb file with 1 picture(s), 0 sound(s)

Playing the game!

Now it is finally time to play the game using your favorite interpreter! For example,

glulxe "$GAME_PROJECT_DIR/Release/Pot of Petunias.gblorb"
 Wide Open Field
──────────────────────────────────────────────────────


Pot of Petunias
An Interactive Fiction
Release 1 / Serial number 220501 / Inform 7 v10.1.0 / D

Wide Open Field
A big field under a big sky. The clouds are puffy, the trees are handsome.

You can see a rock here.

>

Have fun and happy hacking!

Tags: if, inform7

Footnotes:

1

Install via sudo apt install build-essential

2

If not installed, install via sudo apt install uuid

3

Using the build-in uuid library as suggested by libele (thanks!): python3 -c "import uuid;print(str(uuid.uuid4()).upper())"