SkillAgentSearch skills...

Pez

Portable Executable Zork; notes and code for interactive fiction authoring via Cosmopolitan Libc

Install / Use

/learn @ChristopherDrum/Pez
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Portable Executable Zork

Screenshot of resurrected ZIP (z-machine interpreter) by Infocom for Unix, running in Windows 11 PowerShell and Ubuntu WSL2

Here, I'm using "Zork" as a shorthand to represent "the world of interactive fiction" in general. This project is not exclusive to Zork, and very much not exclusive to the z-machine. The Å-machine and the Scott Adams games are also under investigation.

The purpose of this repository is to gather my findings/research while using Cosmopolitan Libc to build and run tools (modern and historical) for IF authoring. When necessary, I supply modified source code to enhance a project (make it more flexible, or improve output) or enable compilation via cosmocc (replace deprecated functions, etc.)

The final product of the build process for each tool is a single executable in the APE format. An APE file self-contains everything it needs to run natively on the wide range of 64-bit machines supported by the Cosmopolitan project. We don't need separate builds for each platform. In some cases we don't even really need a makefile any more. By swapping the compiler for cosmocc we can generate a platform-independent/agnostic tool which can be enjoyed by the widest audience possible.

An end-to-end interactive fiction development workflow boils down to three tasks: authoring, compiling, and playing. Projects that I've built and tested are noted here; I'll continue to expand the list as I gain experience with the build tools and various source code. Everything is built with cosmocc linked against the Cosmopolitan Libc libraries.

As well, the /zip/cosmo_source folder shows off one of the most interesting features of the APE format: the ability to embed executable launch arguments and application data, to auto-launch into a specific user experience. The Zork trilogy in this repo's "Releases" demonstrates the profound utility of this approach. The included makefile makes it easy to build your own standalone games with embedded z-machine.

||||| |-|-|-|-| |Authoring|vim||| |Compiling|Inform6|DialogC|| |Playing|Mojozork|Frotz|Infocom's ZIP|

<br>

Authoring

vim

For authoring I have only been testing the vim build provided by Justine Tunney in her cosmos project. It worked perfectly on my test systems, and comes with Inform syntax highlighting built-in. That made it an easy choice for this project, for now. emacs should also be viable, but I haven't given it a proper shakedown yet. There are other languages that I need to look into for their syntax support, namely ZIL and Dialog.

Download it from here: https://cosmo.zip/pub/cosmos/bin/vim

Compiling

Not to be confused with the cosmocc C compiler which builds the executables for this project, interactive fiction programming languages have their own special compilers. These compilers translate the code we write in the interactive fiction domain-specific languages (Inform6, Dialog, ZIL) into intermediate z-machine opcodes. The z-machine itself (see #Playing below) is a virtual machine with its own opcodes. I recommend this page to understand those: https://zspec.jaredreisinger.com/zz03-opcodes

Inform6

Inform7 is technically the more relevant language to use these days, but at my current experience level it is too large and machine-dependent (very graphics/UI-heavy; maybe there is a subset I can target?) to tackle for this project. I've been using the Inform6 compiler, which gives us a little more flexibility in the compilation to target the limitations of specific interpreters (see #Playing below)

Building Inform6

The code can be cloned from: https://github.com/DavidKinder/Inform6<br><br> It's super simple to compile and we can trivially modify its compilation to point to cosmocc.<br>From inside the inform6 repo folder:<br>cosmocc -o inform6 *.c -mtiny

It should also be possible (though I haven't tried it yet) to provide an absolutely standalone build of Inform6 with embedded libraries. The APE file format supports such a scenario and the APE build of vim is proof this can work.

DialogC

A newcomer to the scene, the interactive fiction community is working to keep the project alive. The Dialog language is quite different to Inform, taking a very Prolog "logic based" approach. This is conceptually similar to the changes made in Inform from v6 to v7.

Where Inform7 takes a "literate" and "English language-like" approach, Dialog looks and feels more like a "typical" programming language. However, at the end of the day it can compile itself down to the same z-machine opcodes as Inform.

Dialog can only target .z5 and higher for its builds, which will run on the dfrotz interpreter. I test compiled a .z8 file using an APE build of Dialog and it ran perfectly in Status Line, so I feel confident an APE-based workflow for Dialog will be sound.

Building DialogC

Source can be downloaded from: https://hd0.linusakesson.net/files/dialog-0m03_0_46.zip

The Dialog source includes a makefile, but it isn't strictly necessary.<br>Run either of these from inside /dialog-0m03_0_46/src

  • Using the makefile: /cosmocc/bin/make -j dialogc<br>
  • Invoking cosmocc directly: cosmocc -DVERSION=\"0m/03\" -o dialogc frontend.c backend_z.c runtime_z.c blorb.c dumb_output.c dumb_report.c arena.c ast.c parse.c compile.c eval.c accesspred.c unicode.c backend.c aavm.c backend_aa.c crc32.c -mtiny

Playing

Once we have our code written and compiled into a z-machine ready file, we need to be able to play and test it. That's where a z-machine interpreter comes in. I've written a full-featured one called Status Line for the Pico-8 in Lua, but of course we need a C-based one for this project.

Mojozork

The first z-machine I tried, it gave me a quick way to test a z-machine interpreter with its single-file, no-external-dependencies simplicity. It only supports .z3 games, which excludes a huge number of games, but does enable Infocom classics and many recent PunyInform games. (link here)

I modified this to add VT100 terminal codes for a more polished presentation. This repo adds the inverted status bar and provides simple window scrolling in an 80 char x 24 line window. Classic presentation for classic games.

Building Mojozork

cosmocc -o mojozork mojozork.c -mtiny

Frotz

A Unix/DOS z-machine interpreter, this long-running project has been ported over to a huge number of vintage and modern machines. Its "dumb" version plays a wider variety of games than #Mojozork (above), but provides only raw output; no status line or anything resembling "layout."

There are two other variations of Frotz which provide a more robust visual experience: SDL and Curses I felt intimidated by the SDL version; I'm unclear about Cosmopolitan Libc's boundaries when it comes to GUI and and graphics stuff. The Curses version (which relies on ncurses) stumped me for now. See Adding additional libraries, below.

Building DFrotz

Clone the source from here: https://gitlab.com/DavidGriffith/frotz<br> From frotz/src/dumb run cosmocc/bin/make -j

Infocom's ZIP

This is it, the big one, the OG written by the company that invented the z-machine itself. Until a couple of years ago we never had the source code to Infocom's own z-machine interpreters. Now we have them all.

Most of the interpreters are written in assembly, targeting each platform's hardware directly. They had to really squeeze as much as they could out of those older machines, especially since Infocom was asking each machine to do natural language processing in a virtual machine in realtime with as little as 16K.

Their first work was on the PDP-10 in FORTRAN, but to bring Zork to a wider audience they realized they would need to abstract things more to support the burgeoning home computer market. One operating system they did choose to target was Unix which they wrote in plain-ole C. Lucky for us!

I focused on Paul Gross's modified Unix code, phg_zip.c because I somehow find it easier to follow. 🤷‍♂️ With a little elbow grease to modernize older coding conventions and deprecations, it worked.

I can't express what a fantastic feeling it was to see that original code spring back to life on a modern computer and to know it was instantly available to almost anyone who wanted to try it out. No platform-specific shenanigans or workaround or makefiles. Just build and go. This, to my mind, is how preservation should be; so simple anyone can do it.

This version of their interpreter only plays z3 games, but does include VT100-style character/terminal handling code to give a proper, real-deal, Infocom presentation. I saw code for split screen handling so even Seastalker's radar should work I think. 🤔

Building ZIP

cosmocc -o zm dgh_zip.c -mtiny<br> (building as zm to not conflict the the zip utility)

A makefile is included in /zip/cosmo_source that gives you two build options:

  1. A raw z-machine with can be run with the -g flag and a path to a .z3 game file.
  2. A self-contained, fully embedded game + z-machin
View on GitHub
GitHub Stars26
CategoryDevelopment
Updated20d ago
Forks0

Languages

C

Security Score

75/100

Audited on Mar 10, 2026

No findings