A Tale of Two Languages

by Daniel Bartholomew

As soon as the interactive fiction (or text adventure) genre got started with the arrival of Will Crowther's Advent in 1975, people have been working on ways to make creating it easier.

The original Advent was programmed in FORTRAN. The expanded version, created by Don Woods, used PL/1. Both of these languages are general-purpose computer languages well suited for many tasks, but not particularly suited for creating interactive fiction. Many of the early fans of Advent wanted to create their own version of the game, and using FORTRAN or PL/1 was difficult to impossible, depending on the computer platform to which they were porting it.

One thing many of these early implementers realized about interactive fiction was that most of it was just text, and that the operating system-specific parts of a game amounted to only about 10% or less of the overall size. The solution many arrived at was to put all the operating system-independent text and logic into a story file and then create an interpreter or virtual machine that could play or run the story file. These story files first were written in a custom language designed for creating adventure games and then compiled into the proper format. This method allowed Zork, the most popular and commercially successful Advent-like game, to be available for 23 different platforms, a testament to the power of “virtualization” decades before it became a hot buzzword.

Infocom, like all the commercial publishers, had its own language. Infocom's language was called ZIL (for Zork Implementation Language). It was not public and had to be compiled on a mainframe. When compiled, it would run inside the Z-Machine (Zork-Machine). Ports of the Z-Machine were built for every platform Infocom supported. The ZIL language was powerful and had lots of features, but its proprietary nature, and the fact that a mainframe was required for compilation, put it out of the reach of hobbyists, so the community created its own languages. Six/Fant, DDL (Dungeon Definition Language), ADL (Adventure Definition Language), TADS (Text Adventure Development System), AGT, Hugo and others were created, enabling anyone to write interactive fiction.

Throughout Infocom's short lifetime, several versions of the Z-Machine were created. These versions differed in the complexity of the story files that they would support. For example, version 3 of the Z-Machine supports up to 255 objects, 32 attributes and a maximum story file size of 128K. Version 5 of the Z-Machine could handle up to 65,535 objects, 48 attributes and a maximum story file size of 256K. Version 8 of the Z-Machine is identical to version 5, with the added feature of supporting story files up to 512K in size. Version 5 was the one used by Infocom for most of its advanced games.

By the early 1990s, all the commercial publishers had gone out of business, so if you wanted to play a new piece of interactive fiction, you either had to write it yourself or hang out on the newsgroups dedicated to interactive fiction. The classic games from Infocom and others still could be found on various re-releases and Collector's Editions. The interactive fiction genre wasn't dead, but many consider the period between 1989 and the mid-1990s to be the “dark ages”.

Despite progress, the Infocom games still were seen as the high watermark in interactive fiction, and creators had a hard time approaching them with the various community-developed systems. They just weren't powerful enough or were missing important features or were lacking a decent parser or all of the above.

It wasn't until after Graham Nelson successfully reverse-engineered the Z-Machine, and created a language and compiler that would produce story files compatible with any interpreter, that supported version 5 (and 6 and 8) of the Z-Machine, that the second golden age of interactive fiction began. He called his creation Inform, and he based the design of the language on ZIL.

Speaking of ZIL, here is a simple example:


<OBJECT SERVER
        (LOC SERVER-ROOM)
        (DESC "an ancient server")
        (FLAGS NODESC)
        (SYNONYM SERVER COMPUTER MACHINE ANCIENT OLD)>

Basically, when creating something in ZIL, you have objects, and those objects have properties and attributes. This format proved itself to be very flexible for Infocom's games, and the language was modified and improved as new versions of the Z-Machine were developed.

Inform has followed a similar path. Like the Z-Machine with which it is designed to be compatible, the Inform language has gone through several refinements over the years. The current versions of Inform are 6 and 7. Of the two, version 6 of Inform is very similar to ZIL. Here is a ZIL example in Inform 6:

Object server "server" server_room
    with
        description "an ancient server",
        name 'server' 'machine' 'computer' 'ancient' 'old',
    has scenery;

Everything is still an object, and most of the differences between them (at least in the example above) are in matters of naming. FLAGS has been renamed to has, SYNONYM has been renamed to name, NODESC has been renamed to scenery and so on. That's not to say that there aren't substantial differences—there are. Probably the main difference at this point is that Inform 6 can create far larger and more complex games than any of the ones Infocom created with ZIL.

However, even with a powerful and refined language at their fingertips, many of the top interactive fiction writers—including Graham Nelson, Emily Short, Andrew Plotkin, Sonja Kesserich and others—felt that writing interactive fiction in Inform 6 was not natural enough. Writing in Inform 6 feels like programming; there's no way around it. The flippant retort to such a statement is, “Well, yeah. You're creating a computer game. What did you expect?” Their response was that creating interactive fiction should be more like creating regular “non-interactive” fiction.

How radically different is Inform 7 from Inform 6? Well, here's the same example from above in Inform 7:

The ancient server is scenery in the server room. Understand 
"machine" and "computer" and "old" as the ancient server. 
The description of the ancient server is "an ancient server".

So, instead of statements, we have natural language paragraphs. However, while Inform 7 was in the planning stages, the decision was made that even though it was going in a radically new direction, it should still be built on top of Inform 6. What Inform 7 does behind the scenes during compilation is to parse what you write and translate it into Inform 6. The translation is done by machine, so it doesn't look like what a human would write, but it is valid Inform 6 and can be compiled by the regular Inform compiler. This allowed developers to focus on the design of the language instead of the design of a brand-new compiler.

To illustrate the differences between Inform 6 and Inform 7 I've created an example game in both languages. Due to space constraints, we can't print the full games here, but they are available on our FTP site at ftp.linuxjournal.com/pub/lj/issue174/10130.tgz.

The compiled version of each game also can be downloaded from the Linux Journal FTP site (available at the same address listed above). Even though the source code is very different, they both play the same.

As I refer to the two programs, I will use the Inform version (i6 or i7), followed by a colon (:) and the line number(s). So, if I refer to the Inform 7 version of the cd-tray object, I would write it as i7:094-095 (Listing 1).

Listing 1. Describing a CD Tray in Inform 7

094  The CD Tray is part of the old server.
095      The description is "It's a CD tray."

The differences between the two languages are apparent from the first lines. When starting a story in Inform 6, there are some essential housekeeping duties that need to be done at the beginning (i6:001-007) and end (i6:172-193) in order for the story to compile (Listing 2).

Listing 2. Essential Code for Compiling Inform 6

001  !% -SD
002  
003  !========================================================
004  Constant Story "The Server Room";
005  Constant Headline
006      "^An Interactive Fiction by Daniel Bartholomew.^";
007  Release 1; Serial "080625"; !for keeping track of releases
.
.
172  !========================================================
173  ! Entry point routines
174  
175  [ Initialise;
176      location = break_room;
177      "^^^^It's Saturday, a nice one at that, and you've been
178          called to fix a server. Again.^^You've had it. This
179          server is going to run Linux starting today! The process
180          will be easy, just put the disc into the server go.
181          Now where is that Ubuntu CD?^";
182  ];
183  
184  [ Deathmessage;
185      if (deadflag == 5) print "You have won";
186  ];
187  
188  !========================================================
189  ! Standard and Extended Grammar
190  
191  Include "Grammar";
192  
193  !========================================================

In Inform 7, the only thing that is absolutely required is the first line (i7:001). To be fair, the initialization routine in Inform 6 also includes the message that is displayed at the beginning of the game. In Inform 7 this also is there (i7:007-011), but it's not required for successful compilation (Listing 3).

Listing 3. Initial Program Code for Inform 7

001  "The Server Room" by "Daniel Bartholomew"
002  
003  Include GNU GPL v3 by Free Software Foundation.
004  
005  The maximum score is 6.
006
007  When play begins, say "It's Saturday, a nice one at that,
008      and you've been called to fix a server. Again.
009      [paragraph break]You've had it. This server is going to
010      run Linux starting today! The process will be easy, just put
011      the disk in the server and go. Now where is that Ubuntu CD?"

The defining of variables is similar in both versions—for instance, the maximum score variable (i6:009, i7:005). The main difference is that the Inform 6 version uses C-like syntax:

Constant MAX_SCORE = 6;

And, Inform 7 uses a sentence that reads similarly to how one would read the Inform 6 version out loud:

The maximum score is 6.

Some of the differences between versions are similarly minor. One example is the method of inserting paragraph breaks into long sections of text, such as in the description of the Server Room (i6:114-118, i7:082-086, Listing 4). In Inform 6, two carat symbols (^^) are used, and in Inform 7, the statement paragraph break enclosed in square brackets ([]) does the job.

Listing 4. Syntax for Describing a Room

Inform 6 Version:
114  description "The fans, the lights, the chill... yep, it's a
115      server room. Full of servers from a dozen vendors,
116      each with their own quirks.^^Your attention is
117      immediately drawn to a server 2/3 of the way up rack 7.
118      The indicator light is blinking red and beeping.",

Inform 7 Version:
082  The Server Room is a room. "The fans, the lights, the chill...
083      yep it's a server room. Full of servers from a dozen
084      vendors, each with their own quirks.[paragraph break]Your
085      attention is immediately drawn to a server 2/3 of the way up
086      rack 7.  The indicator light is blinking red and beeping."

One big mistake I made when I started was creating everything first in Inform 7, and then creating the equivalent Inform 6 code. This proved tricky on a couple occasions—most notably with the random beeping messages that appear at every turn while you are in the server room (until you fix the server and win the game). Programming such logic is very different in each version. In Inform 7, writing this took almost no thought at all (i7:097-103). Basically, I described what I wanted to happen every turn, and Inform 7 made it happen. The Inform 6 code to do the same thing is not as advanced (i6:120-134). It's basically a case statement, but it's significantly more difficult to write in comparison (Listing 5).

Listing 5. Programming Game Logic

Inform 6 Version:
120  daemon [;
121      if (location ~= server_room) return;
122      beeping = random(7);
123      switch (beeping) {
124          1: "^The beeping is driving you crazy.";
125          2: "^It's hard to think, with all of the beeping.";
126          3: "^The monotony of the beeping is maddening.";
127          4: "^You can't stand the beeping.";
128          5: "^The beeping reminds you of your alarm clock.";
129          6: "^beep . . . beep . . . beep . . . beep . . . beep
130               . . . beep . . .";
130          7: "^If you don't stop the beeping soon, you'll lose
132               what little hair you have left.";
133      }
134  ],

Inform 7 Version:
097  Every turn while in the server room, say "[one of]The beeping is
098      driving you crazy.[or]It's hard to think, with all of the
099      beeping.[or]The monotony of the beeping is maddening.[or]You
100      can't stand the beeping.[or]The beeping reminds you of your
101      alarm clock.[or]beep . . . beep . . . beep . . . beep . . .
102      [or]If you don't stop the beeping soon, you'll lose what
103      little hair you have left.[purely at random]"

Scoring is another thing that Inform 7 simplifies. In Inform 6, you can give an object the scored attribute, but for custom cases, like awarding 2 points instead of the default 1 point, you need to track things yourself (i6:150-156). In Inform 7, the process is much easier (i7:105-106, Listing 6).

Listing 6. Syntax for Scoring

Inform 6 Version:
150      before [;
151          Open:
152              if (openedtray == 1) {
153                  score = score + 2;
154                  openedtray = 2;
155              }
156      ],

Inform 7 Version:
105  After opening the CD tray for the first time: award 2 points;
106      say "You press the button and the CD tray pops out."

So, which version is best? If I had to choose my favorite of the two, it would be Inform 7, hands down.

I prefer Inform 7 not because I find Inform 6 difficult to use or because it's an unpleasant experience. On the contrary—Inform 6 is well designed and has excellent documentation for both beginners and advanced users. It also has some clear advantages—a main one being precision. Inform 6 will do exactly what you tell it to do. Inform 7, on the other hand, is less precise, and you sometimes need to fiddle with it to get it to do exactly what you want. This lack of precision is a result of how Inform 7 translates your code into Inform 6 prior to compilation—it has to guess at what you mean sometimes, and occasionally, it will get things wrong.

Despite some disadvantages, the reason that I prefer Inform 7 over Inform 6 is because I am more of a writer than a programmer. The closest I get to programming on a regular basis is bash scripting with a little PHP thrown in now and again. The natural sentence structure of writing something in Inform 7 is more intuitive to me than the C-like syntax of Inform 6. As a writer, I sometimes think to myself, “If when reading code I pronounce 'somevar=42' as 'somevar gets 42', why can't I write it that way?” I realize and accept that computer languages are as terse and precise as they are for many reasons, but I also think efforts like Inform 7 should be applauded and copied wherever and whenever possible.

The precision of Inform 6, as with other programming languages, is good in some instances, but bad in others. One misplaced comma or semicolon or bracket prevents your game from compiling, for example. Inform 7 is not exactly forgiving in this area either, but I find myself making fewer mistakes because of the flexible and natural way you're allowed to write.

Another big advantage of Inform 7 is the wonderful integrated IDE that comes with it, complete with excellent built-in documentation, a debugger and other tools. With Inform 6, compilation was a command-line affair that could be difficult to set up properly. I won't go into the Inform 7 IDE here, but if you are interested, see the two-part series “An Introduction to Gnome Inform 7” on the Linux Journal Web site.

With Inform 7, there's never been a better, or easier, time to create your own interactive masterpieces. So, find the key to the grate, and join me down underground. I'll be in a maze of twisty little passages, all alike, trying to find the bearded pirate who stole my gold—if the dwarf doesn't kill me first. XYZZY!

Resources

Example Games: ftp.linuxjournal.com/pub/lj/listings/issue174/10130.tgz

An Introduction to Gnome Inform 7, Part 1: www.linuxjournal.com/content/introduction-gnome-inform7-part-1

An Introduction to Gnome Inform-7, Part 2: www.linuxjournal.com/content/introduction-gnome-inform7-part-2

Inform 6: www.inform-fiction.org/inform6.html

Inform 7: www.inform-fiction.org/I7/Welcome.html

Frotz: frotz.homeunix.org/frotz

Zoom: www.logicalshift.co.uk/unix/zoom

Fortran: en.wikipedia.org/wiki/Fortran

PL/1: en.wikipedia.org/wiki/PL/I

ADL: adl.sourceforge.net

Six/Fant: www.graysage.com/cg/Compilers/SixFant

TADS: www.tads.org

AGT: www.markwelch.com/agt.htm

Hugo: www.generalcoffee.com/hugo.html

The Interactive Fiction Archive: www.ifarchive.org

Baf's Guide to the IF Archive: wurb.com/if

A Beginner's Guide to Playing Interactive Fiction: www.microheaven.com/IFGuide

Daniel Bartholomew has been a fan of interactive fiction since he first was exposed to it on his Apple IIe many, many years ago. He lives with his wife and children in North Carolina.

Load Disqus comments