scalo.net

John Scalo

Porting HAUNT, the ’70s mainframe text adventure

One of the first games I was ever obsessed with was the text adventure game called HAUNT. It’s pretty obscure. To my knowledge it was only ever available on DEC mainframes, which as a kid I had access to because my dad was a professor at the University of Texas.

The game takes place in a haunted mansion and your goal is to find treasure and score points. Pretty typical stuff for text adventure games of that era, except that this one featured copious adult themes, namely sex and drugs! It was naughty and quirky in a way that I’d never seen in a game before, and I was hooked. I played it so much that I would regularly get “grounded from the modem” – a 300-baud VEN-TEL lollygagger.

You can still play HAUNT, but you have to find a TOPS-20 emulator with the game binary pre-installed, because the source code has since been lost.

That is, until now… I ported HAUNT to the web (JavaScript) and you can now play it in any browser. The port is open source and you can find the code here.

The story of how I got there is pretty interesting. A few years ago I read that the original author, John Laird, had ported the game from OPS4 (a now-dead programming language) to OPS5 (a slightly newer now-dead programming language). And I even found the ported OPS5 code. There are no compilers for OPS5 and documentation of the language is almost non-existent, but “ha!” I thought, “agentic coding to the rescue!”. And sure enough, Claude Code was able to infer the OPS5 by strict observation, and after an evening I had a working port!

There was one minor detail I missed, though: Dr. Laird never actually finished the port! (As documented here). The code I found was maybe 30-40% finished. But he had left placeholders all over the place so in my initial tests what I thought was a complete game was actually just half-finished.

Undeterred, I downloaded the original HAUNT.EXE binary along with a TOPS20 emulator for my Mac, and managed to get it installed and playable. Then, with the aid of a partial binary disassembly (essentially, strings-ifying it) and some external walkthroughs (this and this), I built a harness that allowed a bunch of AI agents to play the game very rapidly and in parallel, averaging around 7 seconds for an entire game session.

Then over thousands of “probe sessions” I had the AI collect transcripts, document divergences, and apply patches into my port. Before too long, the AIs were discovering every treasure, every known room, and every known interaction in the game, and patching my incomplete port to be in sync. (It’s worth noting that the OPS language didn’t have random number support built in, so the game is 100% deterministic.)

While I can’t confidently say the final port is perfectly faithful to the original, I’ve gone to great lengths to get it as close as possible: all known locations and treasures are covered, room descriptions and navigation match the original binary, and the game is fully playable from start to finish with a max score of 435 out of 440 (which according to the walkthroughs was true of the original). That said, whereas the original boasted 1,500 rules, the port has the equivalent of about 1,400. The missing 100? It’s impossible to say for sure, but the vast majority of these are most likely random-ish “You can’t do that here!”-type interactions.

If you’re at all into text adventures, give this one a shot. It’s tricky to score well but the fun is in the zany interactions. 🫎

Want more? Follow me on Threads.

All posts