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.
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 download rust-sdl2, as that will be handled by
cargo in the next step.
In the root directory of the repository:
cd ruzzt
cargo run (Note that cargo 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.
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 the zzt_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.
请发表评论