Fernz
Fernz is a clean-room, pure Python reimplementation of Jericho and its underlying Frotz Z-machine engine, with a familiar Python API for playing and exploring interactive fiction. Here, clean-room means implementing the engine using only open specifications and documented public APIs, then testing its behavior against the original interpreters without inspecting their code (i.e., black-box behavioral comparisons).
It is also an experiment in agentic coding to see how far Astra could get with a public specification and a black-box reference implementation.
It was built to enable cross-platform play and redistribution in Cabin Fever x86 and to make Z-machine games easy to embed, test, and experiment with from Python. Fernz is MIT licensed and runs on Linux, macOS, and Windows.
It currently plays V3, V4, V5, and V8 stories and inspects V1–V8 files. The API covers gameplay, checkpoints, score/move queries, and object inspection; some Jericho methods and Z-machine features remain unimplemented.
Install
Requires Python 3.11+. Include the optional Textual terminal interface:
python -m pip install "fernz[textual]"
Use pip install fernz for the dependency-free library and simple terminal player.
Get a game and play
Download the BYU-PCCL game collection and play Zork I:
fernz --download-games
fernz zork1.z5
The download extracts only the contents of the archive's jericho-game-suite
directly into ./games/, matching the test fixture. Games are distributed
separately and retain their own copyrights and licenses. This Zork I file
contains a V3 story despite its .z5 extension.
To choose a destination, use fernz --download-games /path/to/collection, then
fernz /path/to/collection/zork1.z5. Existing destinations containing zork1.z5
are reused without downloading or overwriting files; an existing destination
without that file reports an error.
You can also bring your own raw Z-machine story. Fernz first tries the exact
supplied path, then, only if it is missing and relative, the same path under
./games. For example, zork1.z5 falls back to
./games/zork1.z5. There is no extension guessing or other
search. Errors reading an existing path are reported without falling back.
This lookup also applies to --inspect; the Python API uses explicit paths.
Try look, open mailbox, and read leaflet. Press Ctrl+Q to exit.
Textual is selected automatically when installed; --simple selects plain text.
The game's save and restore commands open file dialogs.
Use the API
from fernz import FernzEnv
env = FernzEnv("games/zork1.z5", seed=42)
try:
observation, info = env.reset()
print(observation.text, end="")
for command in ("open mailbox", "take leaflet", "read leaflet"):
observation, reward, done, info = env.step(command)
print(observation.text, end="")
if done:
break
checkpoint = env.get_state()
env.step("look")
env.set_state(checkpoint)
finally:
env.close()
Observations provide plain .text and an ordered .stream with display tags.
reward is the score change, info includes score and moves for supported games,
and done means the interpreter has quit. Checkpoints include RNG state for
reproducible replay; env.copy() forks an environment for independent exploration.
Further reading
Detailed guide · Terminal controls · API and project overview · Testing
Specifications: Z-machine Standard 1.1, annotated edition, Quetzal save format, and Jericho's public API.
Maintainers: see the publishing setup and release guide for GitHub/PyPI configuration, tag releases, local packaging checks and recovery.
Metadata
Release files for fernz 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fernz-0.0.2.tar.gz | 59.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fernz-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 127.0 kB
Release files / fernz-0.0.2.tar.gz
| Download URL | fernz-0.0.2.tar.gz |
|---|---|
| Size | 59.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1f7548ebfbecd7ca0b313b0f79274f996046e7b3ba8ec2e43ea400fa09b49f4
|
|
BLAKE2b-256 checksum How to use checksums |
231c801a2d195371f1385e6fe711c11d7d384797381bbe814ad74b964fc42b3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency logRelease files / fernz-0.0.2-py3-none-any.whl
| Download URL | fernz-0.0.2-py3-none-any.whl |
|---|---|
| Size | 67.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
113c24510876cd013e3101b16f042162f2069f83ee39ff4c5979f6596841f51c
|
|
BLAKE2b-256 checksum How to use checksums |
f53b12d5edddb710a794690bf71d164954da12dc42e8d0fb7371b939752192c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.
Transparency log