ADVENTURE PORT ============== The objective of this port was to be able to play the original colos‐ sal cave adventure in its true original form, with no omissions, addi‐ tions, or modernizations. I started with the PDP‐10 FORTRAN source code by Crowther and Woods, and ported it to standard UNIX FORTRAN 77. I’ve only tested it with g77 on Linux and FreeBSD, but it’s pretty much straight‐ahead ANSI FORTRAN 77, so it ought to work with other compilers and systems without much trouble. I did the porting work over a few evenings and weekends in January 2016. SETUP In its original form the program was designed to work with the snap‐ shot feature of the PDP‐10. An installation would initialize it once with the text data file, then save a core image, which included the initialized states of all the program’s variables. The data file could then be removed or made inaccessible, so as to discourage cheating, and the core image could simply be run. This port works the same way, except that the game’s state is saved to a binary file instead of a core image. Thus, the state and the code are kept in two separate files instead of one. After compiling the program, on first running it, the file ’ad‐ vent.dat’ must be present in the current directory. The program will initialize from this file, then save its state to /etc/advent.bin. Then it will pause, and you can either terminate it or go on and play the game. I recommend doing that first run as root, so that it can write to /etc/advent.bin, and then terminating after it initializes. From that point on, advent.dat is no longer required, and /etc/ad‐ vent.bin need only be readable unless you are going to change the game options in magic mode, which is explained further below. If you would like to put the binary file somewhere other than in /etc, simply change the constant BINFIL in the code before compiling. MAGIC MODE The cave hours and a few other options can be changed if you are a wizard. If you’d like to do this, run the program as a user with write access to advent.bin, and then issue "magic mode" as your first com‐ mand. After that, the game will present you with a series of chal‐ lenges to determine whether you are a wizard. It will prompt you for the magic word, which by default is ’dwarf’, though it can be changed via magic mode once you get in the first time. If you respond with the correct magic word, it will ask you if you know what IT thinks the magic word is. You should answer "no" to this question, which will cause the game to print a random magic word. To finish authenticating as a wizard, you must respond with the correct answer to this random magic word. The correct answer is based on the random magic word, the current time, and a magic number. I’ve included a little program called ’wiz’ to calculate it. Run ’wiz’, enter the random magic word from the game, and it will print out the proper response. Go back to the game and enter that response, and it will authenticate you as a wizard. Note that if you change the magic number via wizard mode, you must also change it in the source code for wiz (wiz.for) and recom‐ pile, or you will not get correct results. Only a user with write access to advent.bin can permanently change the game options, but you still want wizard access to be secure, because wizards can do other things to override normal game restrictions. The two mechanisms for securing wizard access are changing the magic word and the magic number. Of course both of these values are stored with‐ out encryption in advent.bin, so it’s not true security, but it ought to be enough to keep honest users honest. SUSPENDING AND RESTORING In the original game, upon suspending, the game would simply exit back to the command level and allow the user to save a core image that pre‐ served the state of their game. In this port I changed the suspend op‐ eration so that it now prompts you for a path to a binary file, in which it saves the state of your game. As in the original, when you suspend a game, the program terminates, and you cannot play that game anymore for at least 90 minutes. (This time is configurable somewhat via magic mode.) To resume a game, I added a new "resume" command, which prompts for the location of the file where you saved your game. It then loads the state from that file and starts exactly as if it were starting from a core image. This means that if it hasn’t been long enough since you saved, it will tell you so and terminate. PORTING NOTES I tried to add good comments as I went along, but I also strove to leave the original comments unscathed, so some of those are now incor‐ rect. Most of the work involved was in three basic areas: (1) using CHARACTER types instead of packing characters into integer types, (2) eliminating use of non‐portable bitwise logical operators and I/O functionality, and (3) dealing with the fact that UNIX architectures don’t have the PDP‐10’s snapshot feature. Where I changed code, I tried to make it comply with the ANSI FORTRAN 77 spec. One place I couldn’t do that was in the date/time routine. There is no standard way to get the date and time, but the intrinsics I used are probably common in the world of UNIX FORTRAN. Another place the code could not be 100% standard compliant was in the assumption that if a READ state‐ ment requires more characters than are supplied by a record, the re‐ mainder will be read as blanks. This is evidently a widespread assump‐ tion, however, even though it is strictly forbidden by the ANSI spec. The original textual data file was tab‐delimited, but standard FORTRAN does not know how to read delimited fields. It wants fixed‐sized fields. So I wrote a small program called datcvt to convert it. This program is supplied along with this port. Beyond that, I added only the necessary vocabulary entries for the new "restore" command. I’m supplying the original files I started with for reference, with .orig suffixes. If you’re interested in exactly what I changed, try diffing against the originals, but make sure you ignore whitespace, because I converted tabs to spaces throughout, which will otherwise make the diffs very noisy. Cheers! Dan Nelson Feb 2, 2016