Vul[kan] du[um] is a Doom port written by me completely from scratch in Rust, with Vulkan rendering and the ECS pattern in the game loop. The project's ultimate goal is to achieve maximum performance on large maps through multithreaded computations, which was fundamentally impossible in the original Id Tech 1.
Note: Vuldu requires a GPU with Vulkan 1.3 support.
First, download the latest release, as well as the wad you want to run (for example, DOOM2.WAD). To run it, open the command line in the game folder and enter:
./vuldu -i your/path/to/DOOM2.WAD You can view the application's parameters
using ./vuldu -h
- winit => Window management
- hecs => Implementation of the ECS world and entities
- rodio => Spatial audio
- serde => Parsing of toml tables
- cxx => FFI bridge between Rust and the C++ renderer
- earcut algorithm => Floor triangulation
It is important to note that I deliberately chose two libraries for multithreading, as they work differently and solve opposite problems:
Rayon is optimized for maximum performance. It achieves this through work stealing: if a thread finishes its work, it takes parts of the work from another thread. It works perfectly for preparing data during loading.
However, practice shows that "work stealing" is unstable when the game's framerate depends on it. Therefore, I chose micropool, which works on the principle of busy waiting: after finishing their work, threads do not go to sleep, but wait so that they can start executing the next task as quickly as possible. It works perfectly when more data needs to be processed without significantly increasing the load.
The project is designed so that the crates are loosely coupled with each other in a strictly one-way order:
↓ Renderer ↓
The FFI bridge leads to renderer_cpp/, where the Vulkan
class is implemented in C++ and safely abstracted in
src/lib.rs for subsequent use of its methods in
Rust. The graphics pipeline is designed with
mass resource processing and minimization of
draw calls in mind.
Objects and UI make extensive use of Instancing, allowing tens of thousands of instances to be displayed on screen with almost no impact on FPS.
> App <
The main coordination center of the project. In
App::resumed() you can find the window initialization
code, while WindowEvent::RedrawRequested contains the
code for redrawing it.
Overall, in App, all other crates are merged together
in the form of GraphicsContext and GameContext, while
also handling audio and user input.
↑ Engine ↑
This is where all ECS systems related to movement, vision, sound propagation, etc. live. Engine can modify level and entity data during gameplay.
There is more code inspired by John Carmack's original source code here than anywhere else in the project.
↑ Wad Parser ↑
In this crate, bytes from the wad are converted into
textures and levels. All file resource management is
handled through the WadManager object, which stores
lumps associated with their source file.
In src/textures/, textures from the patch format
are converted into an array of PLAYPAL color indices.
In src/vertices/, sectors and the linedefs surrounding
them are triangulated into floors and walls and turned
into a fully-fledged 3D scene.
For a local build, you need the Vulkan SDK. After installing it, clone the repository to your computer:
cd your/local/path
git clone https://github.com/2017Knight2017/Vuldu.gitPlace the wad you plan to run (for example, DOOM2.WAD) there as well. After that, compile and run the project using cargo:
cargo build
cargo run -- -i DOOM2.WADVuldu is licensed under GNU General Public License 3.0.
