Why? Bored during COVID lockdown, actually. Then it started working. Here's two years ago:
Looks nice, but sluggish, no lighting, no normals, static scene, no dynamic content loading.
Looked like it was going to work. So I kept at it.
Technically, here's the problem I'm working on:
- High-detail shared virtual world with good graphics.
- Seamless big world, not little rooms with portals.
- User-created content which can be changed in the live world.
- Consistently high frame rate. (60 FPS or better.)
This is the base feature set for the "Ready Player One" / "Snow Crash" metaverse.
Many systems have three of the four. Nobody has all four. Second Life and Open Simulator have 1), 2), and 3), but the client is single-threaded C++ and does too little on the GPU, so it's sluggish and can't do 4) without reducing the draw distance and giving up 2). There are lots of systems where you have little closed worlds, maybe with portals, but no big landscapes. Sinespace/Breakroom are good examples. If you reduce the detail to cartoon level or below, you can get 2), 3), and 4). That's Decentraland and CryptoVoxels. If you preprocess all the content and do a lot of optimization during game development, you can make a good AAA title, but you give up 3).
User-created content means far less instancing, because each creator makes their own stuff. So you need to have a lot more content live to display a scene. It's about 3x over a commercial game, in practice. If you look closely at, say, Cyberpunk 2077, you'll see the same railing showing up all over the place. In Second Life, there are over 50,000 different chairs. So you need about 3x the GPU memory. And you need a lot of network bandwidth for dynamically loading content. Both are available today, and most Steam users have them.
To juggle all that data, you need heavy concurrency. You really need all those CPUs a modern desktop has. This is where Rust shines. If you try to do something this concurrent in C++, it's really hard. The Unity dev team had a big group working for years on that. Unreal Engine depends heavily on preprocessing and optimization of the content in Unreal Editor, which is not compatible with dynamically created user-created content. (Tim Sweeny, CEO of Unreal, was talking about supporting all that a few years ago, but we're not hearing that any more.)
The Rust ecosystem has most of the necessary crates. The trouble is that they're nowhere near finished. I've accomplished a lot, but, as I said, half my time goes into fixing or working around problems of the ecosystem.
A few more reasonably competent game devs using the same stack, so that this stuff gets pushed to the point where it Just Works, would bring the 3D crates up to a usable level.
At the bottom is Vulkan. That's maintained by Kronos and GPU makers for different platforms, and that's pretty solid. Just to be different, Apple has Metal.
Atop this, in the Rust world, we have WGPU. That's a cross-platform graphics system. So cross platform it does phones and web as well as desktop and laptop. Using WGPU, you still have to manage the buffer space and data structure allocation in the GPU yourself, which is a huge headache. But at least you get portability.
Atop WGPU, we have Rend3.
The Rend3 level provides management of all the graphics objects. The application creates meshes, 2D textures, materials, and objects, and Rend3 takes care of getting them into the GPU and displaying them. It's about at the level of classic OpenGL. It's all "retained mode" - you load content into the GPU and it goes, with minimal help from a CPU. That's how you get good performance.
Rend3 is basically a library - you call it. (Well, there's a "framework", to manage refreshing, and it owns the event loop, but you don't have to use it.) There's also Bevy, which is a full game engine, but an unfinished one undergoing a lot of churn.
Other key components are winit, the cross-platform window manager, and egui, which is a 2D overlay for menus and dialogs. They're mostly OK. Egui requires a lot of code for each GUI widget. It needs some kind of tool to generate widgets from JSON or XML or something.
All these crates are tightly coupled. All advance in version lockstep. So, every month or two, there's a big upgrade, it's necessary to deal with the API churn, and it's time to debug stuff that used to work. None of this stuff is documented beyond Rustdoc.
I never wanted to be on the cutting edge of Rust 3D development. I'm trying to solve a new problem, using what I though was a more mature ecosystem already being using by game devs. That's what the Rust hype said. That hasn't been updated since July 2023, by the way. I needed Rust because I knew this was going to need a lot of CPUs working hard to be fast enough. Rust does that part reasonably well.
I have a whole series of other problems to solve, related to that four-item list above. There's high-performance concurrent content wrangling, LOD change management, seamless crossings between regions, automatic impostor generation ... That's what I need to be working on, not fighting the low-level stuff.
If this stack had a few more projects using it for reasonably hard 3D work, most of the dirty laundry problems would get fixed. Most Rust game dev is simple 2D stuff, for which you don't really need Rust.
A few people have done 3D work in Rust, but they often use some C++ engine (DX11, Unity, etc.) for the graphics, so they can actually ship a product. Few are using the whole stack described here.
That's the problem. Comments?