Skip to content

A z-machine interpreter for running Infocom-era text adventure games on embedded hardware.

License

Notifications You must be signed in to change notification settings

daniel5151/embcrusted

Repository files navigation

embcrusted

A z-machine interpreter for Infocom-era text adventure games which can run on embedded hardware.

embcrusted is forked from encrusted, though it's been heavily refactored and stripped-down to run in an embedded no_std environment. It's missing all these features (and more!):

  • No Save / Load functionality
  • No fancy resource-intensive data structures (like hash-maps for dictionaries).
  • Not a single #[derive(Debug)] in sight

Here's a video of embcrusted playing Zork I off a Planck EZ Keyboard (running a ARM Cortex-M4 MCU), intercepting keystrokes as "input", and faking keystrokes as "output". Note that the game is running entirely on the keyboard, and only sends data to the device it's plugged into.

embcrusted running Zork I on a Plack EZ Keyboard

Check out the zorkey branch on my fork of the QMK firmware if you're interested in the code that makes this possible.

Target Platforms

embcrusted is completely no_std, though it does depend on alloc.

At the moment, embcrusted has only been tested on the following system:

Platform Flash ROM RAM
STM32F303xC (inside the Planck EZ keyboard) 256kb 48kb

Resource requirements

Storage and Memory requirements will vary by game (stack usage, dynamic-memory size, binary size) and compilation target (code density).

That said, here are some benchmarks I've collected using encrusted-ui-no-std (compiled and run on amd64, linked with libc, with inlined Zork I game data):

# additional RUSTFLAGS to strip binary during compilation.
# for full list of compiler flags, see the `profile.release` section in Cargo.toml
RUSTFLAGS='-C link-arg=-s' cargo +nightly run -p encrusted-ui-no-std --release
  • Storage Requirements
    • Just embcrusted: 60.43 KiB
    • Just Zork game data: 82.88 KiB
    • Just encrusted-ui-no-std (with Zork and embcrusted commented out): 19.07 KiB
    • Total Additional Storage: 143.32 KiB
  • Heap Usage
    • Zork base z-machine dynamic memory requirements: 11.58 KiB
    • z-machine interpreter (before first exec): 2.70 KiB
    • z-machine interpreter (after a bit of gameplay): 3.71 KiB
    • High Watermark Heap usage: 17.62 KiB

I did not benchmark stack usage during interpreter execution (though it probably isn't too much?).

Usage

In a nutshell:

  • Implement the embcrusted::Ui trait
  • Construct a new Zmachine interpreter with a reference to the game's data, your UI implementation, and an initial RNG seed
  • Run the interpreter in a loop, handling input and exit requests as necessary.

See the encrusted-ui and encrusted-ui-no-std packages for some basic examples.

Future work

At the moment, embcrusted meets the resource constrains of my target hardware, and as such, it's unlikely that I'll be improving it much further.

That said, if you're interested in helping out, there are a couple of places that could be improved / need some more work.

PRs are welcome!

  • RAM usage could be improved by refactoring String operations into in-place buffer manipulations, and replacing Vecs with static buffers.
    • This would also remove the dependency on alloc, for very resource constrained systems.
  • Binary size could be cut down further by adding feature-flags for specific z-machine version features.
  • It might be possible to shrink the game file down somewhat with some low-overhead decompression at runtime (e.g: heatshrink). I've done some preliminary tests, and while it's somewhat promising, it's not something I'll be integrating into embcrusted just yet. If you're interested in experimenting, take a look at buffer.rs 👀
  • A quick grep for "FIXME" or "TODO" will probably turn up plenty of things which need fixing 😄.

About

A z-machine interpreter for running Infocom-era text adventure games on embedded hardware.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages