The Z-Machine Standard 1.2 (draft)

Dannii Willis <>


Status: draft as of 1 March 2012.

1. Introduction

1.1 Rationale

This is a draft proposal for a new standard extension of the Z-Machine. The Z-Machine was first formalised by Graham Nelson, et al. in 1997 [Spec10]. Several attempts were later made to extend the Z-Machine, which were eventually refined down into the 1.1 Standard [Spec11].

However, effectively the only Z-Machine extension to ever gain traction was the introduction of the unicode opcodes in the 1.0 standard. The 1.1 standard has rarely been fully implemented, possibly in part because there is no way to detect the new opcodes other than by checking whether the interpreter set the standard revision header to signify 1.1, which it shouldn't do unless it fully implements the standard. There is no way to partially implement the standard.

This proposal is an attempt to rectify this situation. A new @gestalt testing opcode will be added, following the syntax of Glulx's cognate opcode [Glulx]. This will allow story files to test for interpreter support of new features and opcodes before using them, with the possibility of using alternative code if they are not.

That is the only change which this standard directly makes, although an official registry of selectors and the additions they test for is listed below. Some of the selectors may be used to identify which of several conflicting interpretations of the previous standards has been implemented in an interpreter, but they do not require that one interpretation be implemented over another.

1.2. Compliance

An implementation of this standard will set the standard revision header (address $32) to $0102. It will add the @gestalt opcode, as detailed below, and will support the core selectors, as listed in the selector registry.

To comply with this standard an implementation must also comply with the 1.0 and 1.1 standards, as they are written at the time of the publication of this standard [Spec10] [Spec11]. If you ignore the Z-Machine version 6 then the changes required by the 1.1 standard are quite limited and extending a 1.0 interpreter to both 1.1 and 1.2 should not be a large task. As noted above, there are unfortunately some areas of the previous standards which have been interpreted differently by implementation writers. Because of that some selectors may be used to identify which interpretation has been implemented in the interpreter.

Praxix is a Z-Machine unit test which includes tests for this standard [Praxix]. Implementors should check that their implementation passes all the tests it performs.

2. @gestalt

The @gestalt opcode has the following specification:

@"EXT:30S" id arg -> (result);

This will test for the selector id, with the optional argument arg, storing the result in the variable specified. If a certain selector does not need the optional argument, set it to 0.

If a selector is set which the interpreter doesn't recognise, then 0 will be stored. What a selector will do with an argument it doesn't recognise is up to that selector; see the registry for details.

Before using the opcode, ensure that you are using an 1.2 standard interpreter by checking whether the standard revision header (address $32) is $0102 or higher.

3. Selector registry

The following is an official list of selectors and their associated opcodes. Extensions will generally be specified elsewhere (and only a short description given below) although a few from existing interpreters have also been documented. If you would like to reserve a selector or opcode for your own extensions, please contact the author.

Extension titleSelector IDAssociated opcodes, streamsDescription
Standard version$01-Core: stores the Z-Machine standard which this interpreter supports. Will be $0102 or higher.
Transcripts Protocol$10-Specifies whether the interpreter supports tagged responses. [Transcripts]
@parchment$20EXT:31Support for @parchment. [@Parchment]
eval() stream$30Stream:5Supports the eval() stream. It behaves like the memory stream, except that when it is turned off its contents will be run through the Javascript function eval(), and what that returns will be written back to memory. If they are both enabled then the memory stream takes priority.
Vorple$31Stream:6A stream reserved for Vorple. [Vorple]
Zoom profiling$1000EXT:128-131Provides opcodes for accessing the system timer. For more details see Zoom's README [Zoom].
Zoom stack dump$1001EXT:132Prints out a stack dump. For more details see Zoom's implementation (src/zmachine.c: zmachine_dump_stack()) [Zoom].
@set_font 0$2000EXT:4Core: clarification for @set_font 0. Set to which of the following is implemented:
  1. not supported
  2. no change, and return the current font
  3. change to the second last font, and return it
Streams 3/4$2001-Core: clarification for when streams 3 and 4 are supported. Set to which of the following is implemented:
  1. V3 and higher
  2. V5 and higher
@call_vs2$2002VAR:224Core: clarification for how many arguments are allowed in V4 for @call_vs2. Set to which of the following is implemented:
  1. 0-3
  2. 0-7
Private use$F000-$FFFFEXT:133-255Selectors in this range will never be specified, and are free for use in custom interpreters. As in previous standards, opcodes EXT:133-255 are available for custom interpreters, and you may use one of these selectors to test whether the story file is being run in your interpreter (pick one at random). Please consider though whether there might be value in standardising your extension for others to use.


  1. [Glulx] Glulx - VM specification version 3.1.2. 2010. Andrew Plotkin.
  2. [@Parchment] @parchment. 2010. Dannii Willis.
  3. [Praxix] Praxix - a Z-Machine unit test. 2010. Zarf and Dannii. Hosted here: source code/compiled zcode.
  4. [Spec10] The Z-Machine Standards Document - Version 1.0. 1997. Graham Nelson, et al.
  5. [Spec11] Z-Machine Standard 1.1 Document. 2006. Kevin Bracey, Jason C. Penney, David Kinder.
  6. [Transcripts] IF Transcripts Protocol. 2010. Dannii Willis.
  7. [Vorple] Vorple JavaScript user interface library. 2012. Juhana Leinonen.
  8. [Zoom] Zoom - Z-Machine interpreter. 2009. Andrew Hunter.