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 nearly 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. Usage of the dumb interface can be forced with the "-dumb" command-line switch.


Makes use of the standard Term::Cap module to provide support for a status line and multiple windows. 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".

Windows console

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".


The simplest output model, even more stripped-down than the Dumb interface. It is meant for use in automated testing rather than interactive play, and to have no external dependencies. The interface has the following restrictions:

Obviously this interface is only appropriate for games with the simplest I/O requirements. On the other hand, it "should" work on any Perl installation. I've received some reports from CPAN testers where even the "dumb" interface fails in ways I can't reproduce, probably related to the gyrations that module goes through to perform single-character input (via and detect the screen size (via Hopefully this interface will address these problems, and so now uses it. Use the "-test" command-line switch to enable.


Advanced command emulation

Rezrov emulates a number of in-game commands which were either not or only sporadically available in version 3 games:

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".

Speech synthesis and recognition

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:

Command-line option to enable speech synthesis (you may also type "#speak" during the game at the command prompt to toggle it on or off). When speech synthesis is enabled, the game will speak the game text as well as print it to the screen. This will not work well with games using multiple windows.


Command-line option to enable speech recognition (you may also type "#listen" at the command prompt to enable it). When speech recognition is enabled, the game will listen for you to speak commands into your computer's microphone rather than type them at the keyboard. Once enabled, control will only be returned to the keyboard if dictation is disabled in the Microsoft Dictation control panel. In future releases of Rezrov, event-driven interfaces (such as Tk) may allow simultaneous voice and keyboard input.

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!


Command-line option to enter speech recognition debugging mode. This will display speech recognition events as they are processed by the system. More work needs to be done to explain incoming events.


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.


Whenever an object in the game is moved, it tells you the name of the object and where it was moved to. Using this feature you can, among other things, see the name Infocom assigned to the "player" object in a number of their early games:

 West of House
 There is a small mailbox here.
 [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.

Each object in the game has a list of properties associated with it. This flag lets you see when object properties are changed. As an example, in my version of Zork 1 the "blue glow" given off by the sword in the presence of enemies is property number 12 (1 for "a faint blue glow" and 2 for "glowing very brightly").


Likewise, each object has an associated list of single-bit attributes. This flag lets you observe when object attributes are set. As an example, in my version of Zork I the "providing light" attribute is number 20. Tweaking of this attribute is the foundation of "frotz" emulation (see "Cheating" below).


This option lets you see when object attributes are tested.


This option lets you see when object attributes are cleared.


Highlights object descriptions in the text printed out via the print_obj opcode (1OP, 0x0a).

Interface flags

-fg, -bg

If the interface you want to use supports colored text, this allows you to specify foreground (text) and background colors used in the game. If you specify one you must specify the other, i.e. you cannot specify just the foreground or background color. Example: "-fg white -bg blue".

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").

-sfg, -sbg

Specifies the foreground and background colors use for the status line in version 3 games; the same restrictions apply as to -fg and -bg. These must also be used as a pair, and -fg and -bg must be specified as well. Example: "-fg white -bg blue -sbg black -sfg white".


Specifies the color of the cursor. At present this only works for the Tk interface, and defaults to black. Note that if the game changes the screen's background color to the cursor color, the cursor color will be changed to the foreground color to prevent it from "disappearing". This happens in "photopia", for example.

-columns, -rows

Allows you to manually specify the number of columns and/or lines in your display.


Updates the screen with every line printed, so scrolling is always visible. As this disables any screen buffering provided by the I/O interface it will slow things down a bit, but some people might like the visual effect.

Tk-specific flags

-family [name]

Specifies the font family to use for variable-width fonts. Under win32, this defaults to "Times New Roman". On other platforms defaults to "times".

-fontsize [points]

Specifies the size of the font to use, as described in Tk::Font. Under win32 this defaults to 10, on other platforms it defaults to 18. If your fonts have a "jagged" appearance under X you should probably experiment with this value; for best results this should match a native font point size on your system. You might also try using the "xfstt" TrueType font server, which I've had very good results with under Linux.

-blink [milliseconds]

Specifies the blink rate of the cursor, in milliseconds. The default is 1000 (one second). To disable blinking entirely, specify a value of 0 (zero).

-x [pixels]

Specifies the width of the text canvas, in pixels. The default is 70% of the screen's width.

-y [pixels]

Specifies the height of the text canvas, in pixels. The default is 60% of the screen's height.

Term::ReadLine support

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.

Miscellaneous flags


Displays the game time in "time" games (Deadline, Suspect, etc) in 24-hour format rather than 12-hour AM/PM format.


Disables usage of the "font 3" character graphics font. Generally only has meaning in Beyond Zork when using the Tk or Curses interfaces. Font 3 support is incomplete so you'll probably need this if you're playing Beyond Zork for any length of time.

-debug [file]

Writes a log of the opcodes being executed and their arguments. If a filename is specified, the log is written to that file, otherwise it is sent to STDERR.


Prints a count and summary of the opcodes executed by the game between your commands.

-undo turns

Specifies the number of turns that can be undone when emulating the "undo" command; the default is 10 turns.

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).

-playback file

When the game starts, reads commands from the file specified instead of the keyboard. Control is returned to the keyboard when there are no more commands left in the file. Useful for testing, especially with the "-test" output interface.


Disables rezrov's attempts to guess the name of the game you're playing for use in the title bar. To guess the title, rezrov actually hijacks the interpreter before your first command, submitting a "version" command and parsing the game's output. This can slow the start of your game by a second or so, which is why you might want to turn it off. This also currently causes problems with the Infocom Sampler (sampler1_R55.z3) and Beyond Zork, for which title guessing is automatically disabled.


Specifies the ID number used by the interpreter to identify itself to the game. These are the machine ID numbers from section 11.1.3 of Graham Nelson's z-machine specification (see acknowledgments section):

   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 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:


   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:


 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     
 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
 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
 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 <>

Rezrov homepage: