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.
- Clone the repository.
- Install the Rust compiler (Rust).
- Since this project uses the
sdl2Rust 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 download
rust-sdl2, as that will be handled by
cargoin the next step.
- In the root directory of the repository:
cargo run(Note that
cargois 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).
- 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.
- 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
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.
- 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!
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 the
zzt_file_formatto 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_engineto load and render worlds, compiles to WASM.
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.