Write a First Person Game in 2KB with Rust
grantshandy.github.io
grantshandy.github.io
I've been thinking about re-writing my raycasting engine in Rust but never really found the time - glad to see someone has done it and documented it so well!
If anyone else is interested in raycasting this page is also worth a read: https://lodev.org/cgtutor/raycasting.html
You wouldn't use the same technique to implement a "realistic" 6DOF flight simulator, for example. Wolfenstein 3D released in 1992 - and a mere year later, Microsoft Flight Simulator 5 would be released, with actual 3D meshes and arbitrary 3D rotations coming much earlier.
I think 128 bytes may be close to a lower limit, although for a different platform (MS-DOS): https://www.pouet.net/prod.php?which=63518
Sharing experiences. My first encounter and fascination for these kind of perpective effect was in the 90s demoscene.
I learned to program the magic behind "tunnel" effects by just spawning multiple non-concentric growing circles.
Actually not sure if I'll get around to finishing it, but currently a WebGPU-based renderer + scene graph + softsynth fits in about 30k compressed. That's unfortunately a bit big, but we'll see.
If I don't get around to finishing it I'll probably open source the code anyway, just as a fun starting point for others maybe.
Do you think it’s the WebGPU, scene graph, the sound, or the Rust infrastructure that consumes the most space?
Additionally, there's just a lot of code being generated for common containers. It would probably be simpler and smaller to create unsafe containers that just shift pointers to boxed structs around or something, but I haven't gotten around to that yet.
My group: https://www.ctrl-alt-test.fr/productions/
The Pouet search contains a good list of modern 64kB: https://www.pouet.net/toplist.php?type=64k&platform=68&limit...
I don't think he mentions it, and I doubt it's relevant in your Hello World example, but if you have a lot of generic code, it's useful to extract the non-generic parts into a separate non-generic function. For example:
fn foo<T: AsRef<str>>(s: T) -> String {
bar(s.as_ref())
}
fn bar(s: &str) -> String {
// A whole bunch of other stuff
s.to_string()
}Also depth buffers only ever were viable with dedicated rasterization hardware, and on early consumer "GPUs" they were a luxury because even when depth testing was supported, they reduced rendering performance by half - which basically meant "utterly unplayable". It was almost always better to determine surface visibility through other techniques.