Skip to content

Z-Machine Interactive Fiction

ENiGMA½ includes a native Z-Machine interpreter for running interactive fiction games — the format used by classic Infocom titles (Zork, Hitchhiker’s Guide to the Galaxy, Planetfall, etc.) and hundreds of modern IF competition winners. The zmachine_door module runs these games directly in a Node.js worker thread. No external emulator, no drop file, no BIOS image, and no platform-specific setup — just a path to a .z3, .z5, or .z8 game file.


  1. ENiGMA½ spawns a worker thread per session running ifvms.js — the same Z-Machine interpreter that powers the Parchment web-based IF player.
  2. The worker loads the game file, runs the VM, and emits text output + input-mode events over postMessage.
  3. The main thread bridges the user’s terminal connection: forwarding keystrokes as line-mode or character-mode input and routing game output back to the client.
  4. Glk text styles are rendered as ANSI SGR; Z-Machine set_colour calls are hooked at the VM level and emit ANSI color codes inline.
  5. Output is word-wrapped server-side to a fixed width, and paginated with ”— More —” prompts so long passages don’t scroll off screen.
  6. When the user types QUIT (or disconnects), the worker exits cleanly and control returns to the calling menu.

  • A Z-Machine game file (.z3, .z4, .z5, or .z8). ENiGMA does not bundle any games — sysops provide their own.
  • No other setup. No emulator, no drop file, no configuration files.

Modern free Interactive Fiction is available from the IF Archive — see especially the Z-code games index. Thousands of free games are available, including IF Competition winners and pioneering works. Highly recommended starting points:

  • Colossal Cave AdventureAdvent.z5. The original text adventure (Crowther & Woods, 1976), ported to the Z-Machine by Graham Nelson. Public domain.
  • Photopia — Adam Cadre’s 1998 IF Competition winner. Famous for its color-coded narrative vignettes; runs in our color pipeline.
  • Lost Pig — Admiral Jota’s 2007 IF Comp winner. A beloved starting-point for newcomers to IF.
  • Anchorhead — Michael Gentry’s Lovecraftian horror masterpiece.
  • An Act of Murder — Christopher Huang’s procedurally-generated murder mystery. Every playthrough is a different case.

By convention, game files live under misc/zmachine/games/:

misc/zmachine/games/
├── advent.z5
├── photopia.z5
├── LostPig.z8
└── anchor.z8

The game_path config field is fully configurable — you can put files wherever you like.


The zmachine_door config block supports the following fields:

ItemRequiredDescription
nameYesDoor name. Used as a key for tracking concurrent sessions.
game_pathYesAbsolute path to the Z-Machine game file (.z3, .z4, .z5, or .z8).
nodeMaxNoMax concurrent sessions. 0 = unlimited (default).
tooManyArtNoArt spec to display when nodeMax is exceeded.

No drop file configuration is needed — Z-Machine games don’t use them.


doorAdventure: {
desc: Playing Colossal Cave Adventure
module: zmachine_door
config: {
name: Adventure
game_path: /home/enigma/misc/zmachine/games/advent.z5
nodeMax: 3
tooManyArt: DOORMANY
}
}
doorPhotopia: {
desc: Playing Photopia
module: zmachine_door
config: {
name: Photopia
game_path: /home/enigma/misc/zmachine/games/photopia.z5
nodeMax: 3
tooManyArt: DOORMANY
}
}
doorActOfMurder: {
desc: Playing An Act of Murder
module: zmachine_door
config: {
name: ActOfMurder
game_path: /home/enigma/misc/zmachine/games/ActofMurder.z8
nodeMax: 3
tooManyArt: DOORMANY
}
}

VersionSupportedNotes
z1 / z2NoVery early Infocom releases; not implemented by ifvms.
z3YesMost classic Infocom games (Zork, Planetfall, Hitchhiker’s Guide, etc.)
z4YesTrinity, A Mind Forever Voyaging, Bureaucracy
z5YesBeyond Zork, Sherlock, Border Zone, and most modern IF. The most common target version for modern games.
z6NoGraphical variant — requires a full windowed Glk implementation; not applicable for terminal use.
z8YesLarger modern IF games (Anchorhead, Lost Pig, Varicella, etc.)
GlulxNoA different virtual machine used by some modern IF; not supported. Most z-machine games also have Glulx builds — use the .z* version.
FeatureNotes
Glk text stylesBold, italic, header, subheader, alert, emphasized, block-quote, preformatted, and user styles rendered as ANSI SGR.
Z-Machine colorsset_colour opcode emits ANSI SGR inline. The 8 standard Z-Machine colors map to the basic ANSI palette.
Word wrapServer-side 80-column word wrap with correct handling of embedded ANSI escapes (zero-width).
Pagination”— More — Press any key to continue” prompts at termHeight - 2 rows (default 23 for an 80×25 terminal).
Input modesLine-mode (with local echo + backspace editing) for commands; character-mode for “press any key” prompts.
Input editingStandard server-side line editing: printable keys echoed, backspace erases, Enter submits.

These reflect the current MVP state of the module. Some are intentional design choices, others are candidates for future improvement.

  • No save/restore. Games start fresh each session. In-game SAVE/RESTORE commands will not persist across sessions. (A SQLite schema is already provisioned for per-user autosave, but the full implementation is deferred — glkote-term’s DumbGlkOte does not implement save_allstate/restore_allstate, which are required by ifvms’s built-in autosave path.)
  • No split-window / status line. ifvms’s “upper window” (the top-of-screen status line used by some games to display score/turn or draw title art) is not rendered. Games that rely heavily on it (most Infocom z3 titles) still run and their main-window content works fine, but the status line is effectively hidden. Photopia’s splash title art is drawn in the upper window, so you’ll see its “press any key” indicator without the title artwork.
  • No Glulx support. .gblorb / .ulx games don’t run. Most modern IF is also available in a .z* build — use those.
  • No hyperlinks. Some IF games support clickable hyperlinks via Glk; terminal clients obviously don’t support mouse interaction, so they’re rendered as plain text.