rezrov - a pure Perl Infocom (z-code) game interpreter
rezrov game.dat [flags]
Rezrov is a program that lets you play Infocom game data files. Infocom's data files (e.g. ``zork1.dat'') are actually platform-independent ``z-code'' programs written for a virtual machine known as the ``z-machine''. Rezrov is a z-code interpreter which can run programs written in z-code versions 3 through 5 (nearly complete support) and 8 (limited support).
Rezrov's chief distinguishing feature among z-code interpreters is its cheat commands. It also features basic speech synthesis and recognition capabilities (when running under Windows, using the SAPI4 interface).
I/O operations have been abstracted to allow the games to be playable through any of several front-end interfaces. Normally rezrov tries to use the ``best'' interface depending on the Perl modules available on your system, but you can force the use of any of them manually.
Designed to work on almost any perl installation. Optionally uses Term::ReadKey and/or local system commands to guess the terminal size, clear the screen, and read the keyboard. Optionally uses Term::ReadLine to provide line-editing history, assuming a backend readline module is available (e.g. Term::ReadLine::Perl). While there is no status line or multiple window support, this interface is perfectly adequate for playing most version 3 games. Can be forced with ``-dumb''.
Makes use of the standard Term::Cap module to provide support for a status line and multiple windows. I've had difficulties making the last line on the display usable while reading from STDIN or Term::ReadLine; it seems the line-terminating newline entered by the user scrolls the screen, wiping out the status line. Maybe there's a simple termcap feature to help with this; advice would be appreciated.
So, by default the termcap interface avoids using the last line on your display. There's an experimental workaround you can try that doesn't seem to work on all systems; enable it by specifying ``-flaky 1'' on the command line. This will only work if the program can figure out how to read characters one at a time from the terminal, and it also breaks Term::ReadLine support.
Usage of the Termcap interface can be forced with ``-termcap''.
Use the Curses module to improve upon the features available in the Termcap interface, adding support for color, clean access to all the lines on the screen, better keyboard handling, and some support for character graphics. Some problems remain: if you specify screen colors, the terminal may not be reset correctly when the program exits. Also, I've only tested this with a few versions of Curses (Linux/ncurses and Digital Unix's OEM curses), and was unpleasantly surprised by the difficulties I encountered getting this to work properly under both of them. Can be forced with ``-curses''.
Uses the Win32::Console module to act much like the Curses version. Only works under win32 (Windows 95, 98, etc). Force with ``-win32''.
Uses the Tk module; supports variable-width fonts and color. Requires the 800+ series of Tk; tested under Linux and the ActiveState binary distribution of perl under win32. Force with ``-tk''.
Rezrov emulates a number of in-game commands which were either not or only sporadically available in version 3 games:
>give lmap to troll I don't know the word "lmap".
>oops lamp The troll, who is not overly proud, graciously accepts the gift and not having the most discriminating tastes, gleefully eats it. You are left in the dark...
If the entered word is in the dictionary, behave normally.
If the length of the word is less than 3 letters long, give up. We don't want to make assumptions about what very short words might be.
If the word is the same as a dictionary word with one
transposition, assume it's that word ("exmaine" becomes
"examine").
If it is a dictionary word with one deleted letter, assume it's
that word ("botle" becomes "bottle").
If it is a dictionary word with one inserted letter, assume it's
that word ("tastey" becomes "tasty").
If it is a dictionary word with one substitution, assume it's
that word ("opin" becomes "open").
Typo correction is enabled by default. While often helpful, it may not be desirable in some games which expect the user to enter non-dictionary words (i.e. Beyond Zork). It can be disabled on the command line with ``-typo 0''.
Rezrov also expands the following ``shortcut'' commands for games that do not support them:
x = "examine"
g = "again"
z = "wait"
l = "look"
o = "oops"
The ``-cheat'' command-line parameter enables the interpretation of several fun new verbs. Using these commands in a game you haven't played honestly will most likely ruin the experience for you. However, they can be entertaining to play around with in games you already know well. Note that none of them work if the game understands the word they use; for example, ``Zork I'' defines ``frotz'' in its dictionary (alternate verbs are available). You can turn cheating on and off from within the game by entering ``#cheat''.
Robot Shop This room, with exits west and northwest, is filled with robot-like devices of every conceivable description, all in various states of disassembly. Only one robot, about four feet high, looks even remotely close to being in working order.
>open robot In one of the robot's compartments you find and take a magnetic-striped card embossed "Loowur Elavaatur Akses Kard."
>turn on robot Nothing happens.
>wait Time passes...
Suddenly, the robot comes to life and its head starts swivelling about. It notices you and bounds over. "Hi! I'm B-19-7, but to everyperson I'm called Floyd. Are you a doctor-person or a planner-person? That's a nice lower elevator access card you are having there. Let's play Hider-and-Seeker you with me."
>show access card to floyd "I've got one just like that!" says Floyd. He looks through several of his compartments, then glances at you suspiciously.
- "Planetfall", 1983
I'd be very curious to know about any easter eggs this command might uncover. For example, in Planetfall there is a blacked-out room you can't see anything in. There's a lamp in the game, but it's located in a lab full of deadly radiation. You can enter the lab and take the lamp, but will die of radiation poisoning before you can make it back to the darkened room.
I always wondered, if you could get the lamp somehow, what was in the dark room? Now you can find out.
While this is just a simple tweak, turning on a particular object property, exactly *which* property varies by game and I know of no easy way to determine this dynamically, so at present this only works in a few games: Zork I, Zork II, Zork III, Zork: The Undiscovered Underground, Infidel, and Planetfall (I'm taking requests).
>i
You are carrying:
A brass lantern (providing light)
A leaflet
>north
The Troll Room
This is a small room with passages to the east and south
and a forbidding hole leading west. Bloodstains and deep
scratches (perhaps made by an axe) mar the walls.
A nasty-looking troll, brandishing a bloody axe, blocks all
passages out of the room.
>kill troll with leaflet
Trying to attack the troll with a leaflet is suicidal.
>travis leaflet
The leaflet glows wickedly.
>kill troll
(with the leaflet)
Your leaflet misses the troll by an inch.
The axe crashes against the rock, throwing sparks!
>g
You charge, but the troll jumps nimbly aside.
The troll's axe barely misses your ear.
>g
It's curtains for the troll as your leaflet removes his head.
Almost as soon as the troll breathes his last breath, a
cloud of sinister black fog envelops him, and when the fog
lifts, the carcass has disappeared.
>
West of House You are standing in an open field west of a white house, with a boarded front door. There is a small mailbox here.
>kill mailbox (with the sword) I've known strange people, but fighting a small mailbox?
>vilify mailbox That small mailbox is really asking for trouble.
>kill mailbox (with the sword) Clang! Crash! The small mailbox parries. Your sword has begun to glow very brightly.
>g The quickness of your thrust knocks the small mailbox back, stunned.
It takes a talented person to be killed while already dead. YOU are such a talent. Unfortunately, it takes a talented person to deal with it. I am not such a talent. Sorry.
spiel takes up to 3 arguments, all optional. The first argument is the memory address to start decoding text. The default is the start of static memory, which is often a bit early. 20000 is usually a good starting point for version 3 games. The second argument is the level of detail to show. This is a number from 1 to 4:
1: Unconditionally show whatever's decoded from each possible address.
2: Like 1, but if a chunk of text is decoded that passes the various junk filters, continues decoding after it rather than at the next byte. Still shows ``bad'' text.
3: don't show text I suspect is junky. Subjective but pretty effective.
4: only show text we're highly confident of. This is the default setting.
The third argument is the minimum number of decoded words that must be present in a fragment to consider it good under most circumstances. Defaults to 3.
Speech synthesis and recognition capabilities are available under Windows via the Win32::SAPI4 Perl module, which must be installed separately, along with Microsoft's SAPI4 speech API distribution. As of this writing (March 2004), SAPI4 seems to be on the verge of being obsoleted by Microsoft, but it works fine on my Windows XP system. The API distribution is about a 40 MB download, search for ``SAPI4SDKSUITE.EXE''. Here's one link, though YMMV:
http://download.microsoft.com/download/speechsdk/Install/4.0a/win98/EN-US/SAPI4SDKSUITE.EXE
The SAPI4 speech recognition API requires voice training to work well. Use the Microsoft Voice and Dictation tools to set up your microphone and train the system to recognize your voice. Be sure you are able to run the Microsoft Dictation pad and dictate with reasonable success before attempting to use voice recognition with Rezrov.
Dictation must be enabled within the Microsoft Dictation application for speech recognition to work.
Rezrov's speech recognition support should be considered highly experimental, and it can be a pain to get running. But it's fun when it works!
Several command-line flags allow you to observe some of the internal machinations of your game as it is running. These options will probably be of limited interest to most people, but may be the foundation of future trickery.
West of House There is a small mailbox here.
>north [Move "cretin" to "North of House"] North of House You are facing the north side of a white house. There is no door here, and all the windows are boarded up. To the north a narrow path winds through the trees.
When using the Curses interface, allowable colors are black, blue, cyan, green, magenta, red, white, and yellow.
When using the Win32::Console interface, allowable colors are black, blue, lightblue, red, lightred, green, lightgreen, magenta, lightmagenta, cyan, lightcyan, brown, yellow, gray, and white. Note that the program tries to shift to lighter colors to simulate ``bold'' text attributes: bold blue text uses lightblue, bold gray text uses white, etc. For this reason it looks best if you not use white or any of the ``light'' colors directly (for ``white'' text, specify ``gray'').
If you have the Term::ReadLine module installed (and a backend such as
Term::Readline::Perl), support for it is available in the dumb,
termcap, and curses interfaces. By default support is enabled in the
``dumb'' module and ``termcap'' interfaces, and disabled in the curses
interfaces (because it doesn't work right :P ). You can
enable/disable support for it with the ``-readline'' flag: ``-readline 1''
enables support, and ``-readline 0'' disables it.
Undo emulation works by creating a temporary saved game in memory between every command you enter. To disable undo emulation entirely, specify a value of zero (0).
1 DECSystem-20 5 Atari ST 9 Apple IIc 2 Apple IIe 6 IBM PC 10 Apple IIgs 3 Macintosh 7 Commodore 128 11 Tandy Color 4 Amiga 8 Commodore 64
The default is 6, IBM PC. This only seems to affect gameplay for a few games, notably ``Beyond Zork''.
My primary goal has been to write a z-code interpreter in Perl which is competent enough to play my favorite old Infocom games, which are mostly z-code version 3. Infocom's version 3 games are Ballyhoo, Cutthroats, Deadline, Enchanter, The Hitchhiker's Guide To The Galaxy, Hollywood Hijinx, Infidel, Leather Goddesses of Phobos, The Lurking Horror, Moonmist, Planetfall, Plundered Hearts, Seastalker, Sorcerer, Spellbreaker, Starcross, Stationfall, Suspect, Suspended, Wishbringer, The Witness, and Zork I, II, and III. These all seem to work pretty well under the current interpreter.
Version 4 and later games introduce more complex screen handling and difficult-to-keep-portable features such as timed input. Later games also introduce a dramatic increase in the number of opcodes executed between commands, making a practical implementation more problematic. For example, consider the number of opcodes executed by the interpreter to process a single ``look'' command:
Zork 1 (version 3): 387 opcodes
Trinity (version 4): 905 opcodes
Zork: The Undiscovered Underground (version 5): 2186 opcodes (!)
While rezrov can run most of these games, if you seriously want to *play* them I recommend you use an interpreter written in C, such as frotz or zip; these are much faster and more accurate than rezrov.
A secondary goal has been to produce a relatively clean, compartmentalized implementation of the z-machine that can be read along with the Specification (see acknowledgments section). Though the operations of the interpreter are broken into logical packages, performance considerations have kept me from strict OOP; more static data remains than is Pretty. The core StoryFile.pm package, formerly quasi-OO, has been flattened to plain functional style in a crass attempt to make the program run faster. The Perl version is actually based on my original version of rezrov, which was written in Java.
rezrov would not have been possible to write without the work of the following individuals:
http://www.gnelson.demon.co.uk/zspec/
http://www.ifarchive.org/if-archive/README
http://www.ifarchive.org/if-archive/infocom/interpreters/specification/zspec02/
http://www.ifarchive.org/if-archive/infocom/interpreters/zip/
http://www.ifarchive.org/if-archive/infocom/interpreters/specification/savefile_14.txt
http://www.ifarchive.org/if-archive/infocom/interpreters/tools/
>read dusty book The first page of the book was the table of contents. Only two chapter names can be read: The Legend of the Unseen Terror and The Legend of the Great Implementers.
>read legend of the implementers This legend, written in an ancient tongue, speaks of the creation of the world. A more absurd account can hardly be imagined. The universe, it seems, was created by "Implementers" who directed the running of great engines. These engines produced this world and others, strange and wondrous, as a test or puzzle for others of their kind. It goes on to state that these beings stand ready to aid those entrapped within their creation. The great magician-philosopher Helfax notes that a creation of this kind is morally and logically indefensible and discards the theory as "colossal claptrap and kludgery."
- "Enchanter", 1983
Bug? Not in a flawless program like this! (Cough, cough).
- Zork I (encoded at byte 29292 of revision 88)
While I've tried, the interpreter is not fully compliant with the
specification in some areas. With that said, I currently know of no
flaws that prevent version 3 games from being perfectly playable.
Version 4 games (A Mind Forever Voyaging, Bureaucracy, Nord and Bert
Couldn't Make Head or Tail of It, and Trinity) I'm less sure about,
this complicated by the fact that I haven't completed any of them :)
Version 5 games (Beyond Zork, Border Zone, Sherlock) seem to work to
the limited extent I've played them, but there are a few unimplemented
opcodes that I have yet to see used. The only version 8 game I've
tried has been ``anchorhead'', which runs, but is unbearably slow on my
P133. YMMV.
Things I need:
>up Jewel Room This fabulous room commands a magnificent view of the Lonely Mountain which lies to the north and west. The room itself is filled with beautiful chests and cabinets which once contained precious jewels and other objets d'art. These are empty. Winding stone stairs lead down to the base of the tower. There is an ornamented egg here, both beautiful and complex. It is carefully crafted and bears further examination.
>get egg then examine it Taken.
This ornamented egg is both beautiful and complex. The egg itself is mother-of-pearl, but decorated with delicate gold traceries inlaid with jewels and other precious metals. On the surface are a lapis handle, an emerald knob, a silver slide, a golden crank, and a diamond-studded button carefully and unobtrusively imbedded in the decorations. These various protuberances are likely to be connected with some machinery inside. The beautiful, ornamented egg is closed.
>read spell book
My Spell Book
The rezrov spell (open even locked or enchanted objects). The blorb spell (safely protect a small object as though in a strong box). The nitfol spell (converse with the beasts in their own tongue). The frotz spell (cause something to give off light). The gnusto spell (write a magic spell into a spell book).
>learn rezrov then rezrov egg Using your best study habits, you learn the rezrov spell.
The egg seems to come to life and each piece slides effortlessly in the correct pattern. The egg opens, revealing a shredded scroll inside, nestled among a profusion of shredders, knives, and other sharp instruments, cunningly connected to the knobs, buttons, etc. on the outside.
- "Enchanter", 1983
Michael Edmonson <edmonson@sdf.lonestar.org>
Rezrov homepage: http://edmonson.paunix.org/rezrov/