A Personal, Opinionated Guide to the Rust Game Development Ecosystem
The Rust Game Development Working Group has been investigating creating an ecosystem guide, in a similar vein to arewegameyet.com. If there is one thing we have consensus on, it's that we want it to be impartial and not opinionated.
However, there is value in having opinionated guides to the ecosystem, even if the working group isn't the right place for it. It was proposed that individuals could write their own guides to fill this purpose. So here's mine!
I've only been involved in the Rust community for a few months, so I haven't actually used that many of these. However, I'll list out where I would point someone if they asked.
All-In-Ones
My personal preference is to find things that do one thing well and glue them together. But, if I wanted to ship something ASAP in Rust, I'd probably start with ggez, mostly because it's based on an existing framework. Or SDL2 if you want something battle-tested and don't mind native code
ggez- It's been around for a while, and it's based on an existing technical design (LÖVE). It also has clearly defined scope. If I were looking for a single library to meet broad but basic needs, I would start here.amethyst- This is a big ambitious project, and clearly a lot of good work has gone on here. They even have some sponsors!- The scope is very ambitious, and until recently it wasn't clear if there was much practical usage to help inform the technical design. However, they recently announced two showcase games. I'm hoping this will help prioritize the minimum required features for this project to see real-world usage.
- Several reusable libraries (
rendy,sheep,laminar) have come from this community already. This has been to the benefit of the broader ecosystem. - I wouldn't discourage anyone from giving this one a try.
sdl2- Putting Rust logic on top of proven, shipped C code is a legitimate strategy.coffee- Worth keeping an eye on! It's still... brewing.piston- Mentioned for completeness because it's been around for a long time and it has lots of downloads on crates.io. But the technical design, vision, and scope does not seem as well-defined as amethyst or ggez.
Low-Level Rendering
icefoxen's guide is more detailed than what I intend to do here, so I highly recommend giving that one a look.
First, you need a window to draw on. You will almost certainly use winit and most (all?) of the below build on that. (May 2020 edit: I've switched to using sdl2 for window management)
Once you have a window, there are a few options:
- There are wrappers around C-APIs if you want to write DirectX, Vulkan, etc. directly. (
ash,winapi/d3d12-rs,gl-rs,metal-rs) - There is a Vulkan-like API
gfx-halthat abstracts all these that quite a few people are using. It makes no attempt to be safe. There's a good tutorial available for this one. - The amethyst crew recently put out
rendy. It sits on top ofgfx-haland takes care of a lot its boilerplate, but without hidinggfx-halitself. You'll still need to write some "unsafe" code. - There are a couple "safe" (mostly) crates around OpenGL,
gliumandluminance. Andgfx(before it becamegfx_hal) attempted to be a safe API as well. - (July 2020 edit: I've been working on my own renderer)
I'm personally using Rendy, and I think gfx-hal and rendy are likely to be broadly adopted and supported long term. (May 2020 edit: I've switched to using ash/vulkan directly)
For higher level rendering, you could use sdl2, one of the above all-in-ones, or if you just want some shapes (pong?) maybe even wrap something like skia. There's even some terminal rendering libraries like tui-rs if you want to make something truly old-school. (May 2020 edit: I released Skulpin last year which embeds Skia into a Vulkan-backed window. It's even getting some real use!)
ECS
If you don't know what this is, I'd watch this video. ECS designs have their own merit, but aside from those benefits, specifically in Rust, they provide a good foundation that is relatively friendly to the borrow-checker.
specsis by far the most popular. It's a great place to start. There are some good ideas inlegiontoo.- For a while I used
shred- which is basicallyspecswithout the entities/components.
I ended up doing my own thing, but it's too early to recommend it to anyone in good conscience. (May 2020 edit: I've switched to legion, highly recommended!)
Math
There was a lot of good discussion here about the state of math libraries in Rust.
nalgebrais complete, well documented, and likely to be maintained for a long time. However, in my opinion, it is overly general for gamedev.nalgebra-glmis a wrapper that pairs most of that back.- If you want something lower level, look at
glam. It's a bit more efficient too. - In my opinion, the ideal math crate for lowest-level gamedev math in Rust does not exist yet. If I were to build it myself, I would port
DirectXMathwithout attempting to be Rust idiomatic. Then I'd put a wrapper around it that looks more like glam. (May 2020 edit: Usingglamfor now!)
Physics
nphysicsis a solid default choice. I think it has a bright future ahead of it. It uses nalgebra, so using both of them together is a natural choice.- You could also go with
bulletorbox2d. I'm not sure what the state of using this in Rust would be. Bullet has heavy integration with python, so I expect their C bindings are fairly complete. Embark very recently released somephysxbindings as well.
Sound
I haven't gotten far enough along to care about audio yet. There are some audio crates (cpal and rodio), but I haven't heard glowing reviews for any of them. I'd consider wrapping some C/C++ code. First places I'd look are sdl2, SoLoud, FMOD (not open source), and OpenAL.
Networking
Networking in gamedev is a really complex topic. It's actually my day job. But I haven't gotten far enough along to try anything myself in Rust yet.
I'm going to consider backend systems out of scope for the time being. And with async/futures landing imminently, the state of that ecosystem is likely to change. (keep an eye on tokio)
For replicating simulations:
- Amethyst is working on
laminarbut I'm not sure how far along they are. - The fastest path to ship something today is probably going to be opening a TCP socket and doing it yourself. Some kinds of games won't work well on TCP, but many will.
- But if you want to use UDP,
enetwill at least get you started with a reliable UDP implementation with flow control.
Honorable Mentions
- (May 2020 edit:
atelier-assetsmakes a great asset pipeline although it may be overkill for some people) imgui-rsis awesome. I'm using it. In its current form you may need some unsafe code to make it easier to use.serdeis a flexible serialization librarystrumfor turning enums into strings, and counting the number of elements in an enumnamed_typefor getting names out of types at runtimequoteandsynto get compile-time reflection (this is deserving of a blog post later)logandenv_loggerfor a basic logging framework. (buttracinglooks promising)lazy_staticfor those times you really need a global- If you need something from C/C++ likely someone already wrapped it for you! For example, I ported some code to rust that used
gpc- I was able to drop that into Rust and it worked immediately. imageis the unsung hero of loading texturessheepfor sprite sheet processing (it's pretty new!)
Final Comment
I will probably write something more about this later, but dependency management is one area where Rust shines. I expect that this will enable the community to build many small, high quality, single-purpose libraries that do one thing well. I think this will be key in the formation of a vibrant ecosystem that can support a broad variety of games and creators.