This video accompanies a blog post of the same title. The content is mostly the same; the blog post contains a few extra elements (especially in the footnotes!). Enjoy whichever one you choose.
This blog post is also available as a video. Would you prefer to watch/listen to me tell you about the video game that had the biggest impact on my life?
This simple text-based adventure was originally written by Tim Hartnell for use in his 1983 book Creating Adventure Games on your Computer. At the time, it was common for computing books and magazines to come with printed copies of program source code which you’d need to re-type on your own computer, printing being significantly many orders of magnitude cheaper than computer media.3When I first came across the source code to Werewolves, I’d already begun my journey into computer programming. This started alongside my mother and later – when her quantity of free time was not able to keep up with my level of enthusiasm – by myself.
I’d been working my way through the operating manual for our microcomputer, trying to understand it all.5And even though I’d typed-in dozens of programs before, both larger and smaller, it was Werewolves that finally helped so many key concepts “click” for me.
In particular, I found myself comparing Werewolves to my first attempt at a text-based adventure. Using what little I’d grokked of programming so far, I’d put together
a series of passages (blocks of
INPUT statements) that sent the player elsewhere in the story (using, of course, the long-considered-harmful
GOTO statement), Choose-Your-Own-Adventure style.
Werewolves was… better.
Werewolves and Wanderer was my first lesson in how to structure a program.
Let’s take a look at a couple of segments of code that help illustrate what I mean (here’s the full code, if you’re interested):
What’s interesting about the code above? Well…
- The code for “what to do when you win the game” is very near the top. “Winning” is the default state. The rest of the adventure exists to obstruct that. In a language with enforced line numbering and no screen editor7, it makes sense to put fixed-length code at the top… saving space for the adventure to grow below.
- Two subroutines are called (the
- The first sets up the game state: initialising the screen (
2610), the RNG (
2620), and player characteristics (
2660). This also makes it easy to call it again (e.g. if the player is given the option to “start over”). This subroutine goes on to set up the adventure map (more on that later).
- The second starts on line
160: this is the “main game” logic. After it runs, each time, line
IF RO<>11 THEN 30. This tests whether the player’s location (
RO) is room 11: if so, they’ve exited the castle and won the adventure. Otherwise, flow returns to line
30and the “main game” subroutine happens again. This broken-out loop improving the readability and maintainability of the code.8
- The first sets up the game state: initialising the screen (
- A common subroutine is the “delay loop” (line
3520). It just counts to 900! On a known (slow) processor of fixed speed, this is a simpler way to put a delay in than relying on a real-time clock.
The game setup gets more interesting still when it comes to setting up the adventure map. Here’s how it looks:
What’s this code doing?
2690defines an array (
DIM) with two dimensions9 (19 by 7). This will store room data, an approach that allows code to be shared between all rooms: much cleaner than my first attempt at an adventure with each room having its own
- The two-level loop on lines
2730populates the room data from the
DATAblocks. Nowadays you’d probably put that data in a separate file (probably JSON!). Each “row” represents a room, 1 to 19. Each “column” represents the room you end up at if you travel in a given direction: North, South, East, West, Up, or Down. The seventh column – always zero – represents whether a monster (negative number) or treasure (positive number) is found in that room. This column perhaps needn’t have been included: I imagine it’s a holdover from some previous version in which the locations of some or all of the treasures or monsters were hard-coded.
- The loop beginning on line
2850selects seven rooms and adds a random amount of treasure to each. The loop beginning on line
2920places each of six monsters (numbered
-6) in randomly-selected rooms. In both cases, the start and finish rooms, and any room with a treasure or monster, is ineligible. When my 8-year-old self finally deciphered what was going on I was awestruck at this simple approach to making the game dynamic.
- Rooms 4 and 16 always receive treasure (lines
2980), replacing any treasure or monster already there: the Private Meeting Room (always worth a diversion!) and the Treasury, respectively.
- Curiously, room 9 (the lift) defines three exits, even though it’s impossible to take an action in this location: the player teleports to room 10 on arrival! Again, I assume this is vestigal code from an earlier implementation.
- The “checksum” that’s tested on line
2740is cute, and a younger me appreciated deciphering it. I’m not convinced it’s necessary (it sums all of the values in the
DATAstatements and expects
355to limit tampering) though, or even useful: it certainly makes it harder to modify the rooms, which may undermine the code’s value as a teaching aid!
Something you might notice is missing is the room descriptions. Arrays in this language are strictly typed: this array can only contain integers and not strings. But there are other reasons: line length limitations would have required trimming some of the longer descriptions. Also, many rooms have dynamic content, usually based on random numbers, which would be challenging to implement in this way.
As a child, I did once try to refactor the code so that an eighth column of data specified the line number to which control should pass to display the room description. That’s
a bit of a no-no from a “mixing data and logic” perspective, but a cool example of metaprogramming before I even knew it! This didn’t work, though: it turns out you can’t pass a
variable to a Locomotive BASIC
Werewolves and Wanderer has many faults11. But I’m clearly not the only developer whose early skills were honed and improved by this game, or who hold a special place in their heart for it. Just while writing this post, I discovered:
- A moderately-faithful Inform reimplementation
- A less-faithful semi-graphical adaptation
- A C# reimplementation with a web interface (video)
- An ongoing livestreamed effort to reimplement as a Sierra-style point-and-click adventure
- An Applesoft BASIC implementation which includes a dynamically-revealed map
- A C reimplementation with a high score table
- A somewhat-faithful reimplementation in Rust (playable online via WebAssembly)
- A very accurate rendition in Python
- A Ruby/Python microservices-based implementation
- Many, many people commenting on the above or elsewhere about how instrumental the game was in their programming journey, too.
A decade or so later, I’d be taking my first steps as a professional software engineer. A couple more decades later, I’m still doing it.
And perhaps that adventure -the one that’s occupied my entire adult life – was facilitated by this text-based one from the 1980s.
There are five mysteries here right now:
Go back to wizardzines.com
Each mystery is a Twine-powered “choose your own adventure” game in which you must diagnose the kind of issue that a software developer might, for real. I think these are potentially excellent tools for beginner programmers, not just because they provide some information about the topic of each, but because they encourage cultivating a mindset of the kind of thinking that’s required to get to the bottom of gnarly problems.
Twine 2 is a popular tool for making hypertext interactive fiction, but there’s something about physical printed “choose your own adventure”-style gamebooks that isn’t quite replicated when you’re playing on the Web. Maybe it’s the experience of keeping your finger in a page break to facilitate a “save point” for when you inevitably have to backtrack and try again?
As a medium for interactive adventures, paper isn’t dead! Our 7-year-old is currently tackling the second part of a series of books by John Diary, the latest part of which was only published in December! But I worry that authors of printed interactive fiction might have a harder time than those producing hypertext versions. Keeping track of all of your cross-references and routes is harder than writing linear fiction, and in the hypertext
So I’ve thrown together Twinebook, an experimental/prototype tool which aims to bring the feature-rich toolset of Twine to authors of paper-based interactive fiction. Simply: you upload your compiled Twine HTML to Twinebook and it gives you a printable PDF file, replacing the hyperlinks with references in the style of “turn to 27” to instruct the player where to go next. By default, the passages are all scrambled to keep it interesting, but with the starting passage in position 1… but it’s possible to override this for specific passages to facilitate puzzles that require flipping to specific numbered passages.
If this tool is valuable to anybody, that’s great! Naturally I’ve open-sourced the whole thing so others can expand on it if they like. If you find it useful, let me know.
If you’re interested in the possibility of using Twine to streamline the production of printable interactive fiction, give my Twinebook prototype a try and let me know what you think.
Normally this kind of thing would go into the ballooning dump of “things I’ve enjoyed on the Internet” that is my reposts archive. But sometimes something is so perfect that you have to try to help it see the widest audience it can, right? And today, that thing is: Mackerelmedia Fish.
What is Mackerelmedia Fish? I’ve had a thorough and pretty complete experience of it, now, and I’m still not sure. It’s one or more (or none) of these, for sure, maybe:
- A point-and-click, text-based, or hypertext adventure?
- An homage to the fun and weird Web of yesteryear?
- A statement about the fragility of proprietary technologies on the Internet?
- An ARG set in a parallel universe in which the 1990s never ended?
- A series of surrealist art pieces connected by a loose narrative?
Rock Paper Shotgun’s article about it opens with “I don’t know where to begin with this—literally, figuratively, existentially?” That sounds about right.
What I can tell you with confident is what playing feels like. And what it feels like is the moment when you’ve gotten bored waiting for page 20 of Argon Zark to finish appear so you decide to reread your already-downloaded copy of the 1997 a.r.k bestof book, and for a moment you think to yourself: “Whoah; this must be what living in the future feels like!”
Because back then you didn’t yet have any concept that “living in the future” will involve scavenging for toilet paper while complaining that you can’t stream your favourite shows in 4K on your pocket-sized supercomputer until the weekend.
Mackerelmedia Fish is a mess of half-baked puns, retro graphics, outdated browsing paradigms and broken links. And that’s just part of what makes it great.
It’s also “a short story that’s about the loss of digital history”, its creator Nathalie Lawhead says. If that was her goal, I think she managed it admirably.
If I wasn’t already in love with the game already I would have been when I got to the bit where you navigate through the directory indexes of a series of deepening folders, choose-your-own-adventure style. Nathalie writes, of it:
One thing that I think is also unique about it is using an open directory as a choose your own adventure. The directories are branching. You explore them, and there’s text at the bottom (an htaccess header) that describes the folder you’re in, treating each directory as a landscape. You interact with the files that are in each of these folders, and uncover the story that way.
Back in the naughties I experimented with making choose-your-own-adventure games in exactly this way. I was experimenting with different media by which this kind of branching-choice game could be presented. I envisaged a project in which I’d showcase the same (or a set of related) stories through different approaches. One was “print” (or at least “printable”): came up with a Twee1-to-PDF converter to make “printable” gamebooks. A second was Web hypertext. A third – and this is the one which was most-similar to what Nathalie has now so expertly made real – was FTP! My thinking was that this would be an adventure game that could be played in a browser or even from the command line on any (then-contemporary: FTP clients aren’t so commonplace nowadays) computer. And then, like so many of my projects, the half-made version got put aside “for later” and forgotten about. My solution involved abusing the FTP protocol terribly, but it worked.
(I also looked into ways to make Gopher-powered hypertext fiction and toyed with the idea of using YouTube annotations to make an interactive story web [subsequently done amazingly by Wheezy Waiter, though the death of YouTube annotations in 2017 killed it]. And I’ve still got a prototype I’d like to get back to, someday, of a text-based adventure played entirely through your web browser’s debug console…! But time is not my friend… Maybe I ought to collaborate with somebody else to keep me on-course.)
In any case: Mackerelmedia Fish is fun, weird, nostalgic, inspiring, and surreal, and you should give it a go. You’ll need to be on a Windows or OS X computer to get everything you can out of it, but there’s nothing to stop you starting out on your mobile, I imagine.
Sso long as you’re capable of at least 800 × 600 at 256 colours and have 4MB of RAM, if you know what I mean.
Today, @bodleianlibs releases Shadows Out of Time, a Choose-Your-Own-Destiny story. It’s amazing – go read it: https://s.danq.me/Np #halloween #InteractiveFiction