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.

  • 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.
  • 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.
  • sdl2 - I haven't tried using it myself, but putting Rust logic on top of proven, shipped C code is a legitimate strategy.

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.

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-hal that 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 of gfx-hal and takes care of a lot its boilerplate, but without hiding gfx-hal itself. You'll still need to write some "unsafe" code.
  • There are a couple "safe" (mostly) crates around OpenGL, glium and luminance. And gfx (before it became gfx_hal) attempted to be a safe API as well.

I'm personally using Rendy, and I think gfx-hal and rendy are likely to be broadly adopted and supported long term.

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.

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.

  • specs is by far the most popular. It's a great place to start. There are some good ideas in legion too.
  • For a while I used shred - which is basically specs without the entities/components.

(I ended up doing my own thing, but it's too early to recommend it to anyone in good conscience.)

Math

There was a lot of good discussion here about the state of math libraries in Rust.

  • nalgebra is complete, well documented, and likely to be maintained for a long time. However, in my opinion, it is overly general for gamedev. nalgebra-glm is 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 DirectXMath without attempting to be Rust idiomatic. Then I'd put a wrapper around it that looks more like glam.

Physics

  • nphysics is 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 bullet or box2d. 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 some physx bindings 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 laminar but 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, enet will at least get you started with a reliable UDP implementation with flow control.

Honorable Mentions

  • imgui-rs is awesome. I'm using it. In its current form you may need some unsafe code to make it easier to use.
  • serde is a flexible serialization library
  • strum for turning enums into strings, and counting the number of elements in an enum
  • named_type for getting names out of types at runtime
  • quote and syn to get compile-time reflection (this is deserving of a blog post later)
  • log and env_logger for a basic logging framework. (but tracing looks promising)
  • lazy_static for 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.
  • image is the unsung hero of loading textures
  • sheep for 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.