BOCFEL(6) Games Manual BOCFEL(6)

bocfelZ-machine interpreter ⟨https://bocfel.org/

bocfel [-cCdDefFgGhHkmprstxXyY] [-a eval_stack_size] [-A call_stack_size] [-E escape_string] [-l username] [-n number] [-N version] [-R replay_filename] [-S record_filename] [-T transcript_filename] [-u slots] [-z seed] [-Z device] file

bocfel -i file

bocfel -v

TABLE OF CONTENTS

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:

eval_stack_size
The Z-machine contains an evaluation stack which games use as a sort of scratch space when performing calculations. By default the size of this stack is set at 16384, which should be sufficient for any game. The entire stack is allocated at once, so if you are on a system with a small amount of memory, setting this to a smaller value will cause less memory to be allocated.

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.

call_stack_size
The Z-machine allows games to call routines in order to get work done; these routines can call other routines, and so on. Information about these routines is placed onto the call stack, which by default has a size of 1024. This means that no more than 1024 routines can be active at any single time. This value should be much more than sufficient for any game. As with the evaluation stack, memory for the call stack is allocated at one time, so machines with small amounts of memory can reduce this value to reduce memory consumption.

The maximum value allowable by the Z-machine is 65535. Each call stack entry takes between 40 and 50 bytes.

If the Glk implementation being used is Gargoyle, or if Glk is not being used at all, support for colors is provided. This option disables color support entirely.
Do not read the configuration file. Settings in the configuration file take precedence over those specified on the command line, so if you want to override the configuration file, use this option.
Many Glk implementations allow timed input as used by games such as . This option disables timed input and informs games that timed input is not available.
If Gargoyle is being used, sound effects are supported. This option disables sound effects and informs games that sound effects are not available.
Turn on ANSI escapes in the transcript. If this option is enabled, all user input in the transcript can be decorated with ANSI escape sequences so it stands out. See the -E option.
escape_string
If the -e option 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.
Many Glk implementations allow a fixed-width font to be selected. This option disables fixed-width fonts and informs games that fixed-width fonts are not available. The game might still be displayed using a fixed-width font (e.g. if you are playing in a terminal), but the game has no way of knowing this.
Glk does not allow the mixing of text styles, so it is not possible to request, for example, both fixed-width and reverse video. If both styles are requested, fixed-width takes precedence. However, if bocfel is being run in a terminal (with, for example, the glktermw Glk implementation), the font will be fixed at all times. The -F flag tells bocfel to assume that the current font is always fixed, allowing other styles to be applied simultaneously. See the puzzle pieces in Graham Nelson's 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.

Disable the character graphics font. See the CHARACTER GRAPHICS FONT section below.
Select an alternative style of box drawing characters.

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.

Display a short help message then exit.
Disable save history playback. When saving, bocfel includes 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.
Print out the ID of the specified game and exit. This ID is used to uniquely identify a game and is adapted from the Treaty of Babel standard. Game IDs can be used in the configuration file to set options for specific games. See the CONFIGURATION FILE section for more information.
The Z-machine has a concept of “terminating keys”. When enabled, these keys, in addition to Enter, terminate input immedately. Beyond Zork, for example, uses this so that F1 automatically executes “look around”, F2 does “inventory”, and so on. However, Beyond Zork also claims the up arrow, which means that history browsing, in Glk implementations that support it, might not be able to be initiated with the up arrow. This option disables the use of terminating keys. Note that not all Glk implementations support terminating keys.
username
Set the username by writing up to 8 bytes to the location in the story file. This is not officially part of the Z-machine, but is at least used by , where a username starting with either “DA” or “TOMAS” enables the debugging command “flush 33” which moves you to a junction room which leads to various other locations, allowing puzzles to be bypassed.
Disable meta commands. See META COMMANDS below for more information.
number
Z-machine interpreters are able to inform games what platform they are running on by setting an interpreter number in the range 1 to 11. The following are the valid values (taken from Graham Nelson's Z-Machine Standards Document 1.1):

  1. DECSystem-20
  2. Apple IIe
  3. Macintosh
  4. Amiga
  5. Atari ST
  6. IBM PC
  7. Commodore 128
  8. Commodore 64
  9. Apple IIc
  10. Apple IIgs
  11. Tandy Color

By and large this value is meaningless. Some Infocom games do make small use of this information: , 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.

Version 6 games are another matter, however. Due to graphics and mouse support requiring more knowledge of the underlying hardware platform, version 6 games tend to check this value more often. Most version 6 testing has been done with the value set to 1. It's entirely possible that other values will not have material effects on gameplay, but they might. As incompatibilities are discovered, bocfel will be updated to work around them, but be prepared for (even more) potential unexpected behavior in version 6 games if this is set to anything other than 1.

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.

version
Even more meaningless than the interpreter number is the interpreter version. This, as far as has been determined, is never used except when the user asks a game to either report its version or to verify its disk image. In these cases, the version is simply printed out, nothing more. This is a single character and there is no real reason to change it. The default is C.
bocfel includes patches to work around some known bugs in games. This flag disables such patches. Note that user patches provided in the config file (via “patch”) will still be applied.
Play back a command record (see -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.

replay_filename
When command-record playback is enabled, you will be prompted for a filename. This prompt can be bypassed by providing a filename here.
Turn on command recording. This records every keystroke the player makes, and (hopefully) creates a record that is suitable for playback either by using -r or 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.

record_filename
When command recording is enabled, you will be prompted for a filename. This prompt can be bypassed by providing a filename here.
Turn on transcripting. This records both the output of the game and user input. If the chosen transcript file exists, it will be appended to, not overwritten. This way you can easily continue a transcript every time you come back to a game.

Transcripts are always written in UTF-8.

See also the -y option and the META COMMANDS section.

transcript_filename
When transcripting is enabled, you will be prompted for a filename. This prompt can be bypassed by providing a filename here.
slots
Some games provide the ability to undo a turn. In fact, some games allow multiple turns to be undone. This option controls how many save slots are available. Unlike the stacks (see -a and -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 knowledge, do: and Beyond Zork. However, bocfel includes the ability to perform multiple undo regardless of whether the game provides support for it. See the META COMMANDS section for more information.

The default value is 100. A value of zero disables undo.

Display version information and show which compile-time options are set.
Many games include abbreviations for commonly-used commands: x for EXAMINE, g for AGAIN, z for WAIT, and o for OOPS. Some early Infocom games, however, do not provide these. For these Infocom games, x, g, z, and o are mapped to their respective commands, providing convenient shortcuts for games that don't provide them. If a game requires one of these letters for its own use, these abbreviations can be turned off with -x.
Enable the Tandy, or censorship flag. This flag is generally unused, but it does change some language in The Witness which was, apparently, offensive to the Tandy Corporation. Some other games add a note regarding licensing to Tandy, but apart from this, it is apparently unused by Infocom.
When transcripting is turned on and an existing file is selected, that file is appended to rather than overwritten. This option causes the file to be overwritten.
In almost all games, either the game's UNDO command or the /undo meta command will work. However, if you encounter a game where undo appears broken, try using this option. It will instruct bocfel to 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.
seed
Provide a seed to the pseudo-random number generator, causing it to yield predictable values. This option is probably only of use to game authors who are doing testing. The generator will be reseeded with this value whenever the @random opcode is called with a 0 operand or when the @restart opcode is called. The -Z option overrides this option.
device
Provide a device from which random numbers are read for the @random opcode. This is meant to be used with special files such as /dev/urandom, although it can be used with any file. If a read error occurs or end-of-file is reached, bocfel will 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:

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.

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

Undo a turn. This is similar to the UNDO command some games provide, but has two distinct advantages: it works even in games that do not provide undo, and it provides multiple undo even in games which do not support multiple undo.
Start a transcript.
Stop a transcript.
Start a command record.
Stop a command record.
Replay a command record.
Save the game. This creates save files that are incompatible with those created by SAVE, so they should only be restored with /restore. bocfel has 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 bocfel solely for the case of such anti-social games.

Restore a game saved by /save. Do not attempt to use /restore to restore games saved with a normal SAVE command.
Push a save state onto the in-memory stack.

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.

/ps [description]
Identical to /ps, except that when the save state is displayed by /ls, the supplied description is shown rather than the time of the save.

Please note that at the current time, any characters which are not printable ASCII characters will be replaced with a question mark.

Restore the last-stored in-memory save state, as created by /ps, removing it from the stack.
/pop [slot]
Restore the specified in-memory save slot. [slot] must correspond to one of the slot numbers shown by /ls. The specified save, as well as any newer saves, will be removed from the stack.
Drop the last-stored in-memory save state, as created by /ps, removing it from the stack.
/drop [slot]
Drop the specified in-memory save slot. [slot] must correspond to one of the slot numbers shown by /ls. The specified save, as well as any newer saves, will be removed from the stack.
/drop all
Drop all in-memory save slots, removing them from the stack.
List all available in-memory save states. Each state is shown either as a string representing the time when the state was saved, or, if it was supplied, the description passed to /ps. The last-listed state, which is marked with an asterisk, is the default state which will be restored with /pop.
If persistent transcripting is turned on, this will allow the transcript to be written to a file.
Open a copy of the transcript in a text editor. Any changes made to the transcript will not be retained. The transcript is opened in an editor as opposed to being dumped into the main screen due to the fact that transcripts tend to grow large and would be unwieldy in the main window. Using an editor allows for easier reading, searching, and so on.
Start a text editor to take notes associated with this gaming session. Such notes will persist across saves.
Display (in the main window) notes which have been taken.
Write notes to a file.
Display the status line. This only works for V1, V2, and V3 games, and is meant to be used either in non-Glk mode, or if the Glk implementation being used does not support windows (e.g. cheapglk).
Disable meta commands for the remainder of the session. This is useful if the game itself expects input to start with a slash character.
Pretend like [command] was typed. As with /disable, this is meant for games which expect input to start with a slash character.
Toggle forcing a fixed-width font in the main window. This is intended for games which attempt to draw ASCII art in the main window without first setting a fixed-width font. It was added for 's hieroglyphics, but there may be other games where it is also useful.
Open bocfel's configuration file in a text editor.
Perform a debugging operation; see META DEBUG COMMANDS.
Quit immediately, as though the @quit opcode were executed. In general this isn't necessary, but if you're in a game with no clear way to quit and you want the autosave file removed, /quit will accomplish that.
Display some information about the current story file: filename, Z-machine version, and ID.

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 /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 , where is a hexadecimal value in the range [00, ef], corresponding to global variables 0 to 239.

The debug commands are as follows:

Begin a “change” operation. This tracks word-sized memory addresses, allowing you to see if the values at any addresses have increased or decreased since the last check. This is primarily useful for cheating (see CHEATING), helping, for example, to determine which memory address is used to track hunger or thirst.
Display a list of all memory addresses which have decreased since the last change operation (either a change start, change inc, or change dec. Values are treated as signed words, so a change from 0 to 65535 is considered a decrease from 0 to -1.
Display a list of all memory addresses which have decreased since the last change operation.
Begin a “scan” operation. This tracks word-sized memory addresses, checking if particular addresses have specific values over time. As with “change” operations, this is useful mainly for cheating. An example would be tracking which memory address holds the amount of money being carried. If you have $50, you can scan all addresses for the value 50. After spending $5, scan all addresses for 45. Repeat until only one address matches and that is likely where the money count is being stored.
Scan all memory addresses for the value N, which is a signed decimal integer (hexadecimal if a leading 0x is used, octal if a leading 0 is used). The total number of matching addresses (constrained by previous scan operations) is then printed.
Display all addresses matching all previous scan criteria. This is a separate operation because initial scans will potentially match thousands of addresses.
Print the word (as both signed decimal and unsigned hexadecimal) at address.
Freeze a 16-bit value in memory; this is analogous to the freeze configuration variable (see CHEATING). address is the address to freeze, and value is the value it should be frozen to. value can be decimal, hexadecimal, or octal, with a leading 0x signifying hexadecimal and a leading 0 signifying octal.

Please note that it is possible for bocfel to be built without cheating support, so this and related commands might not work.

Unfreeze the 16-bit value which is frozen at address; the address is parsed identically as for freeze. It is not an error to unfreeze an unfrozen value.
Display all frozen values.
Report any changes to the 16-bit word at address.

Please note that it is possible for bocfel to be built without watch support, so this and related commands might not work.

Watch every address for changes. This will likely produce a lot of output.
Stop watching address for changes. It is not an error to stop watching an address which is not being watched.
Stop watching all addresses which are currently being watched.
Display all watched-for values.

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 “cheating”. 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 and drink.

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.

Example:

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 bocfel 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 Standards Document). 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 -i option.

bocfel is believed to comply fully with version 1.1 of The Z-machine Standards Document; see https://www.inform-fiction.org/zmachine/standards/z1point1/index.html and http://ifarchive.org/if-archive/infocom/interpreters/specification/ZSpec11.txt.

Chris Spiegel ⟨cspiegel@gmail.com⟩

July 11, 2024