Brett Makes Games
../the-state-of-game-dev-in-rust-2024

The State of Game Dev in Rust 2024: A Newcomer's Perspective

After taking about a yearlong break from game dev due to personal and professional parts of my life taking priority, I got the itch to dig back in again. Making games is where I started with programming, although my career has taken me down other avenues. But I also come back to it. I was checking out Raylib, drawn toward its simple API and stability. As I was writing C, it got me thinking, I'd really prefer using Rust! I've dabbled in Rust over the years—read The Book, made a simple CLI to learn, peeked around the landscape—but never committed to it in any serious way. I saw there are Raylib bindings for Rust, which then led me down a rabbithole for the last month to explore the state of game development in Rust. Here's what I see and where I think we can head from here!

First, a very brief intro. I'm a hobbyist game developer. I started game programming at a summer camp that used C# and XNA when I was a teenager. I've done full stack web development for my day job for the past 13 years. I've written a lot of Ruby and TypeScript. I've made a bunch of small games in a variety of languages and toolings, from C# to Haxe to Lua to Ruby to Godot. I've released a few small games. I wrote a book for beginners on game programming with Ruby, and I've made a handful of Godot tutorial videos on YouTube. I'm by no means a professional game developer, but I'm also not totally new to this whole thing.

My motivations and aspirations are the following: 1. make small games that I can finish 2. learn Rust & lower level programming 3. contribute to the community in a meaningful way to help others make games. I'm personally interested in making 2D action, puzzle, and role playing games, as well as simple 3D games (think PS1 era).

I've tried to check out and explore as many libraries, frameworks, and engines as possible to get the lay of the land before picking one for my first non-trivial Rust game. I like to read the documentation, experiment with the examples, and make simple games. Crates I've checked out: Bevy, Macroquad, Tetra, ggez, abg, Comfy, good-web-game, Pikuseru, bracket-lib, Raylib bindings, and SDL2 bindings. I've read Hands on Rust and gone through the examples. I've made few prototypes: a top down 2D shooter with Bevy, simple vertical shmup with Tetra, and a Sokoban client with Macroquad.

I'll start with the positives, of which there are many!

Rust feels really great to program in coming from TypeScript, Ruby, GDScript, and Haxe. Rust Analyzer + Neovim + CoC works really well, with inline docs, and instant feedback on changes. Structs + traits + enums are some of my favorite parts of the language. The compiler and clippy are a big help for learning the language. Cargo works well and seems stable. I love that I can have multiple bins in my project, which is great for dev tools and experimenting. I've been putting my game code in src/lib.rs and then src/main.rs is the main entryway, and then src/bin has my custom dev tools (a level editor, an input tester, and animation tester, etc.). Being able to cargo check all the bins quickly has been useful. Testing in Rust is top-notch—I unit test my functions where it makes sense (e.g., some math functions). And I've been writing integration tests for verifying asset files. For example, I've got an integration test that checks that all of the Sokoban levels included in the game are valid. Really thrilled with the language, and while the learning curve is steeper than other ones, I've found it to be exciting and rewarding. I'm still fumbling my way through architecture—I'm passing a global Context struct around because it's not clear how else to do that without singletons or some sort of global data structure that other languages have.

Rust has a rich ecosystem of game dev crates. From windowing to bindings to frameworks to engines. There's a lot happening, which is a good sign. I'll give an example: with Macroquad, there isn't built-in gamepad support yet, but there's a crate called gamepads that easily drops in and supports WASM. It works quite well. Excellent! Want to load maps from Tiled? There's a crate for that. Want to read Aseprite files directly into your game? There's a crate for that.

The community has been kind, and its active. I really love seeing all the various projects, updates, and writing about what's happening. Not every language is like that, and it's special and something worth acknowledging. Game dev in Ruby and Haxe are pretty small and quiet comparatively.

There are interesting games being made and shipped with Rust. I just bought and played USG by Pollapee on Steam. It's made with the Tetra crate. Tiny Glade made in Bevy looks really chill. doukutsu-rs is an impressive re-implementation of one of my favorite games, Cave Story. Veloren looks neat as heck. There are many more in development that I've checked out too. I think we'll only continue to see more and more interesting, high quality games ship with Rust. Shipping good games will help bring people to the language and a given engine/framework/library. I've also seen some interesting usecases of Rust being used in multi-language tech stacks (e.g., for writiting libraries used by other languages/tech).

It's not all sunshine and roses though! I'll start to dig into some of the challenges I see as a newcomer (and also offer up and be part of the solutions). There's a general lack of committment to stability. So many of the crates haven't reached 1.0 yet. And while that may seem arbitrary—just pin to a minor version and who cares, it signals to newcomers (like me) that by choosing an unstable crate, you're possibly committing to a world of pain when it comes to upgrading with breaking changes. (For example, I've got a Bevy 0.9 project from early 2023 when I dabbled with it for a week at that time that doesn't compile on my currently machine. Not a total surprise but a bummer). Having a major version released, especially for frameworks like Fyrox or Bevy or Macroquad, does at least two things: 1) lets game developers know they can expect some amount of stability (and possibly new features) in that release series 2) makes it much more appealing for educators to create books, videos, etc. about the framework. For example, with Godot 4, I expect at least a couple years of updates to that major version that will be compatible, so its much more compelling to record a video tutorial that'll be relevant for years to come with that version. Making a comprehensive tutorial video about Bevy 0.9 is a risk because it may be irrelevant and outdated within months. People today wouldn't want to watch that tutorial. Recording new videos or updating a book frequently is a lot of work, and having major version releases brings an implied commitment to some amount of support for that version that allows the ecosystem to grow around it. I very much understand this will come in due time. It's just one of the challenges of the Rust game dev ecosystem still being pretty young.

There's a related downside to the lack of commitment to stable, major versions of game frameworks and engines. There's no shortage of defunct game engines and frameworks and libraries. As a newcomer, there being a lack of 1.0+ Rust game frameworks and a big list of inactive, unmaintained ones makes it incredibly difficult to decide which library to go with. I mean absolutely zero shade to the creators and contributors to these projects. I very much get life happens, priorities change, and that this is all (mostly) free labor. This is an observation, and I'll offer some thoughts on how it could possibly be alleviated, as well as why I think it very common in Rust. If I search "Rust game engine recommendations," web pages will come up with lists of crates to use, many of which are not actively maintained. ggez, Tetra, amethyst, rend3, nannou, comfy, bracket-lib (RLTK), quicksilver, Oxygengine, keeshond, Ambient, Arete, etc. All of these crates are either inactive or passively maintained but look quite neat, interesting, and promising. Open source + game dev is immensely challenging, and I really appreciate that these projects exist. I've been able to learn a lot from ggez and Tetra in particular! But in my opinion, choosing a defunct crate isn't a good idea for a newcomer, as those crates will rot at Rust progresses, operating systems progress, etc. That's not ideal for the longevity I'd like for my projects at least. Ideally, in 15 years, I'll be able to compile and run my Rust projects, unlike my Flash projects from many moons ago.

An anecdote on lack of stability: Hands on Rust is a nice book for getting into Rust Game Dev. I like the writing and the projects and approach. But when I run the game code on my computer, it uses 97% CPU to render ASCIII characters. Something ain't right there! For a commercial book I purchased from a publisher, I do expect a bit more stability and less bugginess there. I very much understand and sympathize with the author of the book and bracket-lib needing to step away for personal reasons. But ideally people would be writing books against more stable libraries.

My take on why this is the case is because certain types of programmers are drawn to Rust: those interested in going a bit lower level or they're sick of C/C++'s problems. Maybe someone wants to code their own engine. Maybe someone wants to have minimal dependencies. Maybe someone wants to learn. So an individual digs in makes something. When it's functional-ish, they open source it! But that's not very resilient because the single point of failure is often that individual. Sure, someone could fork it or the maintainership could change, but more often than not it just goes silent. Bevy and Fyrox do a nice job of community maintainership. In particular, from the sidelines, I've seen Bevy really mature in how their organization and project is structured. Humans are, after all, at the core of all of this open source game dev stuff. And I think creating a more resilient, intentional game dev community is a key area of growth for the Rust game dev ecosystem.

The excited programmer who decides to dig into an engine first seems like approaching the problem fundamentally backwards in my opinion. Game engines are at their best when they're the byproduct of one (or more) shipped games (or when they have massive commercial funding). If the engine becomes available and useful, a community may then grow around it. And it'll evolve and grow to meet that community's needs. It seems immensely difficult to start an engine that isn't propelled by a game because an engine will just scope creep and scope creep because it'll want to be a lot of things to a lot of people. The bottleneck in many of the Rust crates I see is often the single maintainer project. There are lots of good, legit unmerged PRs out there! A shipped game, especially one that is profitable, is much more likely to lead to the funding of an engine into the future. Funding will help accelerate things, and an engine being used by games will help lead to decisions being made about scope. Successful games that then extract their engines/frameworks/libraries and contribute back to the ecosystem will massively help.

For me, and for any newcomer, I think what would be most impressive is seeing Rust crate that's 1.0+ with at least one interesting, polished game shipped with it. Ideally there are many games shipped with it. It should be easy to do the things every game needs (package and ship binaries, load and save data, textures, sounds, etc.). Even better is that there are tutorials, guides, a community structure for how it's maintained, and active development happening. Having a vision for a crate is arguably as important as having a vision for a game. As a developer, I don't want an everything engine. I want something I can learn pretty quickly, contribute to, and that gets me pretty quickly to making the game.

There has been a fair amount of negative chatter about Rust game dev from poking around online. The compile times are often complained about (but hasn't been so bad for me so far, we'll see how that is as my projects grow!). There was the comfy dev's break up letter (lots of interesting, good points but likely there's a bigger, long-term convo to have there). Jon Blow has a video saying Rust isn't good for game programming (clip titled "Rust Will Lose" 🙄). Embark ending funding for open source Rust projects after years of investment. This a pretty normal thing though—the great Language Wars. I'm sure folks have left Rust for Zig or Odin, etc. That's normal and to be expected. A lot of that stuff is just noise. But I do think it is up to the Rust Game Dev community to make the case for Rust being an excellent choice for game development beyond it just seeming like Rust should be a good fit for game development.

Game development is also a pretty weird term. When I say it, I think of small indie games—a few people or so. I think of Pico-8. I think of Celeste, Balatro, Stardew Valley. I think of Cave Story. But I also recognize some people think of Baldur's Gate 3 or The Witcher or Call of Duty. There's some weird dynamics there. Could a large AAA game be made with Rust? I'd imagine with time and money, sure! And there'll probably be good things over C++ and bad things. Rust, in 2024, to me, seems well suited for making solid 2D games, ambitious 2D games, and small 3D games. Ain't nothing wrong with that! There are a lot of good, interesting games to be made within that space. And maybe it'll become more viable for larger 3D projects in time. In my opinion, the Rust game dev community's goal should be: make Rust an incredible choice for ambitious indie developers with programmers who want full control of the source, a top-notch dev experience, and a great open source ecosystem. This means having stability, resources, and community support. And most importantly, shipped games! I believe the Rust game dev ecosystem evolving is dependent on there being interesting, finished, polished, games made with it. Console support will come in due time, just as it has with Haxe and other languages. It seems to be motivated by, honestly, money and the opportunity to make it on those platforms. The goal should be, IMO, how do we help the community make good games?

I've rambled about the highlights and challenges of using Rust. So where have I landed and what am I doing? Well, right now I'm enjoying using Macroquad. I love how simple it is, as it's been great for learning Rust. Support for WASM, especially for smaller games, is absolutely essential. Macroquad's aim for targeting as many platforms as possible is really appealing. Macroquad's track record is fairly consistent—years of development. Although I do worry about it primarily driven by just one person and it not being stable yet. It's a risk I know I've taken. I've started to contribute to Macroquad (improving the website to start and then writing docs next), so hopefully I can be part of the solution to some of the challenges I've outlined here.

Using Bevy felt too much like learning Bevy and its ECS, not Rust. Too much at once for me. I'm quite interested in checking out Bevy, Piston, and Fyrox in the future more deeply once I've got more of a handle on Rust. I'm also curious about using SDL2 or Raylib with bindings or going even a little more lower level to learn. But I don't know if I want to go down that rabbithole quite yet.

A stable landscape over time could look something like: engines like Fyrox & Bevy for more feature-full engines with advanced 3D capabilities & Macroquad for your go-to 2D and simple 3D library. Something neat that I haven't seen but think could be interesting: a Rust framework that makes it easy to script games with Rhai or Lua with live reload for fast prototyping. Then parts of it or all of it could be rewritten in Rust. Basically work quickly to start and then stabilize in Rust. Seems like it'd be very possible and an interesting experiment.

In summary: Rust's game dev ecosystem is still maturing and on its way. IMO, we need stable libaries and more educational resources. The ecosystem is pretty fragile right now, and I think stability will be bring growth and community ownership. And most of all, we need interesting, polished, shipped games. There are lots of defunct frameworks and engines, but also a handful of ones that persist and continue on! Macroquad, Bevy, Fyrox, Piston, and lower level bindings seem to be the most promising right now as of summer 2024. Who knows how that'll change and shift over time.

Back to making small games and trying to create resources to help folks. Excited to be along for this journey with y'all!