No Time To Play

CoffeeScript as a domain-specific language for interactive fiction

by on Jun.22, 2012, under Gamedev

While my latest gaming project fizzled out before I could announce it (better that way, arguably), and I’ve been distracted by other shiny things, something has been on my mind, and recently culminated in an epiphany.

Javascript is increasingly used to program computer games, and interactive fiction could not avoid the trend for long. That’s a good thing for players, who get easier access to their favorite stories. Programmers on the other hand are in trouble because, you see, JS just isn’t a very good language for the job.

Mind you, the original Adventure must have been written in Fortran IV, a.k.a. Fortran 66, which had terrible support for strings; that’s one reason why the data was in a text file (though other reasons were more important). But even newer languages, while having all the tools needed to deal with text, are not so good at simply encoding it. Here’s what I mean:

function init() {
    start_room = foyer;
    cloak.moveInto(player);
    say(
"Hurrying through the rainswept November night, you're glad to \
see the bright lights of the Opera House. It's surprising that \
there aren't more people about but, hey, what do you expect in \
a cheap demo game...?");
}

That’s what the intro to Cloak of Darkness might look like in a naive Javascript implementation. Note how a multi-line string needs those backslashes, and everything must start in the first column lest we end up with unwanted whitespace. You can see it in Versificator and Undum — it’s ugly to say the least.

The alternative, namely concatenating successive strings, is no better:

"Hurrying through the rainswept November night, you're glad to"
+ " see the bright lights of the Opera House...";

That’s like writing with a blunt pencil on paper that tears easily. You want to be focusing on what you’re writing, not on the process. But don’t blame the language! A general-purpose one simply can’t be expected to flow naturally for every kind of code out there. A better metaphor would be a multitool: no matter how good it is, it just can’t match up to a real toolbox.

This is where domain-specific languages come in. Professional programmers are probably familiar with SQL and regular expressions. For interactive fiction authors, the best examples are Inform 7 and Alan 3. It would be exceedingly difficult to write an address book program in I7, but a small adventure game with three locations is a single sentence:

The Living Room is south of the balcony, southeast of the kitchen
and east of the hallway.

Of course, the disadvantage is that I7 requires its own compiler, and a virtual machine for running the games. And while that’s standard procedure in IF, there are reasons why it may not be what you want. For example, if you’re making your own authoring system in order to learn what goes into it.

That was the point of Jaiffa; my second goal was to make expressing IF in Javascript feel natural. Judge for yourself:

current(room("Hallway"));
exit("North to bathroom").altname("n").to(room("Bathroom"));
exit("East to living room").altname("e").to(room("Living room"));
exit("West to the outside").altname("w")
    .to(room("11th floor"))
        .via(door("outside door"));

This approach is called a fluent interface. While elegant, it can only go so far. Note how little text I used; there are longer descriptions in the game, but none over two lines. That dictates what kinds of adventures I can make with Jaiffa, and Cloak of Darkness is right out. Which also means most typical text-filled games.

Are general-purpose languages unsuitable for the task, then? Not necessarily. By design, languages such as Lua and Ruby provide syntax shortcuts to make code look less like higher mathematics and more like plain English descriptions. But running either in a web browser is resource-intensive. We need a lighter solution… and we have it!

I’ve known about CoffeeScript for a while now, but had no use for it, since I can write JS that’s as compact, clean and fast by hand. And then it struck me: that was missing the point. The real advantage of CoffeeScript is that you can write code that looks like this:

room "Foyer of the Opera House"
    desc: """
    You are standing in a spacious hall, splendidly decorated
    in red and gold, with glittering chandeliers overhead.
    The entrance from the street is to the north, and there
    are doorways south and west.
    """
    exits:
        north: """
        You've only just arrived, and besides, the weather
        outside seems to be getting worse.
        """
        west: room "Cloakroom"

room "Cloakroom"
    desc: """
    The walls of this small room were clearly once lined with
    hooks, though now only one remains. The exit is a door to
    the east.
    """
    exits:
        east: room "Foyer of the Opera House"

hook = supporter "small brass hook"
    desc: () ->
        "It's just a small brass hook, " +
        if this.has cloak
            "with a cloak hanging on it."
        else
            "screwed to the wall."

I dare say it looks more natural than most IF languages, and as a bonus it’s truly at home on a Web page. The only question is whether that would be enough to justify a new entrant in an already crowded market. Then again, there are other game families out there that could benefit from a DSL. But that’s another story, which may lack an end.

P.S. The authors of the language have thought of it as well…

(CoffeeScript logo used for illustration purposes.)

Creative Commons License
CoffeeScript as a domain-specific language for interactive fiction by Felix Pleșoianu is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

:, ,

5 Comments for this entry

  • george

    hi Felix,

    I’ve had the same thought. If you’re on the fence about giving it a go, you have my encouragement! 🙂

  • JIm Aikin

    I hadn’t heard of CoffeeScript. I think you’re right that it would be very good for IF authorship! My only comment is … Alan? I don’t know a lot about it, but my impression is that it’s pretty marginal. What about TADS 3? T3 is a robust object-oriented IF development system.

  • Felix
    Felix Pleșoianu

    Alan is indeed underused — a victim of history, in my opinion (see my review). But it is an excellent example of a DSL, which is why I mentioned it.

    TADS 3, on the other hand, is a general-purpose programming language with only a few features designed to facilitate writing IF. Apart from the standard library, that is. 😛 I wanted to mention that in the article, but didn’t find a good place. Obviously, I should have. Thank you!

  • Peter Orme

    Hi Felix,

    I’m looking at coffeecript and interactive fiction too. I can’t say that my efforts are going anywhere, but it’s a fun way to learn coffeescript if nothing else.

    Did you ever make any progress on this? Is there anything to see? If and when I make something that’s starting to resemble a playable demo I’ll post my code on github or whatever, but I’m not there yet.

    // Peter

    • Felix
      Felix

      Hi Peter,

      I never got around to playing with this idea any further. Got too many other projects. But I’d like to see what you come up with, whenever you do, and wouldn’t mind chatting about it either.

1 Trackback or Pingback for this entry

Posts by date

June 2012
M T W T F S S
« May   Jul »
 123
45678910
11121314151617
18192021222324
252627282930  

Posts by month