A short time ago I started writing my first game with the intention of implementing it in both Inform 7 and TADS 3 in order to figure out which system was right for me. Here are my thoughts about Inform 7.
This post is not spoily, but in case you want to play the game, it’s available at IFDB.
Before even starting the game, I decided to keep it as simple as possible. To that end, I decided on the following rules:
- Refrain from using extensions. The reason for this is that it adds a lot of complexity and extra material to learn.
- Keep the customizations to a minimum. This means no mucking about with customizing library messages for everything. If the default response for something wasn’t horrible, I kept it.
- Don’t ask for help. The game is quite simple and I wanted to see how difficult it would be to figure pretty basic things out for myself. This may or may not have been a good idea, but it’s done now.
Before I start the analysis, let me just say that overall the experence was very positive and I had fun writing the game. Inform 7 is a great system, but invariably, the parts that you remember best are the bad parts. So forgive me if this sounds overly nitpicky - I’ve tried to only include the issues that I think are actually important. There were pleny of frustrating moments that I believe were caused by my inexperience. I’ve left those out.
Rant starts here:
[rant]Almost the first line of the source is Include Custom Library Messages by Ron Newcomb. So much for rule number 1 above. I wanted the game to be in third person, and that’s really the only way to do it. But the transition was painless, so I’m not complaining. The line after that reads Include Pronouns by Ron Newcomb. This one has a story behind it. It was added almost at the very end. You see, after switching the story to third person, I wrote the introductory text that describes the character arriving. After that a logical player command would be X HIM. For the life of me I couldn’t figure out how to make the pronoun ‘he’ refer to the player. When play starts: set pronouns from the player/yourself didn’t work, nor any other thing I tried. So I just left it until most of the rest of the game was finished, at which time I discovered the extention, which does just what I needed.
And this highlights a problem I have with extensions in Inform (and some other things, like LaTeX). There are just too many of them. I don’t have an overview of what is available and when I need some small functionality, I don’t immediately go looking for an extension. That was part of the orginal reason why I decided not to use extensions for this project - I didn’t want to get bogged down in reading the documentation of all the extensions to find out what they do. If I stick with Inform, I will be using extensions for my more serious works, and I imagine there will be plenty of times where I just overlook a really useful extension because I never think to look for it.
A somewhat related problem is the diversity of the language constructs. Again, there’s really no way to know what to actually type for any specific case without diving into the documentation. The descriptions of groups of objects that Inform provides is a powerful way to generalize, but I found that I couldn’t write any kind of complex description that would actually compile. The error messages where very general, so I don’t really know what I did wrong. The result was that I either found an expression that worked and stuck with it, or split up the code over several expressions, so that all the power and versatility of the description system was wasted. One specific example: descriptions used as values can’t contain temporary variables. Why not? The error message said something which basically means that it’s trying to protect me from using a value which might not exist. Dear Inform, I know what I’m doing. Trust me, the value exists - I just created it on the previous line and I know the object is there. And if I didn’t know what I was doing, the error message wouldn’t make any sense to me anyway. Besides, there’s a workaround for it, which compiles, but would still generate a run-time error if the value didn’t exist.
Speaking of diving into the documentation, it just doesn’t work for me. Usually when I tried to find out how to do something, I spent a lot of time looking for the right place in the documentation. For example, I wanted to find out how to crete a new action applying to a topic instead of a thing (at that time I didn’t know it was called a topic, I just knew it had to match some fairly arbitrary text the player typed). Is the section of the documentation in the Actions chapter? No, how about the Advanced Actions chapter? Nope, it’s in the Understand chapter under the header The text token. Sure, the two things are related, but I wouldn’t know it before reading it.
Compilation time is a real problem in my opinion. It’s just annoying when I make a small change and have to wait almost a minute to test it. It’s probably even worse in a large project. Separate compilation and the ability to split the source text among several files would help a lot, but that would probably require a complete redesign. A smaller redesign could be to keep the extensions and standard rules compiled. That would shave off a lot of time. Another thing: why do we need to recompile when I haven’t actually made any changes to the source? That’s a really easy fix. Also, what happens to the index when I close the application? The next time I open it, the index is gone and needs to be recompiled before it will appear. Does the program just delete it when it closes? Or does it keep the whole thing in memory? Either way, it’s silly. This is a problem, because I’m frequently in a situation where I make a lot of changes that no longer compile. I get frustrated with them and take a break from the whole thing. The next time I come back, the source still won’t compile and I have no way to use the index until I fix it.
Another thing I found annoying was the verbosity of the language. ‘Description’ and ‘Understand’ are long words and it’s easy to make a typo while writing them, but these are among the most common things you need to type. Some sort of shortcut for those would be nice. There is a shortcut for descriptions of rooms - just write a quoted string after creating the room. That same shortcut for things sets the initial appearance instead. Why? Every object needs a description, but not every object needs an initial appearance.
I struggled with naming things. Forgive the comparison to TADS 3 here, but I really missed the ability to have anonymous objects. I have lots of similar objects in different rooms with slightly different behaviours. The behaviour is completely defined in general rules, so I don’t really care what it’s called as I don’t have to refer to it anywhere, but I have to keep thinking of different names for everything. Making it privately-named is two extra sentences for every object, so that’s annoying too.
After all that whining, let’s talk about something good. I’m really impressed with the index, skein and transcript tabs. I frequently used all the subsections of the index tab to see what actions are available to the player and what commands lead to those actions, what rules govern the standard behaviour, and so on. The most useful feature has to be the ability to jump to the place of definition of various things from the index, though that gets screwed up if you edit the file before recompiling. The skein was also very nice, though I imagine that a less linear game might see more use out of it. Right now, I just did a walkthrough of the game and annotated some checkpoints so I could quickly get to them. The transcript is good too, it allowed me to quickly scan the output and only note the places that actually changed. This saves a lot of time as you don’t need to reread everything.
Also, a word about the parser and understand rules. Though I didn’t go very deep into it, it seems to me that with skillful use of understand rules the parser can understand some rather complicated phrases. Actually writing the rules is clunky and verbose, but it’s straightforward and very doable. One feature I missed was the ability to match all the vocabulary of a game object as a token. I know that several extensions provide an equivalent functionality, but again, I decided not to use extensions.
I like the fact that the standard behavior is broken up into small rules, which made it easy to modify specific parts of it.
The built-in spellchecker is a nice feature, though I wish it would only check quoted strings.[/rant]
Despite what it might seem like from this post, there are more positive than negative aspects to Inform 7. I’d readily write another game with it and I’d probably have less complaints doing so as I know to avoid some of the annoyances and utilise the more powerful features of the language.