Hadean Lands: The Source Code

In 2010 I launched a Kickstarter for a full-scale modern text adventure, to be called Hadean Lands. I said “It might take six months; it might take more.”

In October of 2014 (I know), I launched the game on the iOS App Store and started sending out gift codes to my backers. There’s a whole story there, mind you, but let’s not get into it. Two years later I released a Mac/Win/Linux port on Steam and Itch.IO.

In early 2023, Mike Russo bruited the idea of IF Source Code Amnesty Day – a day to release the source for your game, be it good, bad, or janky.

The Hadean Lands source code was part of a high-level Kickstarter reward. About thirty generous backers received it – as a printed volume, not a digital file. And that was a one-time offer. I didn’t want to dilute the value of the reward by make the source more widely available. Nor (I selfishly thought) did I want to spoil players’ experiences by making the source easy to read.

But hey, it’s been almost a decade! Hadean Lands has been sitting out there all this time, earning a tiny (but steady) trickle of money. Lots of people have played it. Spoilers aren’t going to hurt its sales now. Surely more fans are interested in reading it than playing it. And the backers have had their period of exclusivity.

(Truth told, I was already considering the idea of a source code release. I was going to time it for the game’s tenth anniversary. But Source Code Amnesty Day was a way better idea.)

Overview of files

The game:

Test framework game:

Testing scripts:

About the code

Hadean Lands is copyright 2014-6 by Andrew Plotkin.

This source code is provided for personal, educational use only. The story and text of Hadean Lands belong to me; you may not use them or create derivative works which contain them. However, you have permission to use the programming techniques of this game in your own works, and you may use the source code excluding game text.

The source represents release 5 (May 22, 2016), which is the version on Steam. The iOS app is stuck on release 4 for reasons of save-file compatibility.

The source is organized into a main file and eight extensions, totalling 34,000 lines of code. (241,000 words, of which about 73,000 are printable text that a player might read.) It must be compiled with Inform 7 release 8.5 (“6G60”), which was the extant version when I started coding. This is unfortunately difficult to get hold of, as Inform was not yet open-source at that point. I don’t think there’s much need to recompile the game, mind you. I certainly don’t plan to. If you want to try, you’re on your own.

(Before you ask: no, I am not soliciting bug fixes, patches, or updates. It’s fine the way it is.)

Also note that the game requires a relatively modern version of the Inform 6 compiler – version 6.33 or later. Yes, 6.33 postdates 6G60. I made use of some “recent” features and bug fixes.

I formatted the Inform source code for the Web using this script, which is based on the Pygments syntax-coloring package.

About the test scripts

The test scripts are meant to be run in RegTest, a unit testing framework that I built.

Each script describes a series of game inputs and outputs. RegTest starts up the game, shoves in the inputs, and verifies the outputs. It uses a specially built interpreter (based on RemGlk) which runs “headlessly”, with all inputs and outputs intercepted by the test framework.

(What about randomness, you might ask? I could have used an interpreter option to fix random results in place. But it wasn’t necessary. HL has no significant random events. Many of the game responses have minor random variations, but I used partial matches or regexes to verify those reliably.)

The “end-tests” script plays the entire game, beginning to end. In fact it’s organized in several chunks, so that we can run through puzzles one at a time. It also tries the dragons in various orders.

The “ritual-tests” script checks every step of every alchemical procedure – both successful and unsuccessful moves. This one runs in the “Ritual Testing” test game. The test game puts all of the ritual objects together in a single room. No puzzles, just a ritual bound and shelves of ingredients. This was crucial for development; in fact, I worked on the test game for months before I started building the Retort itself.

The “element-tests” check a lot of miscellaneous stuff that can only be tested in the full game environment. The behavior of the homunculus and the dragons; the working of various locks and puzzles which are scattered around the ship. This script also tests the “go to room” auto-navigation system from every significant zone to every other.

Finally, the “tutorial-tests” check all the tutorial responses for the initial puzzle.

The organization of the code

The game code can be divided into two parts: generic code (“Mechanism”, “Ritual”, “Gen Goals”) and game-specific code (everything else, including the main file). Generic code includes the fundamental laws of magic and all the objects which can be used in rituals. Game-specific code defines the rooms and scenery of the Unanswerable Retort.

(Why divide things up this way? Because the test game needed to contain all the ritual ingredients, but not the game map.)

So, we’ve got the “Mechanism” section, which defines core functionality and ritual objects. The “Ritual” section defines the behaviors of the rituals themselves.

Then there’s the goal mechanism. You won’t be surprised to learn that it takes up a good chunk of the code. A goal is an abstraction which represents one step, location, or tool in a PERFORM command. Like the rest of the game, the goals are divided into generic goals (which construct ritual objects) and game goals (which solve puzzles in the game, like opening doors). See the “Gen Goals” and “Game Goals” sections.

Game Locs” defines all the rooms; “Game Recipes” is the texts of all the recipes and sheets that you discover. “Tutorial” is the guts of the first-room tutorial. “Debug” is a whole lot of debug commands. (Most of these are omitted from the released game, of course.)

And finally – but listed first! – is the top-level file, which defines the start and end of the game, the plot progression, and all of the characters you meet. Including the dragons.

(The dragons are dedicated to Adam Thornton, by the way.)

Last updated March 31, 2023.