Local Doors — Z-Machine Interactive Fiction

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.

:information_source: Each active session runs in its own worker thread, isolated from other users. Multiple players can run the same or different games simultaneously with no cross-talk.


How It Works

  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.

Prerequisites

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

Where to Get Games

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.

:warning: Infocom games are not legally distributable. The original commercial Infocom titles (Zork, Hitchhiker’s, etc.) remain under copyright and are still sold commercially (e.g. via GOG). Do not redistribute them; if you own a legitimate copy you can use your own .z5 files.

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.


Configuration

The zmachine_door config block supports the following fields:

Item Required Description
name :+1: Door name. Used as a key for tracking concurrent sessions.
game_path :+1: Absolute path to the Z-Machine game file (.z3, .z4, .z5, or .z8).
nodeMax :-1: Max concurrent sessions. 0 = unlimited (default).
tooManyArt :-1: Art spec to display when nodeMax is exceeded.

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


Example Menu Entries

Colossal Cave Adventure

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

Photopia (with color)

doorPhotopia: {
    desc: Playing Photopia
    module: zmachine_door
    config: {
        name: Photopia
        game_path: /home/enigma/misc/zmachine/games/photopia.z5
        nodeMax: 3
        tooManyArt: DOORMANY
    }
}

An Act of Murder (procedural mystery)

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

Supported Features

Z-Machine versions

Version Supported Notes
z1 / z2 :-1: Very early Infocom releases; not implemented by ifvms.
z3 :+1: Most classic Infocom games (Zork, Planetfall, Hitchhiker’s Guide, etc.)
z4 :+1: Trinity, A Mind Forever Voyaging, Bureaucracy
z5 :+1: Beyond Zork, Sherlock, Border Zone, and most modern IF. The most common target version for modern games.
z6 :-1: Graphical variant — requires a full windowed Glk implementation; not applicable for terminal use.
z8 :+1: Larger modern IF games (Anchorhead, Lost Pig, Varicella, etc.)
Glulx :-1: A different virtual machine used by some modern IF; not supported. Most z-machine games also have Glulx builds — use the .z* version.

Rendering

Feature Notes
Glk text styles Bold, italic, header, subheader, alert, emphasized, block-quote, preformatted, and user styles rendered as ANSI SGR.
Z-Machine colors set_colour opcode emits ANSI SGR inline. The 8 standard Z-Machine colors map to the basic ANSI palette.
Word wrap Server-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 modes Line-mode (with local echo + backspace editing) for commands; character-mode for “press any key” prompts.
Input editing Standard server-side line editing: printable keys echoed, backspace erases, Enter submits.

Known Limitations

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.

See Also