Design Philosophy

"It is a thousand times harder to make simple things than complicated ones."
- Mikhail Kalashnikov

With so many existing IF authoring systems, anyone with the audacity to create yet another one really needs to justify that decision, particularly if it departs from the proven and widely accepted (at least within the IF community) usage of the Z-machine. Well, I'm a bit of a contrarian, and I've chosen to do just that. This essay describes why - in particular, it examines the fundamental choice of framework/library vs. specialized language. While I don't doubt that someone could create a better framework than JIFFEE, I do believe that any better system is quite likely to use this same basic approach. (Note that unlike the rest of this web site, this page does assume that the reader is an experienced programmer, as nobody else is likely to care about this material anyway.)

Before delving into the details, it's important to state up front that this discussion is in no way a criticism of the creators of any existing systems. Most established IF authoring systems like INFORM and HUGO were designed years ago, at a time when the computing and web landscapes looked very different from their current state. Indeed, the whole Z-machine architecture predates the Internet itself, and it was an elegant and well thought out design for the requirements and conditions of the time. My argument here is that the widespread adoption of web browsers, and in particular the ubiquitous availability of JavaScript, has changed the equation, and that different choices can now take better advantage of the new conditions.

First a word about terminology, and the distinction between two approaches to providing "canned" functionality for someone writing in an existing standard programming language:

In some cases the distinction between these two approaches is quite significant, but the JIFFEE framework is so small and lightweight that the difference isn't very relevant to this discussion and is mentioned only for completeness. If you're not familiar with frameworks just think of JIFFEE as a library, and all my arguments will still apply equally well.

Now to the meat of the matter: is it better to create a customized language, i.e. one designed specifically for writing IF, or is it better to create a framework in an existing "standard" programming language? Let's look at a number of aspects of this choice.

Simplicity

This is the essence of the "specialized language" argument: We want a very low barrier to entry for beginners, and by designing a customized language we can create something that looks "almost just like English" and thus makes it very easy to get started. (Old farts in the audience may recall a very similar rationale regarding COBOL.)

While this argument sounds eminently reasonable, I've concluded that it is a false argument. When you look at it closely, even an "English-like" IF language is still really a computer language, it can still be formally described in BNF, and it's still probably parsed by a recursive descent or LR(1) parser. The bottom line is that the user is still going to have to learn some rigid syntax even if that syntax does bear a surface resemblance to natural language. (Again, think back to the experience with COBOL. If it were really as simple as writing in English, colleges wouldn't have offered semester-long courses in it.)

Actually, the real beginner isn't going to learn syntax at all; that's not how the typical human mind works. The beginning IF author is actually going to look at examples in the tutorial and imitate them, probably via cut-and-paste followed by some editing. When you're working this way, it really doesn't matter whether the syntax is:

DESCRIBE lobby AS You're standing in the lobby of the Opera House.
or
traits.set("lobby", "long-desc", "You're standing in the lobby of the Opera House.");
Either way, it's not really English, and either way, it will only take even the rankest beginner a few minutes to get the hang of whatever the syntax is.

Diagnostics

Here a specialized language does have the edge. Using any conventional programming language interpreter or compiler will inevitably lead to error messages - especially about syntax errors - that have no discernible relationship to what the user is trying to do. It's probably possible to write lint-like preprocessors that would do a better job of reporting, but running them could be awkward. The best bet is probably to keep the framework so simple that only a very tiny subset of the full language is needed for beginner-level programs, thus keeping the number of likely errors to a correspondingly small set which the user can quickly learn to recognize.

Flexibility

Making it easy to write "Hello, world" is a noble goal, but no game worth playing (or writing!) is going to stay simple and declarative for very long. Almost immediately the author is going to want to add some variable behavior. You can use templates or forms or patterns or any kind of sugar-coated syntax you want, but the truth is that as soon as the first customized conditional logic appears, the IF author is now programming. The authoring system designer has to specify a well-defined, complete semantics for this conditional logic, and the IF author has to learn it in order to do anything interesting with the system.

You can try to design your own way of doing this, but we already have a way to specify conditionals that has been around for years and is well-proven. It's called an if-then-else statement. If you look at all the major mainstream programming languages (even including things like LISP and Smalltalk), you can't help but notice that at the semantic level they all use roughly the same structure. That's because it works - not just at the level of what the computer can do, but also at the level of how people can think about it.

If you try to use English (or any other natural language) to specify a conditional as unambiguously as an if-then-else statement, you will end up with something that looks like it was written by a paranoid obsessive-compulsive attorney. [1] This is no accident, since attorneys are paid to remove ambiguity just like programmers are, but they have the terrible disadvantage of being required to so so in English.

So whether you roll-your-own or use something standard, a game of any sophistication is going to require the specification of complex logic. You might as well use a standard way of doing it. Note that this need not increase the difficulty right at the very beginning of the learning curve, since total beginners really will be working at the "Hello, world" level. This also doesn't prevent a framework from providing a bunch of canned logic for common actions that can easily be invoked declaratively, e.g. facilities for picking up and moving objects. It just says that at some point, probably fairly soon, an IF author is going to outgrow the predefined facilities and will need to define some real logic, and it's important that the IF authoring system provide good facilities for doing so.

To really put this in proper perspective, take some code from a non-trivial program (even "Cloak of Darkness" will do) written in an existing IF language, show it to some non-IF friends, and ask them to explain what the code does. Even if they are programmers, I suspect they won't be able to produce a coherent and accurate description. (The same would not be true of a Java programmer looking at C++ code, or a Python coder reading Java - in those cases, although they will miss details of how iterators and scoping work, they'll at least be able to follow the basic flow of conditionals, loops, and subroutine calls.)

This really hit me when I started to implement "Cloak of Darkness" in JIFFEE. Even though I already knew the basic idea of the game, when I looked at the published source code examples in the various existing IF languages, I had a lot of trouble deciphering the exact semantics. OK, so I'll admit I didn't bother reading any of the manuals first, but if you have to read the manual to understand the source code, then it's not natural language. It's a programming language, and it's very unlikely that any programming language you or I invent in our spare time is going to be superior to Java or Python. Thus I assert that specialized languages really aren't any easier to use than a framework in JavaScript, and that in fact such languages end up creating "islands" that isolate you from the main body of computer geeks and from all the resources they have to offer.

Platform compatibility

When we author IF, we obviously want our creations to run on as many different computers as possible. In the early days of IF this was a difficult challenge, and designing an intermediate virtual machine was a proven and practical technique to achieve portability. Even mainline languages like Pascal used this approach. This led to the Z-machine, and that worked well.

Today, however, we have much better standardization and much wider availability of conventional languages like C++, Java, and Python. The design of these languages benefits from years of development and input from hundreds of programming professionals, so it's hard to see how a single IF hobbyist is going to come up with anything better. JavaScript has the special additional advantage of immediate availability (i.e. no additional downloads or installs needed) on just about any machine with a modern browser — and almost every PC today has either IE, Firefox/Mozilla/Netscape, Safari, Opera, or Chrome already installed.

Both approaches provide excellent portability, but the balance has shifted: using a specialized language requires the user to do an extra download, but using JavaScript does not. Using JavaScript also provides the IF author with all the power of a fully-developed programming language with no development required from the creator of the IF authoring system. (You could make a good case that what JavaScript actually does is to provide a virtual machine, so the two approaches are actually equivalent, and the only choice is which virtual machine to use.)

Power

Once you get serious, you want to write serious games. Really serious games, that require serious computation, complex logic, and sophisticated implementation. Taking a language designed for newbies and extending it piecemeal to try to add power is a recipe for trouble, and even if you do manage to avoid inventing a spaghetti language it will still be a huge amount of work to implement and test, and at the end you'll have laid one more brick on the Tower of Babel of computing languages.

Why not just use a real language instead? With JavaScript you get conditionals, loops, functions, scoping, exceptions, hash tables, objects, HTML formatting of output, ability to insert graphics and sound, yada, yada, yada, and it's already installed on every new machine out-of-the box. Why would any sane person want to re-implement all that? Or conversely, why would you want to give up all that when it's completely free?

There is however one important area where JavaScript is problematic: saving state. Because JavaScript deliberately doesn't give you access the user's PC or file system, you can't just write a file to save your state. Although there were excellent security reasons for designing JavaScript this way, for this application it's a very serious shortcoming because in large games people will definitely need to save their state and continue playing later. Using a server-based solution would be one approach, but it makes it much more complicated to create a game (and removes the ability to play off-line), so I've really tried to avoid that. Instead, we can use a cookie to store state. It took three versions of JIFFEE to get it to work, but by placing carefully designed restrictions on how the game author declares state, and by using some moderately sophisticated compression, it is possible to store the state of a fairly large game in a 4KB browser cookie.

Availability of help

Everybody starts out as a beginner, and beginners need help from a community of knowledgeable colleagues who have already made all the newbie mistakes. With any specialized IF language, the pool of people who can help is necessarily quite small, i.e. only those few (hundred? thousand? dozen?) people in the world who are using the same system. With JavaScript on the other hand, most of the basic questions can be answered by any of the probably millions of people who have some basic competence in JavaScript. There's even a good chance that the teenager next door is writing DHTML and can help you out. :-)

Empirical evidence

As they say, the proof is in the pudding, and without empirical evidence my opinion is just, well, opinion. The only way to find out for sure is to try it. Alas, since JIFFEE is quite new I don't have any solid evidence either way yet, but I am piloting it with real people (currently, non-programmer middle-school students) to see how they do with it. Time will tell.

Summary

When you look at all the factors, my judgment is that given the current state of the world, creating an IF authoring system as a framework in JavaScript is now a better choice than writing IF in a specialized language. In fact, after over 30 years of experience as a programmer, this has also been my observation in many different application areas completely unrelated to IF: the advantages of using an existing, well-established language are so overwhelming that creating a new language is almost never the right choice.


[1] No offense to the legal profession. One of my best friends is an attorney, although to the best of my knowledge he's not paranoid.