No, It’s Not Easy

Writing text adventure games is not easy. It’s a craft that combines conventional writing with both computer programming and game design. It’s kind of a niche art form, but people are still actively engaged in it. I’m one of them.

The most successful authoring system used for this endeavor is Inform 7. One of the reasons for Inform’s success is that it attempts, very much by design, to disguise the fact that you’re engaged in computer programming. The computer code in I7 looks exactly like writing in plain English. The novice author looks at I7 and thinks, “Oh, this is easy!” Yes, at first it is easy. And by the time it stops being easy, you’re hooked. You’ve invested a fair amount of time in getting started as an Inform author, so you plow on ahead.

The trouble is, Inform is not actually a very good authoring system. I’ve written a couple of games in Inform, so I’m entitled to say this. The TADS 3 authoring system, especially when one uses Eric Eve’s adv3Lite library rather than the default adv3 library, is actually much better.

Why, then, isn’t T3 more popular? The main reason is, it scares the novice author because what you’re doing is not disguised as writing in plain English. You’re writing computer code, and no foolin’. Here’s a more or less typical in-game object, as coded up in T3:

rawChow: Thing 'pterodactyl chow; brown brownish meaty; odor chunks of[prep]'
    "The brownish chunks of pterodactyl chow have a meaty odor. "
    dobjFor(Take) {
        check() {
        "Your husband and children would find it not very palatable. ";
    dobjFor(Eat) {
        preCond = [touchObj]
        verify() { logical; }
        check() {
            "Seriously? Yuck! ";

In order to make sense of this, you have to actually learn something about how TADS 3 code is organized. I’m not going to try to explain it all, but it’s less mysterious than it may look at first glance. The mysterious “dobjFor.” for instance, means “direct object for.” When the player types “eat chow,” the pterodactyl chow is the direct object. The library grabs the code in this object’s dobjFor(Eat), since the Eat action is what the player is attempting. The verify() routine confirms that, yes, the chow is something the player might reasonably ask to eat, but then the check() routine refuses the action with a message indicating why that ain’t gonna happen.

If you’re willing to learn six or eight fairly simple ideas along these lines, writing a simple game in TADS 3 is as easy as writing it in Inform 7. And when you start trying to do more complex things, using T3 is actually a lot easier than groping through the baffling depths of Inform. The guts of Inform, the library (which is called the Standard Rules) is quite opaque. Figuring out what the library is doing is an exercise in patience. Whereas, on the other hand, the T3 library (whether you’re using adv3 or adv3Lite) is written in the same type of code you’re already writing, and also it’s exhaustively commented with explanations of what’s going on, so figuring out what’s what is — well, it’s not always simple, but there are no roadblocks.

For comparison, let’s look at that same in-game object as it would be written in Inform:

The pterodactyl chow is an edible thing. The description is "The brownish chunks of pterodactyl chow have a meaty odor." Understand "brown", "brownish", "meaty", "chunks", and "odor" as the pterodactyl chow.

Instead of taking the pterodactyl chow:
    say "Your husband and children would find it not very palatable."

Instead of eating the pterodactyl chow:
    say "Seriously? Yuck!"

Is that easier for the novice programmer to read? You betcha. Everything that’s not in italics is computer code, but it’s disguised to look like it’s not. And there’s a hidden problem. Inform has silently created an object whose code name is “pterodactyl chow”. And the game is likely also to contain two other objects — a bag containing the chow, and a pterodactyl. Because Inform takes a wild guess about how to name an object in its own internal code, it’s liable to get quite confused when you add the other objects. This cannot happen in TADS, because the object name (in this case, rawChow) is specified by the game author, and must always be unique. The TADS compiler cannot ever be confused about which object is which, but the Inform compiler is quite likely to get confused. There’s a workaround in Inform that allows the author to avoid this problem — but why should a workaround be needed in order to help the compiler deal with something as basic as the fact that you’ve just defined a unique in-game object?

Another reason why authors like Inform is that the IDE (integrated development environment) in which you do your writing is really good. Also, it’s cross-platform. The TADS Workbench is a Windows-only program, and frankly it’s not as sexy-looking as the Inform IDE. You can actually write TADS games on the Mac, and I’ve just discovered a very adequate front end for authoring that uses the VS Code environment with a TADS extension. It’s not Workbench, but it’s good.

When you’ve written some new bits and want to test them, you need to compile your game. TADS compiles much faster than Inform, and you’ll be doing this 30 times a day, so this is a factor. An Inform game has to be written in one long, long wodge of code, but TADS games can be (and should be) written in the form of several shorter files. This makes finding what you need to edit much easier in TADS.

You’ll notice that those two Instead rules in Inform are written as separate paragraphs. The Inform author can put those two rules pretty much anywhere in the code file, without causing any problems. This appears at first glance to be a convenience, because if you think of something you forgot to write, you can just add it near the stuff you’re editing right now. But in fact it’s an open invitation to chaotic, confused code. The TADS dobjFor blocks pretty much have to be embedded within the definition of the object. (You can, in fact, put them elsewhere using the ‘modify’ keyword, but that’s an extra step that nobody would ever take.) TADS code is natively more tidy, and that makes it easier to read, once you understand the syntax. Also, the indentation in the TADS code is purely for visual convenience: You can indent or not indent. The indentation in Inform is required, unless you use an alternative syntax that’s fairly messy. Wrong indentation in Inform causes the compiler to choke on its Wheaties.

And then there’s the infamous paragraph break problem. Inform’s game output will occasionally get confused and either put too much vertical white space between its output lines, or not enough space. This has been a problem with Inform for more than 20 years, and while it’s better than it used to be, it still crops up occasionally. This never happens in TADS games. If there’s a spacing problem in TADS, it’s guaranteed to be due to something you did, and you can fix it.

Inform provides some nice conceptual tools with which to organize your game — things like map regions and ongoing dramatic scenes. So Eric cribbed those good ideas and installed them in his adv3Lite library for TADS. That being the case, I can’t think of a single reason why anybody should ever want to use Inform, other than being horribly intimidated by the fact that they’re actually engaged in computer programming so they’d much prefer to pretend that they’re not.

This entry was posted in fiction, games, Interactive Fiction, technology, writing and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s