A pure Elm Z-Machine version 3 interpreter for interactive fiction.
This module is the main entry point for the library. All functions needed
to load and run a .z3 story file are here. For pattern matching on
result types, also import the constructors from
ZMachine.Types:
import ZMachine exposing (load, runSteps, provideInput)
import ZMachine.Types exposing (StepResult(..), OutputEvent(..))Each StepResult variant carries the
output events accumulated during the call that produced it, so the
host never needs to inspect the machine's output buffer directly.
Result of executing one or more instructions. See
ZMachine.Types.StepResult for the
constructors you will pattern match on.
Structured output events for the host to render. See
ZMachine.Types.OutputEvent for the full
list of constructors.
Metadata about a line-input request. Carried by the NeedInput
variant of StepResult.
Errors that can halt the machine.
Status line data including location name, score, and turns.
Opaque snapshot of machine state. See
ZMachine.Snapshot for operations.
Load a .z3 story file from raw bytes and initialize the machine.
case ZMachine.load storyBytes of
Ok machine ->
-- ready to run
...
Err err ->
-- invalid story file
...Execute a single instruction. Returns a StepResult indicating
whether the machine can continue, needs input, halted, or hit an error.
case ZMachine.step machine of
Continue nextMachine ->
...
NeedInput request machineWithOutput ->
...Execute up to n instructions, stopping early if input is needed,
the machine halts, or an error occurs.
case ZMachine.runSteps 10000 machine of
Continue nextMachine ->
-- budget exhausted, call runSteps again to keep going
...
NeedInput request machineWithOutput ->
-- prompt the player for input
...Provide a line of input to a machine that returned NeedInput.
Writes the text into the story's text buffer, tokenizes it, and resumes execution. In V5, also stores the terminating character (13 for newline).
case ZMachine.runSteps 10000 machine of
NeedInput info _ machineWithOutput ->
ZMachine.provideInput "open mailbox" info machineWithOutput
_ ->
...Provide a character to a machine that returned NeedChar.
Pass a single-character string — only the first character is used.
The ZSCII code is stored as the result of the read_char opcode.
case ZMachine.runSteps 10000 machine of
NeedChar _ machineWithOutput ->
ZMachine.provideChar "y" machineWithOutput
_ ->
...See ZMachine.Snapshot for building custom save
schemes and ZMachine.Quetzal for the standard
portable format.
Capture a snapshot of the current machine state. Safe to call any
time the host is holding a ZMachine between steps — useful for
autosaves or quick-save UIs. The resulting snapshot is tagged
ResumeAt, meaning on restore execution picks up at the next
instruction.
For the standard portable save-file format, serialize with
ZMachine.Snapshot.encode (native) — or
note that ZMachine.Quetzal.encode rejects ResumeAt snapshots
because Quetzal has no way to represent resuming at an arbitrary
instruction boundary.
Rehydrate a running machine from a snapshot. Used to load an
autosave at startup (or any time the host wants to swap state outside
of a restore opcode).
Fails with a RestoreError if the
snapshot is for a different story or its dynamic-memory image is
corrupt.
Resume a machine that returned NeedSave. Pass True if the host
successfully persisted the snapshot, False otherwise. The save
opcode's branch is evaluated against the result.
case ZMachine.runSteps 10000 machine of
NeedSave snap m ->
writeToFile (ZMachine.Quetzal.encode snap)
|> Task.map (\_ -> ZMachine.provideSaveResult True m)Resume a machine that returned NeedRestore. Pass Just snapshot
to rehydrate from the snapshot (the original save opcode's branch is
taken as true); pass Nothing to report failure (the restore opcode
branches false and execution continues normally). Mismatched-story
snapshots are treated as failures.
The complete state of a running Z-Machine.