RUZZT
A clone of the engine for the DOS game "ZZT", written in the Rust programming language.
My wife and I wrote this as a fun exercise, and went a lot further with it than originally anticipated. We wanted to try to replicate the original game's behaviour by simply looking at it running in Dosbox and seeing if we could make RUZZT do the same thing. This means the code architecture is likely very different from the original game.
Eventually we did get far enough that it seemed like a waste of time to try to guess how some specific things were implemented, so we used a disassembler to make sure various behaviours worked correctly.
Building
- Clone the repository.
- Install the Rust compiler (Rust).
- Since this project uses the
sdl2
Rust crate, you will need to install the appropriate SDL2
package for your operating system as well. Follow the instructions under the "Requirements"
heading in the sdl2 crate README to set up SDL2 on
your operating system. You do not need to downloadrust-sdl2
, as that will be handled by
cargo
in the next step. - In the root directory of the repository:
cd ruzzt
cargo run
(Note thatcargo
is shipped with the main Rust installer)
Note that you will probably want to download the original game and copy the .ZZT world files into
the folder where you run cargo run
, so that they show up in the world selection list
(you can download it from The Museum of ZZT).
Goals
- Replicate the behaviour of the original game as closely as possible.
- Use only safe Rust APIs.
- Use only logic and basic data structures and avoid memory tricks like Cell.
- Make the game logic modular where it makes sense, so that parts of the engine can be reused for
possible future ZZT front-end variants. - Make the code as "rustic" as possible.
Non-goals
- Anything related to out-of-bounds array access or reading random unexpected memory is considered
out-of-scope for this project. - If something depends on a tile's appearance on the screen not being updated to the game's current
state, then that behaviour is not considered at the current time. For example, in original ZZT,
a centipede that has just turned around will not be redrawn immediately, so you don't see the head
appearing at the end of the tail until it moves by one tile. - Super ZZT simulation support (although, SZT files should be able to be loaded via the
zzt_file_format
crate).
Status
RUZZT can be used to play most ZZT worlds correctly, including:
- TOWN.ZZT (at least, it worked last time I checked)
- The fractal generator from
PREPOSTM.ZZT
(this can be made to run to completion in 10 minutes if you take out all the sleeps in the code) - And probably a whole bunch of other stuff we haven't tested.
Known issues include:
- Missing game speed control feature
- Missing world editor (probably out of scope)
- Missing high score system
- Bomb+Conveyor bug doesn't work.
- This is where you try to activate a bomb that is rotating around a conveyor, and it displays a
bunch of random characters then causes both the player and the bomb to disappear, breaking the
game.
- This is where you try to activate a bomb that is rotating around a conveyor, and it displays a
- Severe lack of unit tests (at least there's a couple so far, better than nothing).
- Several instances of "TODO" in the code.
- And more!
Crates
ruzzt
- This is the main game executable. It defines how characters are drawn on the screen, and
how sounds are played.ruzzt_engine
- This is a library that can be used to simulate ZZT worlds. This module is
intended to be easily reusable for any ZZT front end. For example, you could go ahead and adapt
this for your own 3D ZZT clone.zzt_file_format
- This is a library that can read and write ZZT and SZT worlds. It supports
serde, so you can easily serialise and deserialise ZZT worlds to other
formats.zzt_to_json
- This is a simple command-line executable that uses thezzt_file_format
to
facilitate conversion between ZZT and JSON files.zzt_web_editor
- This is a work-in-progress ZZT world editor that runs in a web browser using
ruzzt_engine
to load and render worlds, compiles to WASM.
Architecture
The main game simulation is in the ruzzt_engine
crate. See main.rs
in the ruzzt
module for an
idea of how to use it. Maybe I'll expand this section later.