Comment by forrestthewoods

3 months ago

Rust is not good for video game gameplay logic. The ownership model of Rust can not represent the vast majority of allocations.

I love Rust. It’s not for shipping video games. No Tiny Glade doesn’t count.

Edit: don’t know why you’re downvoting. I love Rust. I use it at my job and look for ways to use it more. I’ve also shipped a lot of games. And if you look at Steam there are simply zero Rust made games in the top 2000. Zero. None nada zilch.

Also you’re strictly forbidden from shipping Rust code on PlayStation. So if you have a breakout indie hit on Steam in Rust (which has never happened) you can’t ship it on PS5. And maybe not Switch although I’m less certain.

> No Tiny Glade doesn’t count.

> And if you look at Steam there are simply zero Rust made games in the top 2000. Zero. None nada zilch.

Well, sure, if you arbitrarily exclude the popular game written in Rust, then of course there are no popular games written in Rust :)

> And maybe not Switch although I’m less certain.

I have talked to Nintendo SDK engineers about this and been told Rust is fine. It's not an official part of their toolchain, but if you can make Rust work they don't care.

> The ownership model of Rust can not represent the vast majority of allocations.

What allocations can you not do in Rust?

  • Gameplay code is a big bag of mutable data that lives for relatively unknown amounts of time. This is the antithesis of Rust.

    The Unity GameObject/Component model is pretty good. It’s very simple. And clearly very successful. This architecture can not be represented in Rust. There are a dozen ECS crates but no one has replicated the worlds most popular gameplay system architecture. Because they can’t.

    • Which part of that architecture is impossible in Rust? Actually an honest question, I'm wondering if I'm missing something.

      From what I remember from my Unity days (which granted, were a long time ago), GameObjects had their own lifecycle system separate from the C# runtime and had to be created and deleted using Destroy and Create calls in the Unity API. Similarly, components and references to them had to be created and retrieved using the GetComponent calls, which internally used handles, rather than being raw GC pointers. Runtime allocation of objects frequently caused GC issues, so you were practically required to pre-allocate them in an object pool anyway.

      I don't see how any of those things would be impossible or even difficult to implement in Rust. In fact, this model is almost exactly what I used to see evangelized all the time for C++ engines (using safe handles and allocator pools) in GDC presentations back then.

      In my view, as someone who has not really interacted or explored Rust gamedev much, the issue is more that Bevy has been attempting to present an overtly ambitious API, as opposed to focusing on a simpler, less idealistic one, and since it is the poster child for Rust game engines, people keep tripping over those problems.

    • > ... big bag of mutable data that lives for relatively unknown amounts of time. This is the antithesis of Rust.

      I'm sorry, but I still don't understand. There are myriad heap collections and even fancy stuff like Rc<Box<T>> or RefCell<T>. What am I missing here?

      Is it as simple as global void pointers in C? No, but it's way safer.

      1 reply →

You could probably write the core in Rust and use some sort of scripting for gameplay logic. Warframe's gameplay logic is written in Lua.

The headline is a bit sensational here and shall have been rather called "Migrating away from Bevy" .. That's not (really) comparing C# to Rust (and Luna but that one is missing), but rather comparing game engine where the language is secondary. Obviously Unity is the leader here (with Unreal) - despite all its flaws.

> No Tiny Glade doesn’t count.

Tiny Glade is also the buggiest Steam game I've ever encountered (bugs from disappearing cursor to not launching at all). Incredibly poor performance as well for a low poly game, even if it has fancy lighting...

> Also you’re strictly forbidden from shipping Rust code on PlayStation. So if you have a breakout indie hit on Steam in Rust (which has never happened) you can’t ship it on PS5. And maybe not Switch although I’m less certain.

What evidence do you have for this statement? It kind of doesn't make any sense on its face. Binaries are binaries, no matter what tools are used to compile them. Sure, you might need to use whatever platform-specific SDK stuff to sign the binary or whatever, but why would Rust in particular be singled out as being forbidden?

Despite not being yet released publicly, Jai can compile code for PlayStation, Xbox, and Switch platforms (with platform-specific modules not included in the beta release, available upon request provided proof of platform SDK access).

  • Sony mandates you use their toolchain. You don’t get to ship whatever you want on their console. They have a very thorough TRC check you must pass before you get to ship.

    • Rust being forbidden on a platform, and Rust being unsupported out-of-the-box with the SDK toolchain, seem to me like they're rather different things?

Isn't Veloren doing pretty good?

  • No. No one plays Veloren. It’s a toy project for programmers.

    No offense to the project. It’s cool and I’m glad it exists. But if you were to plot the top 2000 games on Steam by time played there are, I believe, precisely zero written in Rust.

> Rust can not represent the vast majority of allocations

Do you mean cyclic types?

Rust being low-level, nobody prevents one from implementing garbage-collected types, and I've been looking into this myself: https://github.com/Manishearth/rust-gc

It's "Simple tracing (mark and sweep) garbage collector for Rust", which allows cyclic allocations with simple `Gc<Foo>` syntax. Can't vouch for that implementation, but something like this would be good for many cases.