bocfel — Z-machine
bocfel is a Z-machine interpreter. It
fully supports versions 1-5, 7, and 8 of the Z-machine, with extremely
limited support for version 6. It can read stories stored in Blorb files,
but has no support for associated graphics, if any exist.
The following options are available:
The maximum value is limited only by system memory. Each evaluation stack entry takes two bytes. If you ever encounter a “stack overflow” message with the default size, please let me know.
The maximum value allowable by the Z-machine is 65535. Each call stack entry takes between 40 and 50 bytes.
-eoption is used, this sets the escape string that will be used when highlighting user input in the transcript. ^[[ is written, then escape_string, then ^[[0m. By default “1m” is used as the escape string, providing bold text.
bocfelis being run in a terminal (with, for example, the glktermw Glk implementation), the font will be fixed at all times. The
bocfelto assume that the current font is always fixed, allowing other styles to be applied simultaneously. See the puzzle pieces in Graham Nelson's Jigsaw for an example of how this can be useful.
See also the STYLES section. Note that Gargoyle does allow the mixing of styles, so this option does nothing under Gargoyle.
Most characters in the graphics font map fairly well to Unicode equivalents, but a few box drawing characters do not. Two methods for drawing the missing characters are provided, each with pros and cons. A description of the differences is not sufficient, so it is recommended that you try Beyond Zork both with and without this option, paying attention to the map connections. See also the CHARACTER GRAPHICS FONT section below.
bocfelincludes a snapshot of the screen state (more or less) in order to play it back on restore to provide context as to what was happening before the game was saved. This flag disables playback of history. Note that history will still be stored on save even when this option is selected; it just won't be played back on restore.
By and large this value is meaningless. Some Infocom games do make small use of this information: Trinity, for example, has a “print emphasized” routine that is used to print emphasized (which generally means italicized) text; on any machine but the Atari, however, this routine makes sure not to print punctuation in italics. Beyond Zork makes what is probably the most visible use of the interpreter number, using it to decide how to deal with character graphics. See section 16 of the Z-Machine Standards Document 1.1 for more information. By default, the interpreter version is set to 1 becuase this causes Beyond Zork to prompt the user about the machine he is using, allowing him to select whether or not character graphics are used.
I do not recommend setting this to 11. At least Beyond Zork assumes that the largest it will be is 10, and setting it to 11 can cause an out-of-bounds memory access. The instance I have seen of this is not fatal, but there may be other instances that are.
bocfelincludes patches to work around some known bugs in games. This flag disables such patches.
-s) as soon as the game begins. Some games provide a way to play back a record (typically through the REPLAY verb in Inform-based games, and #comm in some Infocom games), but this option is useful to start playback before you have an opportunity to call REPLAY, or if the game provides no way to play back such a record.
Command records must be UTF-8.
See also the META COMMANDS section.
-ror through a game command. Some games provide this functionality themselves (typically through the RECORDING verb in Inform-based games, and #reco in some Infocom games), but this option is useful to start recording before you have an opportunity to call RECORDING, or if the game provides no way to start such a record.
Command records are always written in UTF-8.
See also the META COMMANDS section.
Transcripts are always written in UTF-8.
See also the
-y option and the
META COMMANDS section.
-A), save slots are dynamic, meaning that unless a game provides support for undo, no memory will be used. However, games that do support undo will typically take a snapshot each turn, causing memory to be allocated. The size of each snapshot depends on the game and the current state of play. Memory usage is minimized as much as possible: at the beginning of Anchorhead, for example, each slot takes up roughly 900 bytes. As the game progresses, though, the size of a save slot inevitably will increase: near the end of Anchorhead, my save slots were taking up roughly 4500 bytes.
Note that Inform-based games (at least by
default) do not support multiple undo; two non-V6 Infocom games, to my
Beyond Zork. However,
includes the ability to perform multiple undo regardless of whether the
game provides support for it. See the
META COMMANDS section for more
The default value is 100. A value of zero disables undo.
bocfelto ignore the game's undo code, instead using only its own undo handling. This might work if the game's undo handling is subpar, either by design or by accident. Note that if this option is active, /undo must be used instead of the game's UNDO command.
-Zoption overrides this option.
bocfelwill switch to using a pseudo-random number generator. If the game is put into predictable mode via a negative operand to @random, a pseudo-random number generator will be used until the game switchs back to random mode.
bocfel allows to you control its behavior
through a configuration file. This obviates the need to provide command-line
arguments each time you start a game, as well as allowing customization
based on which game is being played.
On Unix, the configuration file is located at $XDG_CONFIG_HOME/bocfel/bocfelrc. For legacy reasons, if the file $HOME/.bocfelrc exists, it will be used instead. On Windows, the configuration file is located at %APPDATA%\Bocfel\bocfel.ini. An outline of the config file is as follows:
enable_escape = 1 disable_color = 1 [1-990831-d8b4] disable_color = 0 [57-871221] int_number = 1
The first lines are general, and apply to all games. The bracketed
lines start a new group based on the ID contained in the brackets (see the
-i option). Thus disable_color is set to zero only
for 1-990831-d8b4, and int_number is set to 1 only for
57-871221. Comments begin with a # and continue to the
end of the line. Trailing whitespace is ignored.
The following are all the possible options, which are hopefully self-explanatory:
The parenthesized character describes the type of argument: b is a boolean (1 is true, 0 is false), c is a character, n is a number, and s is a string. These all correspond to possible command-line arguments.
In addition to analogs to the command-line arguments, there are a few other options that can be set through the configuration file:
bocfelwill perform a save each time input is read, silently storing the save file to a persistent location on disk. On startup, if that file exists and is a valid save file, it will be loaded. This allows players to continue from where they left off without needing to explicitly save. If the user explicitly quits the game (usually via the QUIT command, but in fact any time the @quit opcode is called), the autosave file will be removed, allowing the game to start from the beginning next time.
Autosaving is not perfect: history is saved and replayed, but only in the lower window. The contents of the upper window, if it is being used, are not saved. That means that if the upper window is in use, it will likely look incorrect after autorestore, because the game will not know it needs to redraw it. This might be something that's quickly corrected by the game (e.g. if it redraws the upper window each turn), but it might not be.
To enable this feature, set the “autosave” option, in the configuration file, to true (1). By default, autosaving is disabled. At the moment, this feature is available only on Unix and Windows. The location of autosave directory is $XDG_DATA_HOME/bocfel/autosave on Unix and %APPDATA%\bocfel\autosave on Windows.
bocfelwill automatically keep a transcript of the entire game session, irrespective of whether “official” transcripting provided by the Z-machine is turned on. This transcript can be saved to a file with the /savetranscript meta command (see the META COMMANDS section below). In addition, the transcript will be stored in save files, including, if enabled, autosave files. This means that transcripts will persist across sessions, so you will have the full transcript without having to remember to turn it on, or where you stored it.
To enable this feature, set the “persistent_transcript” option, in the configuration file, to true (1).
bocfelallows the user to take notes in an external text editor and will include the notes in save files to allow notes to be associated with a particular gaming session across saves and restores. In addition, the configuration file can be edited via a text editor launched by
bocfel. On Windows and macOS, the system text editor is used. On other Unix platforms, a default list of GUI text editors is tried. If you want to set a specific text editor, the “editor” configuration entry can be set to whichever editor you would like. This is either an absolute path to an editor (e.g. /usr/bin/kate) or the name of an executable in the path (e.g. kate). The editor must not run in the background, or else
bocfelwon't be able to determine when it has exited. Some editors fork into the background by default, but can be told to stay in the foreground instead with a flag such as --nofork.
bocfelhas some built-in patches to fix bugs in games, but if new patches are needed, they can also be added via the configuration file, meaning you do not have to wait for a new
bocfelrelease in order to provide a patch. The syntax is as follows:
patch = 0xd3d4 3 [0x31, 0x0c, 0x73] [0x51, 0x73, 0x0c]
This indicates that 3 bytes at address 0xd3d4 are being replaced. The first bracketed set of bytes indicates the expected existing bytes, and the second bracketed set of bytes indicates the replacement bytes. The replacement set must be the same size as the existing set. Such patches should be included only in a specific game's group; otherwise they will be applied to all games, which is generally a bad idea.
At the most basic, there are 8 colors that the Z-machine can use, corresponding to ANSI colors: black, red, green, yellow, blue, magenta, cyan, and white. The syntax for setting these is:
color_red = 0xc23621
The color is specified as a 24-bit RGB value, 8 bits per color. The above is thus 0xc2 red, 0x36 green, and 0x21 blue. The value must be specified in hexadecimal, with an optional leading 0x.
The Z-machine allows for different text styles to be selected:
these are emphasized (typically italicized or underlined), bold, and reverse
video. In addition, a fixed-width font can be selected. Glk does not
guarantee the appearance of styles; it only allows you to select from a list
of uses, rather than appearances. The following Glk styles are how
bocfel maps the Z-machine's text styles:
Italic (or emphasized) uses the Emphasized style. Bold uses the Subheader style. Reverse video uses the Alert style. Fixed-width uses the Preformatted style.
These were chosen because they map appropriately in the glktermw Glk implementation. If your Glk implementation does not render these styles in a manner you like, consult its documentation to see if it is possible to change the appearance of the various Glk styles.
Gargoyle, although a Glk implementation, does not have these issues. The combination of styles is possible, and the appearance of styles can be guaranteed.
Beyond Zork can make use of a character graphics font. This font is used for drawing the interactive map, arrows, and runes. Most of the runes and arrows have Unicode equivalents and can be displayed if you have a font that contains these characters. Unicode also includes box-drawing characters which can be used to approximate the map in Beyond Zork. These are not perfect, but they are not terrible.
-g option disables the character
graphics font, but unfortunately the ability to tell a game that a
particular font is unavailable postdates Infocom, so this flag will not
prevent Beyond Zork from trying to use it. Instead,
Beyond Zork makes use of the interpreter number (see
-n) to decide whether to use character graphics. If
you are using a font that does not provide the necessary Unicode characters,
you will want to run Beyond Zork without the character
graphics font. This is easily accomplished by answering “No”
when the game asks you if you are using a VT-220 (this only happens when the
interpreter number is set to 1, which is the default).
If the character font is disabled with
and a game tries to use it anyway (as is the case with Beyond
Zork), the output will appear garbled, but only for that font. Anything
the game prints out in a normal font will look fine.
See section 16 of the Z-Machine Standards Document 1.1 for more information.
bocfel includes support for “meta
commands”, which are commands interpreted by
bocfel itself instead of the game. These are
introduced with a slash
chosen in an attempt to not clash with game commands. These meta commands
can be entered at any point the game requests user input, e.g. on each turn.
They are as follows, and are case sensitive:
bocfelhas built-in protection to prevent a file saved with a normal SAVE command from being confused with one saved by /save, and vice versa.
Because it creates non-standard save files, this command
should be avoided unless it is absoulutely necessary, e.g. if the game
has disabled saving. It was added to
solely for the case of such anti-social games.
This is meant to serve as an alternative to on-disk save files for when you are trying something dangerous in a game. In such a case, there is generally no need for a save file to be stored on the disk because the save state is not meant to be persistent: it only needs to last long enough to be restored in the same session.
Because a stack is used, /ps can be used multiple times, allowing you to jump backward as many times as there are states. The maximum number of states stored is 25. Once this number of states is reached, each new state causes the oldest state to be dropped.
Please note that at the current time, any characters which are not printable ASCII characters will be replaced with a question mark.
bocfel's configuration file in a text editor.
Please note that /save and /restore are experimental.
Mixing in-memory saves with undo can have odd effects. For example, if a save state is pushed, and undo is then called multiple times, returning to a point which occurred before the /ps call, popping the save state will still jump to the /ps save position, effectively cancelling the undo calls. The undo states will not be recreated. Similarly, if undo is called right after /pop, it will succeed, but will not undo the /pop call. Instead, the effect is the same as if undo had been called on the turn before /pop was called. This is because meta commands are not considered game commands and thus do not cause undo states to be stored.
The /debug command starts a debugging operation. For some debugging operations, an address is expected. This is either an absolute address, specified in hexadecimal with an optional leading 0x, or it is a global variable. Global variables have the syntax Gxx, where xx is a hexadecimal value in the range [00, ef], corresponding to global variables 0 to 239.
The debug commands are as follows:
Please note that it is possible for
bocfel to be built without cheating support, so
this and related commands might not work.
Please note that it is possible for
bocfel to be built without watch support, so
this and related commands might not work.
Sound effects are supported under Glk, assuming the Glk library supports sound. The sound effects should be bundled in a Blorb file. If the story file itself is stored in a Blorb file, that file is used to find the sound effects. Otherwise, a separate Blorb file must exist and be named as follows: if the story file is /foo/bar/sherlock.z5, then the Blorb file must be /foo/bar/sherlock.blb.
Bleeps (sound effects 1 and 2) are supported under sufficiently modern Gargoyle releases.
There is extremely rudimentary support for
bocfel is able to freeze
certain areas of memory so that they always report the same value. The idea
behind this is to prevent hunger and thirst counters from forcing you to eat
Cheating is available through the configuration file as well as through meta debug commands (see META DEBUG COMMANDS for information on using meta debug commands to cheat).
When the configuration file is used, cheats are treated like any other configuration variable. The syntax is as follows: freeze:address:value.
This causes the word (an unsigned 16-bit value) at address address to always contain the value value; value can be decimal, hexadecimal, or octal, with a leading 0x signifying hexadecimal and a leading 0 signifying octal.
cheat = freeze:0xabcd:0 cheat = freeze:G00:0
Visit http://bocfel.org/cheats/ for a list of a few cheats for some Infocom games. More cheats are potentially discoverable using meta debug commands (see the META DEBUG COMMANDS section). A more detailed explanation of how to figure out cheats is beyond the scope of this document.
Please note that it is possible for
to be built without support for cheating, in which case these cheats will
silently do nothing. The
-v option can be used to
determine whether this is the case.
The Z-machine provides the ability for games to load and save
files on the host system (see section 7.6 of version 1.1 of the Z-machine
bocfel confines these files to
game-specific directories so that games are unable to overwrite arbitrary
files on the host system. The game-specific directories are places in
platform-specific locations. On Unix, this directory is
$XDG_DATA_HOME/bocfel/auxiliary. On Windows, it is
%APPDATA%/Bocfel/auxiliary. The individual game
directories are the game IDs as reported by the
bocfel is believed to comply fully with
version 1.1 of The Z-machine Standards Document; see
Chris Spiegel ⟨email@example.com⟩
|September 16, 2021|