Search Results for: interpreters

IFTF's Adoptable Technology Archive

An announcement went up last week on the IFTF blog. You may already have seen it, but it's important and I want to talk about it some more.

[...] While we wish we could take over and maintain software projects, we just don’t have the resources right now. What we can do instead is act as social matchmakers and try to connect projects with volunteers.

Toward this end, we’re establishing a new project called the IFTF Adoptable Technology Archive.

The IFTF Adoptable Technology Archive will be a public archive of adoptable technology on GitHub. If someone owns a project that needs a new owner, they can put it on a free and open-source software license (we favor the MIT license) and pass it over to us, and we’ll put it up on the archive. The benefit of using our archive (instead of putting it up on GitHub as an individual) is that it will be visible under the IFTF “adopt me!” umbrella. This will create a place where developers can go and see all submitted IF projects in need of adoption, while abandoned projects benefit from the related publicity. We’ll also announce all new additions to the archive via our social media channels.

(-- announcement, Feb 14, IFTF blog)

(The Adoptable Technology home page now exists!)

One of the unfortunate truths of the hobbyist IF field is that most of our open-source projects have lost momentum since the late 1990s. There are a couple of reasons for this. A cohort of fans who grew up with Infocom became energetic 20-somethings with lots of free time, but are now 40-somethings with families, mortgages, or other such temporal entanglements. Also, the IF field has become more diverse. When everybody was playing Z-machine games, there were lots of people working on Z-machine interpreters! But the field has broadened.

There have also been many, many experimental IF projects that never went anywhere. Some of these can be found on the IF Archive, or even on GitHub. But if you don't know they exist, they might as well have vanished.

The Adoptable Technology project is our first small step towards saving these projects. As the announcement says, we don't (yet) have the resources to actively maintain them. Instead, we can put them into a sort of showcase (a GitHub organization). This has two incremental benefits:

  • Onlookers can see the list of projects in the collection. They are, at minimum, no longer invisible.
  • If someone wants to pick up a stalled or abandoned IF project, they have a list of possibilities to compare.

To be sure, not every stalled or abandoned IF project needs to be in the collection. We're not pushing this as a panacea! Nor have we committed ourselves to filling it up. An IF project maintainer may just be looking to recruit volunteers, or to hand the project off in some other way.

Quest is an example from a couple of months ago. They spread the word that they were looking for new maintainers, and they were able to find people that suited their needs. We're happy to help pass along such requests from anyone in the IF field.

But if a project really loses all support, we've got a place for it that will help avoid total invisibility. That's what the Adoptable Technology collection is. It's currently empty except for a README. Perhaps it will remain so for a while. But it's our small step.

Tagged , , , , , | Leave a comment

More progress towards Hadean Lands on Steam

Here's a work-in-progress shot of Hadean Lands on MacOS. I'm using an extended version of Lectrote, with HL's map and journal windows added in. (The iOS release of HL has always had these, but not the Mac/Win releases. Until now!)

Yes, two different windows are titled "Map of the Marcher". I'll fix that.

(Background: Lectrote is a new interpreter for Glulx IF games -- meaning most recent Inform 7 games. It runs on Mac/Win/Linux, and it supports all Glulx features except audio. I still have a "beta" label on it, but it's been stable for people so I think it's about ready to 1.0-ify.)

Once this is ready, I'll soft-launch it as an update for existing HL users (people who bought the desktop version through Itch or Humble, plus Kickstarter backers). I'll also post the process of turning your Glulx game into a Lectrote app like this.

In other news, I was interviewed on another podcast! Guy Hasson of Blind Panels talks to me about pretty much the entire history of IF. Plus other stuff I've done.

Posted in Zarfplan | Tagged , , , , , , , | Leave a comment

Lectrote now autosaves; Hadean Lands is that much closer to Steam

I've been steadily updating Lectrote, my new cross-platform(*) IF interpreter. In the past month it's gotten icons, a preferences dialog with font and color options, and -- most exciting from my point of view -- autosave.

(* Cross-platform meaning that Lectrote runs on Mac, Windows, and Linux. The interpreter only runs Glulx games, not Z-machine or TADS or any other format.)

Autosave means that if you close the game window (or quit the interpreter) and then open it again, you will find your game where you left off. You don't have to use the SAVE or RESTORE commands unless you want to keep multiple save points.

As I wrote last month, autosave is a bit of a nuisance. I spent February getting it all polished up and tested. And then the tests revealed some obscure low-level bugs in the iOS implementation of autosave. Turns out my iOS Hadean Lands app was failing to store one VM table, and therefore running about 50% slower than it should have. Whoops. Good thing I wrote tests, right?

Lectrote on the desktop seems to be adequately speedy for most games, including Hadean Lands. So that's the last big technical barrier to creating a really nice HL app for Mac/Win/Linux...

I don't mean to imply that a Steam release is coming this week. It will still take some time to adapt Lectrote to a single-game interface. Naturally I will document this process! I want to make things as smooth as possible for any author who wants to release an Inform game as a Mac/Win/Linux app.

(The iOS process is, er, not very smooth. This is mostly because Apple's process for the iOS App Store is baroque, to say the least. I'm not planning to put HL in the MacOS App Store, so it should be simpler.)

I'll also see if I can include the extra dynamically-updating windows from the iOS version of HL: the clickable map and the alchemy index. In theory, these aren't too hard to set up -- I can copy the logic and contents right over from the iOS app. In practice, theory sits on the curb and laughs at you when you say things like that. So we'll see.

But the end is in sight. Give me another couple of months.

Once I have a working HL app, I will release it as an update for the existing Mac/Win/Linux versions of the game. If you have downloaded HL from the Humble Store or Itch.IO (either as a purchaser or a Kickstarter backer), you will be able to download the new app and try it out. If no horrible bugs turn up, I'll start preparing the Steam release.

Posted in Zarfplan | Tagged , , , , , , | Leave a comment

Introducing Lectrote, an interpreter

Today I posted the beta of Lectrote, a new IF interpreter application for Mac, Windows, and Linux. This is both more and less exciting than it sounds!

If you're familiar with the IF scene, you know that there are several applications which can be used to play these games. Zoom (Mac), WinGlulxe (Windows), and Gargoyle (multiplatform) are the most commonly used. And then there's Quixe, which is a Javascript-based interpreter used on and other web sites.

When I was looking to release Hadean Lands as an app, I found that none of these were really what I wanted. Zoom is unmaintained and buggy; WinGlulxe is weird about scrolling; Gargoyle has problems on hi-res displays. (I'm summarizing, it was a long messy story.)

Quixe had the UI that I wanted -- no surprise; it's the one I wrote the UI for! -- but it wasn't really meant to be used as an app. It exists as a web page, or a component of a web page. Also, it's slow. So I put it aside and went with Gargoyle.

However, the long messy story didn't end there! A few weeks ago I was gazing over the endless cycle of dev-tools and noticed Electron. Electron lets you wrap up a Node.js tool as a standalone app for Mac, Win, and Linux. And Node.js is, well, I don't really know what it is but it's a web thing. Seems ideal, right? Stuff Quixe's web page into Electron and we're done.

It wasn't quite that easy. Node.js has full filesystem access (unlike a web page), so I had to extend Quixe's load/save system to deal with ordinary files. (So you can exchange save files between Lectrote and other interpreters.) But that was still pretty easy. I stuck the IF postcard in a menu, too.

And now you can try it.

So what does this have to do with getting Hadean Lands onto Steam? Well, it's a very simple tweak to drop a Glulx game file into Lectrote. Then you've got a Mac/Win/Linux app that plays a single game. And it looks nice and the text layout is pretty and you can adjust the font size without editing a text file.

I haven't done that yet. I'll have to adjust the menus -- knock out all the support for opening multiple games.

More important, I'll have to add autosave. Right now, if you're playing a game and you close the window, your game is gone. Hope you typed SAVE! That's okay for an interpreter (used by IF habitu├ęs), but it's not ideal. It's really not acceptable for a Steam standalone game release.

Autosave for Glulx games is a bit of a nuisance, but I got it working on iOS. I will get it to work with Quixe. It will just take a few more weeks.

...oh, and then there's the speed. I mentioned that Quixe is slow, right? It's faster than it was but it might not be fast enough for Hadean Lands. If you own HL for Mac/Win/Linux, try it! In particular, try loading a mid-game save file and typing a command which requires many stages, like GO TO BAROSY.

(If you don't own HL, may I remind you that it's on sale for the next two days? I probably don't have to. But I do it anyway.)

Anyway, I may try plugging a different Glulx VM into Lectrote to speed it up. I can probably run RemGlk/Glulxe as a subprocess of the Node.js server... We'll see.

For now, Lectrote is a multi-platform interpreter app which has the UI I want, and that's a good start.

Posted in Zarfplan | Tagged , , , , , , | 8 Comments

Javascript wonkery

Here I will take a break from the ever-burbling stream of IF and Myst news, and talk about Javascript optimization.

You could say it's relevant because it came up in a Quixe bug report. ("I tried loading Emily Short's Counterfeit Monkey.... Load time dropped from 29.4 seconds to 10.4 seconds...") IF interpreter improvements are a high priority for me -- particularly if they could be big speed improvements for a fairly small code change. Double-particularly if they imply I've had crappy Javascript code out there for years.


I usually build my Javascript libraries according to the private namespace pattern. I can't remember where I learned this. I assume it originated in this blog post (Douglas Crockford), but I use the cleaner layout described here (Ben Cherry) or here (Todd Motto).

With this trick, all your internal functions and variables wind up hidden from the outside world. You decide which ones to export, and the rest remain private.

Here's a toy example:

Lib = function() {
    var counter = 0;
    var prefix = "The current value is ";

    function add(val) {
        counter += val;
        return counter;

    function get() {
        return prefix + add(0);

    return {
        add: add,
        get: get

Here counter and prefix are private variables. The add() function increases counter and returns it. The get() function returns it as part of a string. (I've set get() up to call add(0) just to demonstrate that private functions can call each other.) Finally, we return an object which exports the add and get symbols. This becomes the global Lib object, so a user can call Lib.add() and Lib.get(). But there is no Lib.counter; that's private.

Crockford says "This pattern of public, private, and privileged members is possible because JavaScript has closures... This is an extremely powerful property of the language." Okay, that's top-grade hand-waving. What he means is "Javascript is a terrible language, but it has stolen enough features from other languages that you can pull this crap off if you're incredibly careful and don't mind confusing onlookers."

Anyhow. The trick works pretty well until you start constructing Javascript functions on the fly. Let's extend our example:

Lib = function() {
    var counter = 0;
    var prefix = "The current value is ";

    var compiledfuncs = {};

    function add(val) {
        var func = compiledfuncs[val];
        if (func === undefined) {
            var text = "counter += " + val + ";";
            text += "return counter;";
            func = eval("(function func() { " + text + " })");
            compiledfuncs[val] = func;
        return func();

    function get() {
        return prefix + add(0);

    return {
        add: add,
        get: get

What the heck is going on in add()? Imagine that this is an IF virtual machine interpreter, like Quixe. We're doing just-in-time (JIT) compilation. We take a Glulx function -- that is, a string of Glulx opcodes -- and convert it into a Javascript function. The browser's Javascript engine will then convert that function into native machine code and the result will run really fast.

Since this is a toy example, our only opcode is "increase counter by N". When we see a call to add(1), for example, we convert that into this Javascript function:

function func() {
    counter += 1;
    return counter;

We eval that source (compile it) and stash the function (in case another add(1) comes along). Then we execute it.

So that's great, and it works. But if you profile this in Chrome, for example, you'll see a couple of little yellow warning flags:

  • Not optimized: Function calls eval
  • Not optimized: Reference to a variable which requires dynamic lookup

You see, Javascript is a terrible language, and its scoping model is a haystack of ideas jammed together without any planning, and it can never be fixed because backwards compatibility. Certain operations in closures are legal, but slow.

(To be fair, every language's scoping model sucks. You know how the only hard problems are naming and cache invalidation? This is naming. But Javascript is worse than most.)

We could get rid of the eval() if we used a Function() constructor:

func = new Function(text);

But then the code would fail, because the function would exist outside the library closure. It wouldn't have access to the private variable counter.

I fussed around with a couple of different solutions. I tried inner and outer closures, I tried using this a couple different ways. None of them worked. (Crockford progresses from hand-waving to passive-aggressive sniping: " error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions." You tell 'em.)

I eventually settled on this:

Lib = function() {
    var self = {};
    self.counter = 0;

    var prefix = "The current value is ";

    var compiledfuncs = {};

    function add(val) {
        var func = compiledfuncs[val];
        if (func === undefined) {
            var text = "var self = this;";
            text += "self.counter += " + val + ";";
            text += "return self.counter;";
            func = new Function(text);
            func = func.bind(self);
            compiledfuncs[val] = func;
        return func();

    function get() {
        return prefix + add(0);

    return {
        add: add,
        get: get

Our compiled function can't get access to the private namespace. We need a second namespace which can be handed in for that purpose. We'll call that self. We create self up top, and put the counter in it. We'll have to write self.counter to access it now.

To hand self in to our generated function, we call bind. This is a confusing Javascript feature which lets us glue any object in as the function's this. Then we compile it this way:

function func() {
    var self = this;
    self.counter += 1;
    return self.counter;

This is more verbose, but it works. And if we check it in Chrome's profiler, the yellow warning flags are gone.

Note that if we wanted the generated function to call private methods, we'd have to copy them into the self object too:

function get() {
    return prefix + add(0);
self.get = get;

Not too messy.

Now the real question is, does this actually make Quixe run faster? I don't know! I've started converting the code to this new model, but it's going to take more work. (The virtual machine has lots of state to shove into the self object.) The person who filed the original report got good results, but I'm not sure I've snagged the right tricks yet.

The toy example in this post seems to run a little slower with these changes. That's not encouraging, but of course it's not a realistic work model. Hopefully I'll have real results in a few days.

UPDATE, May 29th:

Got an updated Quixe branch working.

Turns out the func.bind(self) plan is terrible. Performance doesn't improve as much as it should; on Firefox it actually gets worse.

Instead, I've given each generated function an explicit self argument, and called them all as func(self). With this plan, Quixe is 65% faster in Safari, 55% faster in Chrome, 10% faster in Firefox. Woot!

Tagged , , , , , | 11 Comments

Forward planning for IF tools

I've been bemoaning the slightly run-down state of IF interpreter software. (The confusing font preference system in Gargoyle is just one example.) The fact is that the big surge of open-source IF activity was the late 90s and early 00s. Since then, coders have been drifting out of the community, and the ones still around have gotten lazy. (I include myself in that indictment, for damn sure.)

As a community, we do not have a tradition of mentoring and fostering new contributors to IF projects. All of our projects were made by people (most often solo developers) who got excited and wrote a whole application or library.

I like to think that we've got a good software stack, which smooths the path a little. You can write an Inform extension or a Glk library port or a Glulx engine core or a Parchment web service, and it will fit into the ecosystem. But it still starts with a person showing up with enough energy to start, build, and finish an idea. If someone shows up who is curious but not committed, we nod companionably and wait to see what happens. The results, over time, are predictable: activity slows down and stops.

With that introduction, you'd expect me to go on and talk about mentoring. But I don't know anything about mentoring. I'm one of the control freaks! I'd rather work on my own projects than collaborate.

Anybody want to think about community-building? (Hopeful look around...)

(Of course a lot of my projects are specifications and tools that interoperate with other people's code. So I kick myself in the ass and make it happen. But my natural talents do not lie in management.)

In this post, I'm going to talk about my plans as a solo IF tool developer. Warning: I will also talk about money.

I have a whole list of things I think Need Doing In IF (see footnote) but the one I intend to tackle next is Glk 2.0. This is pretty much the same Glk 2.0 plan I've been planning for years, but since it's been years, not everybody may remember it. (Or perhaps you remember it with bitterness and loathing, in which case I apologize.) In any case, I will explain it from the top.

The plan is: integrate Glk (the Glulx VM display layer) with CSS and Javascript. That is, you will be able to distribute Inform games with custom stylesheets and special display effects (see Vorple).

Why CSS and Javascript? Because they have already conquered the universe, so we might as well give in to our anger and rule at their side. Also, the most commonly-used IF interpreters are written in Javascript, which makes adding these new features trivial. (If we plan correctly.)

So how do we approach this? I'll admit up front that this plan isn't complete. This is a sketch; I have parts of it worked out.

The basic idea is to define a canonical HTML representation of Glk output. Or rather, a canonical DOM representation. (The DOM is the internal data structure that a browser builds when it reads in an HTML file.)

Currently, the Glk spec describes output in terms of windows, text, and text styles. The new spec will explain this in terms of HTML <div> and <span> elements, and the CSS classes for each one.

I don't mean that your Inform code will output HTML. For simplicity, and to maintain a clean separation of concerns, the Glk calls in the Inform library will remain the same. You'll set a style and print some text. The interpreter's job will be to either translate those calls into HTML (as defined by the spec), or do the equivalent job of text display.

Nor do I mean that interpreters will have to support every crazy CSS trick that Firefox is capable of! Far from it. The idea is this: whatever display capabilities the interpreter does have, let CSS guide where it's used.

It's easy to misunderstand this. Let me lay it out in an organized way.

  • This is a change to the way the interpreter (Glk library) manages the display, not a change to the way you write your Inform game.
    • But there will be some new capabilities available for Inform games. Mostly this will be about letting you use more styles.
  • The display of a stock Inform game will not change much. Any changes will be in the direction of more uniformity between interpreters.
  • This should not require interpreter maintainers to rewrite their code from scratch.
    • Javascript interpreters (Quixe) will work by generating HTML information and shoving it into the browser display. This is how Quixe has always worked. I'll just have to add the CSS and make some adjustments.
    • C interpreters (Gargoyle, WinGlulxe, Zoom, Floyd-bot, etc) can continue to work the way they work, by calling OS-native text-display calls (or use SDL or telnet or whatever). However, to decide on text display attributes for each style, they should start using CSS information. I will provide a library to make this easy.
    • Alternatively, C interpreters could switch over to HTML display. That is, they could throw up an OS-native HTML widget and shove HTML into it, just as Quixe does. This is optional, but it has some advantages -- see below.
  • The new plan will initially be available through an I7 extension. I expect that some future I7 release will make it the default.
  • What new features does this plan give us?
    • A game author will be able to include a CSS stylesheet with the game. This will customize the way the interpreter displays the game.
    • A player will be able to select a CSS stylesheet as an interpreter preference. This will customize the way the interpreter displays the game (overriding the author's stylesheet if necessary).
    • There will be some way to display more and fancier styles. I know we had an argument about this a few years back; let's not restart it in this post. I haven't nailed down the details anyhow.
    • A game author will be able to include a Javascript library (or libraries) with the game.
      • For HTML-based interpreters, the Javascript will be loaded into the browser page (or HTML widget). It can then perform arbitrary display tricks. Glulx Vorple can be built on top of this.
      • For interpreters which do not have an HTML layer (i.e. old-style C interpreters), Javascript tricks will not be possible. The game will have to degrade gracefully or give up.

Where am I with this plan? Not very far. Even after all these years.

I have a roadmap. I've just finished step 1. It will be a few steps more before anybody else has to start writing code.

  1. Write a simple, dependency-free C library to parse CSS. Done! I thought this would be a weekend hack; it actually took many days of work, because CSS is just as horrible as every other Web technology. (No, I didn't search for prior art before I started hacking. Who do you think I am?)

  2. Nail down the HTML representation and the Glk API changes it will require. Think about how it affects all existing interpreters.

  3. Update GlkTerm to the new model. GlkTerm is a terminal-window library (it's built on ncurses), so it can only support a few text attributes -- boldface, underline, ANSI color. This is enough for a proof of concept.

  4. Update Quixe to the new model. (And jQuery, while I'm at it.) Quixe is an HTML-based interpreter so it will allow the full range of CSS and Javascript fireworks.

  5. Write the I7 extension that enables this stuff.

  6. Write a lot of demos. (Not just to show off! Demos will let other interpreter authors know they're hitting the mark, display-wise.)

  7. Update RemGlk and CheapGlk.

  8. Unleash my reign of terror upon the world.

Easy, right?

You can reasonably ask how long all of this will take. Especially since I laid out much the same plan at least five years ago, and then again three years ago, and I've just managed to finished step 1.

Well, Hadean Lands is done. That's a big carcass off my plate. Also, for this semester I'm spending one day a week at MIT(*) and that's a nice regular schedule for working on the project.

(* But not this week, because it snowed some. And the Red Line caught fire or something.)

It's still a lot to promise; enough that I feel queasy just posting this post. I hate making promises that I don't keep.

Thus to the subject of money.

Post-HL, I would like to work more on open-source IF tools. I would also like to work on indie games that will pay the rent. (HL does not pay the rent in the long term, despite the stellar reviews I got this month.) There's also contract work and so on. Life balance, it's hard.

One way to converge these interests: find a way to crowd-source IF tool work. But this is not an easy model. It's not a Kickstarter -- it's ongoing work, not one big deliverable. It's not exactly a Patreon, because I can't give backers early access or bonuses. (But some people try this anyway?)

I'm signed up for Gratipay, which started as a tip model for GitHub users (but now supports any developer). I haven't publicized it at all; despite this, somebody is giving me 33 cents a week. (Thanks!)

Are there any other patronage systems which you folks think I should investigate?

(Note: I am not asking for money at this time! I'm thinking about ways in which I might ask for money in the future.)

I realize this is an awkward subject. Many people support IF software. I don't want to be The One Who Gets Paid while everybody else labors away for free. On the other hand, there's a lot of work that isn't getting done; this has been true for years. I can start to unstick this, but not to the exclusion of paying work.

Furthermore, the Glk 2.0 plan isn't the only thing on my plate. I'd love to get back to Tworld (the Seltani engine). I could dig into CocoaGlk and figure out why Mac Zoom occasionally crashes (and why Mac Inform 7 occasionally trashes my skein, and maybe why it occasionally eats somebody's source code...) I could spend some time experimenting with the rule-based language idea, zog help me.

What I'd really like is a patronage-and-voting system, where people could put money into different projects, with the understanding that the ratios determine how much time I put into each one. Does anything like that exist? (No I'm not going to build one.)

...Wow, this post has wandered in circles, hasn't it. A mix of plans, promises, positions, and pleas!

I guess I'm trying to figure out where the next phase of my life falls, relative to the IF community. I have taken stock, and this is what I see. Comments welcome.

Posted in Zarfplan | Tagged , , , , , , , | 29 Comments