Advent icon indicating copy to clipboard operation
Advent copied to clipboard

A modern ANSI C port of Crowther & Woods' "Adventure".

This project provides translations into modern, modular C99 of four classic games: Crowther and Woods' "Adventure", Luckett and Pike's 440-point "Adventure II", David Platt's 550-point "Adventure 3", and David Long et al.'s 551-point "Adventure 6".

===========================================================================

A summary of existing versions and ports of Adventure is available on Russel Dalenberg's website: http://www.prismnet.com/~ged/www/advelist.html

The original "Adventure" was written in Fortran IV by Will Crowther, and extended also in Fortran by Don Woods.

In 1977, Jim Gillogly ported Woods' code to C. Gillogly's extremely literal port (lots of switches and gotos) is still shipped, as "adventure", in the Debian bsdgames package.

In 1998, Don Knuth rewrote the entire game in CWEB, a literate programming language that combines ANSI C and documentation. The "woven" version of the program appears in its entirety in Knuth's book "Selected Papers on Fun and Games", and has been updated several times, correlated with the publication dates of new editions of "Fun and Games".

For this translation, my primary source was the "woven" version of Knuth's program, circa 2002, as available on literateprogramming.com. In cases when the behavior seemed suspect, I compared it to the "raw" version of Knuth's current program, and/or to Woods' Fortran version. In this way I found at least three bugs in Knuth2010 (and have the checks to prove it). However, I may have unknowingly perpetuated other bugs, and I may have introduced a few myself.

Both Gillogly's and (especially) Knuth's versions suffer from the extreme disadvantage that their main() functions are enormous and convoluted, with gotos jumping all over the place. Knuth's is worse, because CWEB encourages a subroutine-less style: it's easier to inline a code snippet than to create a C function call for it.

But even though Knuth's "tangled" C program is indeed a tangled mass of code (it uses 81 global variables, and the main() function is 3270 lines long), its construction is mostly modular. I've followed Knuth's organization very closely in my translation; my version could best be described as a port of Knuth's code from CWEB to conventional C.

===========================================================================

A second goal of this translation is to produce a faithful version of the original "Adventure" which can be compiled to run on the Z-machine. The history of "Adventure" on the Z-machine, as far as I know, is:

In May 1994, Graham Nelson ported "Adventure" to Inform 5. His starting point was David Baggett's TADS version "Colossal Cave Revisited". This version has "EXAMINE" text for all the scenery, and although Baggett's version keeps the "motion words" such as SLAB and GRATE, Nelson's Inform version gets rid of them. It's easy to distinguish this version, because there is no two-word command that will unlock the grate (you must UNLOCK GRATE WITH KEYS), and the magic words XYZZY, PLUGH, and PLOVER do not immediately work at the start of the game. http://ifarchive.org/if-archive/games/source/inform/Advent.inf

Circa 2010, Chris Conley ported Will Crowther's original ADVENT (that is, ADVENT as it was before Don Woods got hold of it) to Inform 7. Conley devoted much more effort to fighting the Inform parser, but added some convenience commands such as I (as opposed to INVEN). http://ifarchive.org/if-archive/games/source/inform/Advent_Crowther_source.txt

In May 2012, Arthur O'Dwyer (that's me!) ported "Adventure" to C and got it running on the Z-machine. Play it here: http://quuxplusone.github.io/Advent/play.html

===========================================================================

The history of David Platt's 550-point "Adventure 3" is much shorter:

Platt's "Adventure 3" was a largely faithful reimplementation of Crowther and Woods' original 350-point "Adventure", augmented with many totally new locations and items.

Circa 1979, Dave Platt released the first version of "Adventure 550", while he was working for Honeywell. He continued maintaining it for several years, up until at least 1984. "Adventure 550" had a parser written in standard Fortran 77, and all the game-specific logic written in Platt's own language called "A-code", which was compiled into a set of external data files consumed by the Adventure program itself.

In 1982, Ken Wellsch ported Platt's code to RATFOR, and then in 1985 ported the RATFOR code to C. Wellsch's version preserved Platt's original design: a small kernel with accompanying A-code game logic.

Circa 1989, Mike Arnautov released "Adventure 4+", which merged Platt's extension and Jack Pike's "Adventure II" extension (a.k.a. ADV440) into a single 660-point game.

Circa 1999, Platt's extensions were added to the TADS port "polyadv" by Bennett Standeven et al. This being an extension of Baggett's "Colossal Cave Revisited", it was not particularly faithful to the original. The game's README stated: "The approach we took was to add decorations in every reasonable place."

For this translation, my primary source was Platt's A-code circa September 1984 (according to the in-game NEWS command), plus a copy of Platt's Fortran 77 kernel as reconstructed by Mike Arnautov by removing features from the kernel of Arnautov's 660-point "Adventure 4+". For more information, see "PLAT0550/README.txt".

The history of "Adventure 3" on the Z-machine, as far as I know, is:

In June 2012, Arthur O'Dwyer (that's me!) ported "Adventure 3" to C and got it running on the Z-machine. Play it here: http://quuxplusone.github.io/Advent/play-550.html

===========================================================================

The history of David Long et al.'s 551-point "Adventure 6" is:

Long created his 501-point "Adventure 5" circa 1978, both by augmenting the original Crowther and Woods "Adventure" and by slightly modifying a few puzzles (for example, relocating the trident and providing an alternative solution to the troll bridge). Long's game used Crowther and Woods' original command-parsing code, but drastically extended it (influenced by his experience playing DUNGEON, the game that would later become "Zork") to support compound sentences, adjectives, and prepositions, permitting commands such as "GET BRASS LAMP AND PUT LAMP AND AXE IN SACK". Long wrote "Adventure 5" in DEC Fortran, a dialect of Fortran IV.

David Long planned to release version 6 of his game in "summer 1979", and in fact did at some point release a 751-point "Adventure", but that version seems to be lost; or at least not available on the Internet today.

In late 1984, Doug McDonald expanded Long's 501-point game, increasing the maximum score to 551 points and porting the game to Fortran 77. He called his version "Adventure 6".

A 501-point version of Long's game (dated October 1979) was posted to Usenet by Bill Randle in May 1990. By that point Long's single aamain.f had been fragmented into many smaller source files, contained "GRIPE" code attributed to Mike St Johns, and may have had other (anonymous) contributors as well. http://cd.textfiles.com/gigagames9308/NET/USENET/VOLUME9/ADVEN

This 501-point version was ported to Fortran 77 by Johann Oskarsson circa 2003: http://www.ifarchive.org/if-archive/games/source/advent-5.2.2-5.tar.gz

Randle's Usenet post prompted McDonald to release his 551-point version onto Usenet in August 1990.

In 1994, Robert R. Hall combined Long's and McDonald's new features with the guts of a C port of "Adventure" due to Jay Jaeger, Jerry Pohl, et al. Hall's port was dated "Version:7.0, July 1994", but contains no rooms or items besides those in McDonald's version "6.6".

In 1999, McDonald's version was added to the TADS port "polyadv" by David Picton et al. This being an extension of Baggett's "Colossal Cave Revisited", it was not particularly faithful to the original's quirks. Picton made some idiosyncratic changes, most notably adding some hints and randomizing the combination to Long's safe.

For this translation, I took as my gold standard Doug McDonald's August 1990 version ("Adventure 6.6"), since no "original" game by David Long alone appears to have survived. My secondary source was the 501-point Randle version.

The history of "Adventure 6" on the Z-machine, as far as I know, is:

In November 2012, Arthur O'Dwyer (that's me!) ported "Adventure 6" to C and got it running on the Z-machine. Play it here: http://quuxplusone.github.io/Advent/play-551.html

===========================================================================

The history of Luckett and Pike's 440-point "Adventure II" is:

Coworkers Peter Luckett and Jack Pike collaborated to write "Adventure II", an expansion of Crowther and Woods' "Adventure", circa 1978. Pike, at least, continued to work on it through at least July 1981, as indicated by his notes (which include bugfixes with dates attached). Whereas Platt's and Long's versions involved a great deal of "engine" work, Luckett and Pike reused Crowther and Woods' engines almost entirely wholesale; the only major innovation is that Pike's dwarves can pick up and carry objects, "tidying up" the cave and causing mischief in the maze.

Circa 1989, Mike Arnautov released "Adventure 4+", which merged Platt's extension and Jack Pike's "Adventure II" extension (a.k.a. ADV440) into a single 660-point game, written in A-code rather than Fortran.

In 2001, Pike contacted Arnautov and together they reconstructed a new version of "Adventure II", combining a version of the engine code saved by Arnautov with the latest data files from Pike. This new version was compilable as Fortran 77 and included some bugfixes from Arnautov, Volker Blasius, Dave Picton (the author of polyadv), and perhaps others. To judge from comments in the source, it was developed between September and November 2001.

The history of "Adventure II" on the Z-machine, as far as I know, is:

In September 2014, Arthur O'Dwyer (that's me!) ported "Adventure II" to C and got it running on the Z-machine. Play it here: http://quuxplusone.github.io/Advent/play-440.html

===========================================================================

To run C code on the Z-machine, I'm using "vbccz", a Z-machine backend written by David Given in 2008 for Volker Barthelmann's open-source C compiler "vbcc". This git repository hosts an unmodified copy of "vbcc" (as per its license terms), plus a cumulative patch to fix several backend bugs so that it can successfully compile my version of "advent.c". Apply the patch by running "./build-vbcc.sh"; then cd to ODWY0350/ and run "make".

Disclaimer: "vbccz" is not really a general-purpose C compiler. While I'm fixing the bugs that are relevant to "Adventure", I'm ignoring many other trouble areas. For example, it calls out to library routines for all 32-bit math; since "Adventure" doesn't use any 32-bit variables, I haven't bothered to include David Given's "runtime.s" library in this repository. And don't even talk to me about floating point! The unimplemented areas might give an internal assertion error, if you're lucky, but they might just generate bad code. Use with caution.

                                              Arthur O'Dwyer
                                              November 2012