Since finishing Status Line v3 and publishing builds for multiple platforms, I’ve been thinking a lot about software preservation in general and for the IF development toolchain. I have to note here that “preservation” here refers to “the past decade or so, and into the future.” The retro crowd is not really served by this post.
Two things in particular have been on my mind:
- To make “platform agnostic” builds of things, we need a virtual machine to stand between the OS and z-machine interpreter (for example). I use Pico-8. There was (is?) JVM. Electron tries to provide this with Javascript. We have web browsers, but wither Internet Explorer, Flash, etc? There are engines like Unity, which has seen migration to Godot. And so on… It’s just a never-ending cycle of machines falling in and out of favor.
- The alternative is to write in a shared language, like C, and provide massive, complex make files which generate bespoke builds for every platform someone wants to take the time to support.
Write once; run natively anywhere
There is, however, a potential third way. This didn’t really become a viable option (in my opinion) until just last month. But what if we could have the convenience of a virtual machine’s “write once, run anywhere” model with a native application?
If you’re not familiar with Cosmpolitan Libc and the Actually Portable Executable projects, I hope those with some interest/understanding in build tools will take some time to check it out: GitHub - jart/cosmopolitan: build-once run-anywhere c library
The long and the short of it is that v4 of Cosmopolitan Libc came out just last month and this project has gone from “interesting experiment” to “holy crap, we have something useful here.” Justine Tunney is a magician.
She realized that by writing in C and leveraging the shared lineage of modern computers, she could create portable executables which run everywhere. She says,
“I want any software work I’m involved in to stand the test of time with minimal toil. I believe the best chance we have of doing that, is by gluing together the binary interfaces that’ve already achieved a decades-long consensus, and ignoring the APIs. …we can see that few things about systems engineering have changed in the last 40 years at the binary level. Platforms can’t break them without breaking themselves.”
Using her tools, the end result of the build process is a single executable which runs on everything. Copy it to a Mac, it runs. Copy it to Windows, it runs. Copy it to Linux, it runs.
This week I spent time building and using a full, universal IF workflow toolset:
- I wrote an Inform file in a universal build of vim
(complete with Inform syntax coloring) - I compiled it to z5 using a universal build of inform6
- I played the game in a universal build of dfrotz (dumb frotz)
I ran this workflow on:
- Windows in PowerShell.
- Windows Terminal, WSL2 (Ubuntu).
- Ubuntu desktop (in VMware)
- M3 Mac in Terminal.
All tools were built using Justine’s cosmocc
, a modified gcc
vim
was pre-built by Justine (grab it and other tools here)inform6
I built from source (zero problems; worked on the first attempt)dfrotz
I built from source (dumb frotz
because I’m having trouble getting ncurses working, though others have success with it. Still learning!)- (I also added VT100 escape code character display functionality to
mojozork
; works great, status bar and screen scrolling included)
Built executable sizes are larger than single-platform builds, but maybe not by quite as much as you might expect. As well, I’ve come to believe these may be bloated with debug symbols:
vim
, with basically everything pre-installed: 18MBinform6
: just under 2MBdfrotz
: 889KB
With the success of the above builds, I had to try some other things of course.
ScottFree
built and ran games just fine (with a small source code change to remove deprecated function calls)DialogC
built and compiled a z8 file for me without issue. Maybe this can help alleviate a bit of the “which system do you want it for?” question? (at least for 64-bit machines)
Other findings
- It was a struggle to get the
cosmocc
tools to work nicely with Windows, both PowerShell and WSL, but I did get it working. macOS and Ubuntu desktop had zero issues for me. Again, this struggle is for building an executable from source withcosmocc
. Once built, the final executable delivered to a user does not have nearly problems. - The built executables have no file extension. macOS and Linux don’t seem to mind. Windows really wants an extension. So append
.exe
or.com
to the filename to make Windows happy. - I had to
chmod
the executable I copied over to macOS to run it - Executables are actually just .zip files at the end of the day. Something like
inform6
could (for ease of use for a beginner) be distributed with basic libraries embedded into the executable. Likewise,vim
oremacs
could be stripped down to the IF-related basics to reduce filesize. - I’m still trying to figure out how to build libraries, like ncurses, to add to the
cosmocc
build workflow. It comes withlibc
compatible libraries, but adding additional 3rd party stuff requires extra know-how. - I have seen screenshots of someone getting
Command & Conquer
built with these tools, so more complex applications definitely seem possible. - There is a branch of Cosmopolitan which targets Windows Vista and Windows 7, in the interest of broadening the reach of such builds. I haven’t tried it.