I’ve tried. Honestly, I have. My latest project is 95% finished, almost ready for testing. I’ve been at it for several months.
And I’m not a dunce. I’ve completed and released three or four other text-based games, written in Inform 6 and TADS 3. I’m not a computer science whiz, but I’m a halfway decent hobbyist programmer.
Inform 7 has defeated me.
I was sailing along, and things seemed to be going well. But then I hit a snag. So I posted messages on the newsgroup (rec.arts.int-fiction) asking for help with the snag. The suggestions, posted mainly by Inform 7 guru Emily Short, make no sense to me. I try to implement what she’s suggesting, and get nowhere. After days of perplexity, I’m no closer to a solution. I tried to simplify the coding problem to where I could deal with it (in essence dumbing down my game, which is something I hate to do), and hit another snag.
I have no tools with which to try to work my way through the snag. All I can do is sit on my thumbs and wait for some kind person to take the time to explain what I’m doing wrong … and then hope that their explanation makes sense. That’s the essence of the problem, right there.
I’m ready to throw in the towel. I’m angry, frustrated, and completely at a loss how to move forward. I feel ripped off. I’ve put months into this project (for no particular reason other than because it amused me), and now it appears the only way to salvage all that hard work is to rewrite it from the ground up in an entirely different development system (TADS 3).
To make matters worse, some local home-school kids want to learn to write interactive fiction. I’ve promoted the idea of teaching a class by telling their moms that Inform 7 would be an easy, fun way to introduce them to the whole thing. So what am I going to do? Well, I guess maybe I7 is okay for kids. I wouldn’t recommend it for grown-ups.
The roots of my anguish are several.
“Natural Language” Programming. I’ve come to feel that using “natural language” syntax for computer programming, which is how I7 works, is simply a mistake. “Natural language” both creates and encourages a sort of syntactic mush in which it’s very difficult to tell what anything means.
The tendency toward mush is aggravated by the fact that I7 is “rules-oriented” rather than object-oriented. I’m not enough of a codehead to have an opinion about whether a rules-oriented language is inherently better, worse, or just different than an object-oriented language. But after working on my game for several months, I still have no clue what’s in I7’s basic rulebooks. It’s all mush to me. And my code is mush too. You can write your own rules anywhere in the source code — for the most part, that is. Inform does sometimes force you to declare terms before you use them, but not in a way that’s clearly explained anywhere that I’m aware of.
The “natural language” paradigm produces some very specific problems. It’s possible to declare a new in-game object in your Inform 7 source code, for instance, without realizing that you’ve done so. This will introduce hard-to-diagnose bugs. Needless to say, you can’t possibly make this kind of mistake in a well-designed language. You can certainly make other kinds of mistakes — but inadvertently creating objects? No.
Both I7 code and the explanations of I7 code read like word salad — long strings of verbs, adjectives, nouns, prepositions, and so on. This makes it harder to understand what’s going on, even when you can find a possibly pertinent example and an explanation of the example.
Poor Documentation. The I7 documentation is a muddle-headed mess. It’s a pretty good tutorial, in the sense that it gives you hundreds of examples (written by Emily Short) of clever things to try, and if you read it from start to finish you’ll learn a lot of stuff. But it’s not a reference document. Many of the section headings listed in the table of contents are mystifying; things that ought to be visible as section headings aren’t; and while there’s a search engine, there’s no index.
What the documentation really is, is propaganda. Over and over, the documentation (the main body of which was written by Inform developer Graham Nelson, not by Emily) seems to be trying very hard to show you how simple and easy it all is — with the result that the nuts and bolts are pretty consistently swept under the rug. Nuts and bolts? Why should you care about that? It’s eeeee-Z! Well, it’s pretty easy as long as you’re content to do the things that are actually explained. If you try to do something that’s even one tiny step off the beaten path, you’d better wear your hip boots, because you’re going to be wading in shit.
Emily tries to fill in the gaps in the docs by responding to questions on the newsgroup, but there are two problems with this (over and above the fact that she isn’t always available). First, she’s obviously overworked, so some of her answers are written quickly. She’s nudging you in the right direction, but she doesn’t always provide a complete roadmap. (If there were a good owner’s manual, you’d already have a roadmap on your hard drive.) Second, she knows Inform 7 way too well, so she does things that are, I’m sure, intuitively obvious to her and sometimes neglects to articulate her reasons or explain how you would sit down and work with the sample code she offers in order to adapt it to your situation.
Teaching by example is ultimately not as useful as teaching by explaining things in an exhaustive, step-by-step manner, taking explicit cognizance of all of the possibilities that may arise. Just about all of the available information on I7 teaches by example.
Two Languages at Once. The guts of Inform 7 are written in Inform 6, which is an entirely different language. In order to figure out how the library rules work, if you should need to do so, you’ll have to learn two different coding systems. (Contrast this with TADS 3, where the entire library is written in TADS 3. One syntax to learn, and it’s a nice clear syntax, too.)
I’ve taken a quick look at one of the I6 template files, which contain the actual code that causes I7 to run. I can’t make heads nor tails of it. And because it’s rules-oriented rather than object-oriented, there’s no easy way to trace its logic. It seems to consist of a long, long list of global functions that use mysterious constants. Here’s a line, which is as representative as any:
if (bits) bits = RS_ACTIVITY + RS_NOSKIPS;
Are there any comments that explain what this line does? No, there are not. What this means, to the game author, is that there is no way to trace through, and if necessary alter, what the library is doing. It’s going to do whatever it’s going to do. The author is not, then, a participant in the process; the author is a victim of the process.
Skimpy Library. The I7 library has been deliberately kept minimal rather than being designed to do the job right. (The TADS 3 library does the job right.) The I7 library is supplemented using add-on extensions — code supplied by others, which you can download and include if you want to. This code not infrequently uses its own forms of syntax, whose meanings may or may not be clear. Some extensions are known not to be compatible with others. Some extensions are better documented than others. A few have bugs. And because not everyone is using the same extensions, if you have a problem with code supplied in an extension, the I7 gurus on the newsgroup may not have a clue what’s going on, because it’s very possible that none of them is using that particular extension.
To be blunt about it, Graham Nelson is not actually taking responsibility for the code you’ve downloaded in order to write your game. He has handed off that responsibility to others. While many of the extension authors are, I’m sure, as bright and industrious as Graham is, parceling out the work in this manner is a recipe for confusion.
I learned this morning, for example (New Year’s Day), that one of my more vexing coding problems has already been solved in a new version of an existing extension. So I was getting frustrated over nothing — or rather, over the fact that I’m not constantly checking the web page to see whether new versions of various items have been released.
I thought briefly about teaching those home-school kids TADS 3 instead. But the T3 Workbench doesn’t run on the MacOS. (It runs under CrossOver, but not well.) And in any case, T3 is a language for grown-ups. I wouldn’t expect ten-year-olds to be able to grasp dot operators and template syntax without a lot of preparation. It wouldn’t be fun for them.
If writing IF isn’t fun, why bother? Good question.