798 comments

[ 0.30 ms ] story [ 448 ms ] thread
Good for them.

From a dev perspective, I think, Rust and Bevy are the right direction, but after reading this account, Bevy probably isn't there yet.

For a long time, Unity games felt sluggish and bloated, but somehow they got that fixed. I played some games lately that run pretty smoothly on decade old hardware.

Love to have this comparison analysis. Huge LOC difference between Rust and C# (64k -> 17k!!!) though I am sure that is mostly access to additional external libraries that did things they wrote by hand in Rust.
The article says it's 64k -> 17k.
That's not unexpected they went from Bevy which is more of a game framework, than a proper GUI engine.

I mean, you could also write how we went from C# code 1mil code of our mostly custom engine to 10k in Unreal C++.

C# is a very highly underrated (and oft misunderstood) language that has become more terse as it has aged -- in a very good way. C#'s terseness has not come at the cost of its legibility and in fact, I feel like enhances it in many cases.

    > The maturity and vast amount of stable historical data for C# and the Unity API mean that tools like Gemini consistently provide highly relevant guidance.
This is also a highly underrated aspect of C# in that its surface area has largely remained stable from v1 (few breaking changes (though there are some valid complaints that surface from this with regards to keyword bloat!)). So the historical volume of extremely well-written documentation is a boon for LLMs. While you may get out-dated patterns (e.g. not using latest language features for terseness), you will not likely get non-working code because of the large and stable set of first party dependencies (whereas outdated 3rd party dependencies in Node often leads to breaking incompatibilities with the latest packages on NPM).

    > It was also a huge boost to his confidence and contributed to a new feeling of momentum. I should point out that Blake had never written C# before.
Often overlooked with C# is its killer feature: productivity. Yes, when you get a "batteries included" framework and those "batteries" are quite good, you can be productive. Having a centralized repository for first party documentation is also a huge boon for productivity. When you have an extremely broad, well-written, well-organized standard library and first party libraries, it's very easy to ramp up productivity versus finding different 3rd party packages to fill gaps. Entity Framework, for example, feels miles better to me than Prisma, TypeORM, Drizzle, or any option on Node.js. Having first party rate limiting libraries OOB for web APIs is great for productivity. Same for having first party OpenAPI schema generators.

Less time wasted sifting through half-baked solutions.

    > Code size shrank substantially, massively improving maintainability. As far as I can tell, most of this savings was just in the elimination of ECS boilerplate.
C# has three "super powers" to reduce code bloat which is its really rich runtime reflection, first-class expression trees, and Roslyn source generators to generate code on the fly. Used correctly, this can remove a lot of boilerplate and "templatey" code.

---

I make the case that many teams that outgrow JS/TS on Node.js should look to C# because of its congruence to TS[0] before Go, Java, Kotlin, and certainly not Rust.

[0] https://typescript-is-like-csharp.chrlschn.dev/

C# has aged better but I feel like Java 8 approaching ANSI C level solid tools. If only Swing wasn't so ugly. They should poach Raymond Chen to make Java 8 Remastered I like his blog posts. There's probably a DOS joke in there. Also they should just use the JavaFX namespace so I don't have to change my code and I want the lawyer here to laugh too.
> Java 8

Why would you use Java 8?

Java current version is 24.
Java's current version is Kotlin /joke
Sure, where can I download the Kotlin Virtual Machine, with a standard library implemented in Kotlin?

If you feel like replying with ART, there are plenty of .java files in AOSP.

[gong sound]

The Master said, “I consider my not being present at the sacrifice, as if I did not sacrifice.”

The Analects (Confucius, 551-479 BCE), translated by James Legge (1815-1897)

> C# is a very highly underrated (and oft misunderstood) language that has become more terse as it has aged -- in a very good way. C#'s terseness has not come at the cost of its legibility and in fact, I feel like enhances it in many cases.

C# and .net are one of the most mature platform for development of all kind. It's just that online, it carries some sort of anti Microsoft stigma...

But a lot of AA or indie games are written in C# and they do fine. It's not just C++ or Rust in that industry.

People tend to be influenced by opinions online but often the real world is completely different. Been using C# for a decade now and it's one of the most productive language I have ever used, easy to set up, powerful toolchains... and yes a lot of closed source libs in the .net ecosystem but the open source community is large too by now.

    > People tend to be influenced by opinions online but often the real world is completely different.
Unfortunately, my experience has been that C#'s lack of popularity online translates into a lot of misunderstandings about the language and thus many teams simply do not consider it.

Some folks still think it's Windows-only. Some folks think you need to use Visual Studio. Some think it's too hard to learn. Lots of misconceptions lead to teams overlooking it for more "hyped" languages like Rust and Go.

You don't need to use Visual Studio, but it really makes a difference in the overall experience.

I think there may also be some misunderstandings regarding the purchase models around these tools. Visual Studio 2022 Professional is possible to outright purchase for $500 [0] and use perpetually. You do NOT need a subscription. I've got a license key printed on paper that I can use to activate my copy each time.

Imagine a plumber or electrician spending time worrying about the ideological consequences of purchasing critical tools that cost a few hundred dollars.

[0] https://www.microsoft.com/en-us/d/visual-studio-professional...

    > Imagine a plumber or electrician spending time worrying about the ideological consequences of purchasing critical tools that cost a few hundred dollars.
That's just the way it is, especially with startups whom I think would benefit the most from C# because -- believe it or not -- I actually think that most startups would be able to move faster with C# on the backend than TypeScript.
> Some folks think you need to use Visual Studio

How's the LSP support nowadays? I remember reading a lot of complaints about how badly done the LSP is compared to Visual Studio.

Pretty good.

I started using Visual Studio Code exclusively around 2020 for C# work and it's been great. Lightweight and fast. I did try Rider and 100% it is better if you are open to paying for a license and if you need more powerful refactoring, but I find VSC to be perfectly usable and I prefer its "lighter" feel.

I still think Visual Studio is better, but you can easily work on small to mid-size projects in VSCode. Could you use Vim? I probably wouldn't, but you can say the same for Java.
C# is a great language, but it's been hampered by slow transition towards AOT.

My understanding (not having used it much, precisely because of this) is that AOT is still quite lacking; not very performant and not so seamless when it comes to cross-platform targeting. Do you know if things have gotten better recently?

I think fhat Microsoft had dropped the old .NET platform (CLR and so on) sooner and really nailed the AOT experience, they may have had a chance at competing with Go and even Rust and C++ for some things, but I suspect that ship has sailed, as it has for languages like D and Nim.

C# (well, .NET, because that's what does JIT/AOT compilation of the bytecode) is not transitioning to AOT. NativeAOT is just one of the ways to publish .NET applications for scenarios where it is desirable. Having JIT is a huge boon to a number of scenarios too, for example it is basically impossible to implement a competitive Regex engine with JIT compilation for the patterns in Go (aside from other limitations like not having SIMD primitives).
Transition to better AOT, .NET has had AOT support since version 1.0, even if using NGEN is a bit clunky.
> C# is a very highly underrated (and oft misunderstood) language that has become more terse as it has aged -- in a very good way

One negative aspect is that if you haven't kept up, that terseness can be a bit of a brick wall. Many of the newer features, especially things where the .Net framework just takes over and solves your problem for you in a "convention over configuration" kinda way, are extremely terse. Modern C# can have a bit of a learning curve.

C# is an underrate language for sure and once you get going it is an absolute joy to work in. The .Net platform also gives you all the cross-platform and ease of deployment features of languages like Go. Ignoring C#/.Net because it's Microsoft is a bit of a mistake.

> I am sure that is mostly access to additional external libraries that did things they wrote by hand in Rust

This is the biggest reason I push for C#/.NET in "serious business" where concerns like auditing and compliance are non-negotiable aspects of the software engineering process. Virtually all of the batteries are included already.

For example, which 3rd party vendors we use to build products is something that customers in sectors like banking care deeply about. No one is going to install your SaaS product inside their sacred walled garden if it depends on parties they don't already trust or can't easily vet themselves. Microsoft is a party that virtually everyone can get on board with in these contexts. No one has to jump through a bunch of hoops to explain why the bank should trust System or Microsoft namespaces. Having ~everything you need already included makes it an obvious choice if you are serious about approaching highly sensitive customers.

Hugely underrated aspect of .NET. If a CVE surfaces, there's a team a Microsoft that owns the code and is going to patch and ship a fix.
I worked in a regulated space at one time, and my understanding is that this is a big reason they chose .NET over Java. Java relies a lot more on third-party libraries, which makes getting things certified harder.

Log4shell was a good example of a relative strength of .NET in this area. If a comparable bug had happened in .NET's standard logging tooling, we likely would have seen all of the first-party .NET framework patched fairly shortly after, in a single coordinated release that we could upgrade to with minimal fuss. Meanwhile, at my current job we've still got standing exceptions allowing vulnerable version of log4j in certain services because they depend on some package that still has a hard dependency on a vulnerable version, which they in turn say they can't fix yet because they're waiting on one of their transitive dependencies to fix it, and so on. We can (and do) run periodic audits to confirm that the vulnerable parts of log4j aren't being used, but being able to put the whole thing in the past within a week or two would be vastly preferable to still having to actively worry about it 5 years later.

The relative conciseness of C# code that the parent poster mentioned was also a factor. Just shooting from the hip, I'd guess that I can get the same job done in about 2/3 as much code when I'm using C# instead of Java. Assuming that's accurate, that means that with Java we'd have had 50% more code to certify, 50% more code to maintain, 50% more code to re-certify as part of maintenance...

None of this makes any sense. There is no waiting. You just do it. In no universe can you justify using a vulnerable log4j version. You force gradle to use the patched log4j and be done with it.

Five years has nothing to do with Java. It means nobody cares about security in the first place. Outsourcing such a trivial security problem to Microsoft is just another nail in the coffin. "I have no capacity to develop secure software, better make myself dependent on someone who can".

> There is no waiting. You just do it. In no universe can you justify using a vulnerable log4j version.

I agree.

We had been doing interop with a Java process from C# to access some document processing functionality during the log4j incident. The library we were using depended on log4j and had a clear resolution at the time, but there was a big perception problem in our client base (i.e., non-technical people that we must suffer in order to continue doing business).

Our solution to the resulting paranoia was to remove Java from our stack altogether. It was a big pain in the ass to find an alternative, but it was definitely worth it from a customer service perspective. Our clients were very happy with this approach and it saved us from a lot of messy meetings that other vendors were sucked into.

I'm not saying that making an exception is the correct course of action. But it isn't my call to make so it kind of doesn't matter what I think in this case.

What I'm trying to point out is that I've never known this kind of security vulnerability to be quite such a hassle to eradicate when working on the .NET stack. Because the "batteries included" nature of .NET just makes it easier. On Java the supply chain tends to be more unwieldy. Which seems to engender both increased maintenance hassle and a greater tendency toward normalization of deviance. Perhaps as a way to try to sand the sharp corners off of the maintenance hassle.

In sectors that are critical here in the EU, nobody allows c# and microsoft due to licensing woes longterm. It's java and foss all the way down. SaaS also is not a thing unless it runs on prem.
What kind of nonsense is this? EU is perfectly happy to use .NET-based languages as all of them, and the platform itself, are MIT (in fact, it's pretty popular out here).
C# and Microsoft are in all critical places in Europe. What are you talking about
As European, in a polyglot agency, I have no idea of what you're talking about.
That's absurdly wrong
Don’t see any content on that article for some reason (from iPhone)
I experienced the same, I had to disable my adblocker to view it, it seems the content is inside a tag `<article class="social-sharing">` but I am unsure whether this triggered my adblocker.
Adblocking seems to cause issues with the site. Disabling uBlock Origin worked for me as did readability mode in Firefox.
(comment deleted)
Somehow I can't read this with uBlock Origin on. Hm.
Strange, I had no such issue.
Me neither. Default uBlock Origin settings though, maybe the OP is more strict.
I did the same for my project and moved to Go from Rust. My iteration is much faster, but the code a bit more brittle, esp. for concurrency. Tests have become more important.

Still, given the nature of what my project is (APIs and basic financial stuff), I think it was the right choice. I still plan to write about 5% of the project in Rust and call it from Go, if required, as there is a piece of code that simply cannot be fast enough, but I estimate for 95% of the project Go will be more than fast enough.

Is calling Rust from Go fast? Last time I checked the interface between C and Go is very slow
Rust is no different from C in that respect.
I have no experience with FFI between C and Go, could anyone shed some light on this? They are both natively compiled languages – why would calls between them be much slower than any old function call?
There's some type translation and the Go runtime needs to turn some things off before calling out to C
There are two reasons:

• Go uses its own custom ABI and resizeable stacks, so there's some overhead to switching where the "Go context" must be saved and some things locked.

• Go's goroutines are a kind of preemptive green thread where multiple goroutines share the same OS thread. When calling C, the goroutine scheduler must jump through some hoops to ensure that this caller doesn't stall other goroutines on the same thread.

Calling C code from Go used to be slow, but over the last 10 years much of this overhead has been eliminated. In Go 1.21 (which came with major optimizations), a C call was down to about 40ns [1]. There are now some annotations you can use to further help speed up C calls.

[1] https://shane.ai/posts/cgo-performance-in-go1.21/

And P/Invoke call can be as cheap as a direct C call, at 1-4ns

In Unity, Mono and/or IL2CPP's interop mechanism also ends up in the ballpark of direct call cost.

No, it is not all that fast after the CGo call marshaling (Rust would need to compile to the C ABI). I would essentially call in to Rust to start the code, run it in its own thread pool and then call into Rust again to stop it. The time to start and stop don't really matter as this is code that runs from minutes to hours and is embarrassingly parallel.
> but the code a bit more brittle, esp. for concurrency

Obligatory ”remember to `go run -race`”, that thing is a life saver. I never run into difficult data races or deadlocks and I’m regularly doing things like starting multiple threads to race with cancelation signals, extending timeouts etc. It’s by far my favorite concurrency model.

Yep, I do use that, but after getting used to Rust's Send/Sync traits it feels wild and crazy there are no guardrails now on memory access between threads. More a feel thing than reality, but I just find I need to be a bit more careful.
> I still plan to write about 5% of the project in Rust and call it from Go, if required

And chances are that it won't be required.

This seems like the right call. When it comes to projects like these, efficiency is almost everything. Speaking about my own experiences, when I hit a snag in productivity in a project like this, it's almost always a death-knell.

I too have a hobby-level interest in Rust, but doing things in Rust is, in my experience, almost always just harder. I mean no slight to the language, but this has universally been my experience.

The advantages of correctness, memory safety, and a rich type system are worth something, but I expect it's a lot less when you're up against the value of a whole game design ecosystem with tools, assets, modules, examples, documentation, and ChatGPT right there to tell you how it all fits together.

Perhaps someday there will be a comparable game engine written in Rust, but it would probably take a major commercial sponsor to make it happen.

One of the challenges I never quite got over completely, was that I was always fighting rust fundamentals, which tells me I never fully assimilated into thinking like a rustacean.

This was more of a me-problem, but I was constantly having to change my strategy to avoid fighting the borrow-checker, manage references, etc. In any case, it was a productivity sink.

I bet, and that's particularly difficult when so much of modern game dev is just repeating extremely well-worn patterns— moving entities around and providing for scripted and emergent interactions between those entities and the player(s).

That's not to say that games aren't a very cool space to be in, but the challenges have moved beyond the code. Particularly in the indie space, for 10+ years it's been all about story, characters, writing, artwork, visual identity, sound and music design, pacing, unique gameplay mechanics, etc. If you're making a game in 2025 and the hard part is the code, then you're almost certainly doing it wrong.

This was my experience with Rust. I've bounced off it a few times and I think I've decided its just not for me.
Personally, I don’t think of it as fighting, more like “compiler assistance” —

you want to make some change, so you adjust a struct or a function signature, and then your IDE highlights all the places where changes are necessary with red squigglies.

Once you’re done playing whack-a-mole with the red squigglies, and tests pass, you know there’s no weird random crash hiding somewhere

It is a question of tradeoffs. Indie studios should be happy to trade off some performance in exchange for more developer productivity (since performance is usually good enough anyway in an indie game, which usually don't have millions of entities, meanwhile developer productivity is a common failure point).
I wonder why Godot wasn't picked. Did I miss the points in the article?
I also would have liked to have seen the pro/con lists for each of the potential choices.

I've been toying with the idea of making a 2d game that I've had on my mind for awhile, but have no game development experience, and am having trouble deciding where to start (obviously wanting to avoid the author's predicament of choosing something and having to switch down the line).

The key is, you gotta be pretty cold in the analysis. It's probably more important to avoid what you hate than to lean in too hard to what you love, unless your terminal goal is to work in $FAVE_LANG. Too many people claim they want to make a game, but their actions show that their terminal goal was actually to work in their favorite language. I don't care if your goal is just to work in your favorite language, I just think you need to be brutally honest with yourself on that front.

Probably the best thing in your case is, look at the top three engines you could consider, spend maybe four hours gather what look like pros and cons, then just pick one and go. Don't overestimate your attachment to your first choice. You'll learn more just in finishing a tutorial for any of them then you can possibly learn with analysis in advance.

Thanks, I appreciate the comment! I'm certain that my goal is not to work in a specific language, but to bring a long-time idea to life, and ideally minimize the amount of avoidable headaches along the way.

You're probably right that it'd be best to just jump in and get going with a few of them rather than analyze the choice to death (as I am prone to do when starting anything).

This is goes for a lot of things in tech unfortunately. For example, being stuck in a SRE/devops amusement park can be incredibly frustrating and surprisingly resource intense.

Sometimes it feels like we could use some kind of a temperance movement, because if one can just manage to walk the line one can often reap great rewards. But the incentives seem to be pointing in the opposite direction.

I'm beginning to develop a heuristic around the concept of "amount of the library you use". It's intrinsically fuzzy and still something I'm working on, but in general, it's bad to use only a tiny fraction of a library or framework, and really bad to have a code base in which a large number of things are pulled in that you only use small fractions of.

There are some exceptions, e.g., pulling in your languages best-of-breed image library to load some JPGs even though it supports literally a dozen other formats is less disastrous to a code base than pulling in an industrial-strength web framework just to provide two API calls with some basic auth of some sort. But there's something to the concept in general, I think.

That sounds like a good balance indeed.
I wondered the same - the separate C# build might be a bit of a hassle still though.

But they also could have combined Rust parts and C# parts if they needed to keep some of what they had.

One of the complaints in the article was using a framework early in it's dev cycle. I imagine they were just picking what is safe at that point and didn't want to get burned again.
> We wrote extensive pros and cons, emphasizing how each option fared by the criteria above: Collaboration, Abstraction, Migration, Learning, and Modding.

Would you really expect Godot to win out over Unity given those priorities? Godot is pretty awesome these days, but it's still going to be behind for those priorities vs. Unity or Unreal.

The article title is half-true. It wasn't so much they migrated away from Rust, but that they migrated away from Bevy, which is an alpha quality game engine.

I wouldn't have read the article if it'd been labeled that, so kudos to the blog writer, I guess.

More surprising part for me is not migrating from Rust/Bevy, but migrating _to_ C#/Unity.

Although points mentioned in the post are quite valid.

Where would you migrate to?
Maybe godot? The unity scandal recently is not great for developers.
People forget that Unity and Unreal are industry darlings for a reason.

The amount of platforms they support, the amount of features they support, many of which could be a PhD thesis in graphics programming, the tooling, the store,....

Not OP, but it seems that there is still a huge sentiment that Unity is not a "safe" platform to migrate to because of their relatively antagonistic approach to monetization guidelines compared to other open source game engines. I do think it makes sense to also consider Godot given his coworker is his brother who is stated to be new to game development, it has a scripting language even simpler than C#, more like python. Additionally, one might expect that someone more into Rust might prefer the C++ integration that Unreal offers. I think the timeline had an effect here too, as it's not been until recently that people have been taking Godot more seriously.
Personally, literally anything except Unity. The fact that they tried to retroactively change terms on developers means that it will be a long time before I feel comfortable trusting they won't try it again.
The problem with Rust is that almost everything is still at an alpha stage. The vast majority of crates are at version 0.x and are eventually abandoned, replaced, or subject to constant breaking changes

While the language itself is great and stable, the ecosystem is not, and reverting to more conservative options is often the most reasonable choice, especially for long-term projects.

I really don’t think Rust is a good match for game dev. Both because of the borrow checker which requires a lot of handles instead of pointers and because compile times are just not great.

But outside of games the situation looks very different. “Almost everything” is just not at all accurate. There are tons of very stable and productive ecosystems in Rust.

Borrow checker is mostly a strawman for this discussion, the post is about using Bevy as an engine and Bevy uses an ECS than manages the lifetime of objects for you automatically. You will never have an issue with the borrow checker when using Bevy, not even once.
Everything in every ECS system is done with handles, but the parent comment is correct that many games use hairballs of pointers all over the place (and they are handles with ECS). There is never a borrow checker issue with handles since they divorce the concept of a pointer from the concept of ownership.
But then the question becomes - why Rust, if you deliberately work around its single most prominent distinguishing feature?
The main feature of rust isn't borrow checking, the feature is safe low level programming. Borrow checking is Rust's default way of doing this, but it's not the only one (the standard library has Reference Counting primitives built in).

Borrow checking is a way to make manual memory management safe, ECS works around manual memory management entirely, so it doesn't need borrow checking to be safe (which is also why it's popular in C++, which doesn't have a borrow checker) but because it's Rust, you have strong guarantees about the safety of it, while in C++ you can still shoot yourself in the foot if you don't use ECS the right way.

Also Rust is more than safety: https://steveklabnik.com/writing/rust-is-more-than-safety

I would argue that borrow checking is the only feature that is actually unique (more or less) to Rust. If you don't need it, you can get the rest from elsewhere, often with better ergonomics.
If you don't care about performance, then sure.

If you want to squeeze the maximum performance of your hardware (which is indeed the case for game engines) then all your options are Rust, C and C++. In which case is by far the more ergonomic choice on every aspects.

Or Zig. Or (if you want a stable, proven solution) Ada.
Neither is more ergonomic than Rust though.

You could add a lot of research/experimental and/or legacy languages as well (Modula 3, Odin, D, why not FORTRAN, even) but none of them are credible alternatives to C or C++ like Rust has managed to become. And none of them are polished enough (be it in terms of errors messages, libraries, docs, onboarding material, build toolchain) to be considered superior to Rust in terms of developer ergonomics even if you set aside safety.

And again, borrow checking isn't a feature, it's an implementation of the feature which is memory safety without performance tradeoff. Even when using a paradigm that doesn't interact with the borrow checker, you're still using the feature itself (especially because all of the underlying building blocks which aren't using ECS directly are benefiting from the borrow checker's validation).

> I really don’t think Rust is a good match for game dev. Both because of the borrow checker which requires a lot of handles instead of pointers and because compile times are just not great.

I completely disagree, having been doing game dev in Rust for well over a year at this point. I've been extremely productive in Bevy, because of the ECS. And Unity compile times are pretty much just as bad (it's true, if you actually measure how long that dreaded "Reloading Domain" screen takes).

"ECS" == Entity-Component-System, "a software architectural pattern commonly used in game development and other simulations for organizing game objects and their data," according to Google Gemini.
> The problem with Rust is that almost everything is still at an alpha stage.

Replace Rust with Bevy and language with framework, you might have a point. Bevy is still in alpha, it's lacking plenty of things, mainly UI and an easy way to have mods.

As for almost everything is at an alpha stage, yeah. Welcome to OSS + SemVer. Moving to 1.x makes a critical statement. It's ready for wider use, and now we take backwards compatibility seriously.

But hurray! Commercial interest won again, and now you have to change engines again, once the Unity Overlords decide to go full Shittification on your poorly paying ass.

Unfortunately, it is a failing of many projects in the Rust sphere that they spend quite a lot longer in 0.x than other projects. Rust language and library features themselves often spend years in nightly before making it to a release build.

You can also always go from 1.0 to 2.0 if you want to make breaking changes.

> Unfortunately, it is a failing of many projects in the Rust sphere that they spend quite a lot longer in 0.x than other projects

Yes. Because it makes a promise about backwards compatibility.

> Rust language and library features themselves often spend years in nightly before making it to a release build.

So did Java's. And I Rust probably has a fraction of its budget.

In defense of long nightly feature more than once, stabilizing some feature like negative impl and never types early would have caused huge backwards breaking changes.

> You can also always go from 1.0 to 2.0 if you want to make breaking changes.

Yeah, just like Python!

And split the community and double your maintenance burden. Or just pretend 2.0 is 1.1 and have the downstream enjoy the pain of migration.

> And split the community and double your maintenance burden.

If you choose to support 1.0 sure. But you don't have to. Overall I find that the Rust community is way too leery of going to 1.0. It doesn't have to be as big a burden as they make it out to be, that is something that comes down to how you handle it.

> If you choose to support 1.0 sure.

If you choose not to, then people wait for x.0 where x approaches infinity. I.e. they lose confidence in your crates/modules/libraries.

I mean, a big part of why I don't 1.x my OSS projects (not just Rust) is that I don't consider them finished yet.

Godot launched 0.1 in February 2014 and got to 1.0 in December 2014.

The distance in time between the launches of Unreal Engine 4 and Unreal Engine 5 was 8 years (April 2014 to April 2022). Unreal Engine 5 development started in May 2020 and had an early access release in May 2021.

Bevy launched 0.1 in 2020 and is at 0.16 now in 2025. 5 years later and no 1.0 in sight.

If you want people to use your OSS projects (maybe you don't), you have to accept that perfect is the enemy of good.

At this point, regulators and legislators are trying to force people to use the Rust ecosystem - if you want a non-GC language that is "memory safe," it's pretty much the de facto choice. It is long past time for the ecosystem to grow up.

> Godot launched 0.1 in February 2014 and got to 1.0 in December 2014.

Yeah because that's when it was open sourced, NOT DEVELOPED.

See https://godotengine.org/article/first-public-release/

> Godot has been an in-house engine for a long time and the priority of new features were always linked to what was needed for each game and the priorities of our clients.

I checked the history and it was known by another name Larvita.

> If you want people to use your OSS project

Seeing how currently I have about 0.1 parts of me working on it, no I don't want to give people false sense of security.

> At this point, regulators and legislators are trying to force people to use the Rust ecosystem

Not ecosystem. Language. Ecosystem is a plus.

Further more the issue Bevy has is more of there aren't any good mature GUI libraries for Rust. Because cross OS GUIs were, are and will be a shit show.

Granted it's a shit show that can be directed with enough money.

I have totally disagree here.

I don't even look at crate versions but the stuff works, very well. The resulting code is stable, robust and the crates save an inordinate amount of development time. It's like lego for high end, high performance code.

With Rust and the crates you can build actual, useful stuff very quickly. Hit a bug in a crate or have missing functionality? contribute.

Software is something that is almost always a work in progress and almost never perfect, and done. It's something you live with. Try any of this in C or C++.

They might be unsafe, but there is enough tooling to pick from 60 and 50 years of industrial use, approximately.
Well, on the flip side with C++ some of it hasn't been updated beyond very basic maintenance and you can't even understand the code if you are just familiar with more modern C++…
Well it is upon each one to be good with their craft.

If not, the language they pick doesn't really make a difference in the end.

It is like complaining playing a music instrument to be in band or orchestra requires too much effort, naturally.

Except here you are a trained pianist and the tour manager gave you a pipe organ or a harpsichord.
Speaking as someone with musical background, that is where we discover those that actually understand music, from those that kind of get by.

Great musicians make a symphony out of what they can get their hands on.

>”reverting to more conservative options”

From what I’ve heard about the Rust community, you may have made an unintentionally witty pun.

It's still true for game dev indeed, but for back-end or CLI tools it hasn't been true in like 7 years or so.
I wouldn't say 'almost everything', but there are some areas which require a huge amount of time and effort to build a mature solution for, UI and game engines being one, where there are still big gaps.
They mentioned ABI and the ability to create mods, which are Rust things.

Here's a thought experiment: Would Minecraft have been as popular if it had been written in Rust instead of Java?

I mean, we already have a sort-of answer, because the "Bedrock Edition" of Minecraft is written in C++, and it is indeed less popular on PC (on console, it's the only option, so _overall_ it might win out) and does lack any real modding scene
Indeed. Java is sufficiently dynamic/decompilable a game written in it can be heavily modded without adding specific support. C++ is much harder (depending on the game engine), though not impossible. If you do add modding support then everything is much better regardless of language, though (see Factorio, written in C++ and with a huge modding scene, because it was basically written with modding in mind. Lua is certainly helping with that, of course).
I actually disagree with that. Decompilation based mods can completely change anything and everything about the game. Scripting based mods can only change things within the boundaries allowed by the devs of the original game.
True, a limited modding API can be a problem. But in something like minecraft it's not a a free-for-all with mods either, it's just that the community writes their own modding API, but has to deal with breakage whenever the game updates.
(comment deleted)
What are some non-alpha quality Rust game engines? If the answer is "there are none", then I'd say the title is accurate.
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.

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 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.

Somehow I doubt Unity uses global void pointers in C. Not that one would have to use global void pointers when using C.
> 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.

> 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...

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.

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.
...why does Tiny Glade not count?
> 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?
> 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.

Yeah in my haste I mixed up my rants. The bane of typing at work inbetween things.

Tiny Glade is indeed a rust game. So there is one! I am not aware of a second. But it’s not really a Bevy game. It uses the ECS crate from Bevy.

Egg on my face. Regrets.

It’s incredible how many projects and articles have been written around ECS with very little results.

Quake 1-3 uses a single array of structs, with sometimes unused properties. Is your game more complex than quake 3?

The “ECS” upgrade to that is having an array for each component type but just letting there be gaps:

    transform[eid].position += …
    physics[eid].velocity = …
Quake 1-3 were written for computers where memory was not much slower than the CPU as is the situation today.

But yeah, probably you don't need an ECS for 90% of the games.

Memory is sometimes faster today!
In absolute terms yes, but relative to the CPU speed memory is ridiculously slow.

Quake struggled with the number of objects even in its days. What you've got in the game was already close to the maximum it could handle. Explosions spawning giblets could make it slow down to a crawl, and hit limits of the client<>server protocol.

The hardware got faster, but users' expectations have increased too. Quake 1 updated the world state at 10 ticks per second.

> Quake struggled with the number of objects even in its days.

Because of memory bandwidth of Iterating the entities? No way. Every other part - rendering, culling, network updates, etc is far worse.

Let’s restate. In 1998 this got you 1024 entities at 60 FPS. The entire array could no fit in L2 cache of a modern desktop.

And I already advised a simple change to improve memory layout.

> Quake 1 updated the world state at 10 ticks per secondo

That’s not a constraint in Quake 3 - which has the same architecture. So it’s not relevant.

> users' expectations have increased too

Your game is more complex than quake 3? In what regard?

> relative to the CPU speed memory is ridiculously slow

Latency from cpu to memory sure.

Memory frequency has caught up though, so you have have more bandwidth than any CPU can deal with.

The important part of ECS (IMO) is more that it's a pattern that others recognize and less that it's necessarily the best pattern to use.
(comment deleted)
Hype as usual, too many people waste time on how to implement engines, instead of how to make a game fun to play.
Very useful writeup, thank you for taking the time to do it.

PS: I love the art style of the game.

I love Rust, but this lines up with my experience roughly. Especially the rapid iteration. Tried things out with Bevy, but I went back to Godot.

There are so many QoL things which would make Rust better for gamedev without revamping the language. Just a mode to automatically coerce between numeric types would make Rust so much more ergonomic for gamedev. But that's a really hard sell (and might be harder to implement than I imagine.)

What numeric types typically need conversions?
The fact you need a usize specifically to index an array (and most collections) is pretty annoying.
This could be different in game dev, but in the last years of writing rust (outside of learning the language) I very rarely need to index any collection.

There is a very certain way rust is supposed to be used, which is a negative on it's own, but it will lead to a fulfilling and productive programming experience. (My opinion) If you need to regularly index something, then you're using the language wrong.

This is getting downvoted but it's kind of true. Indexing collections all the time usually means you're not using iterators enough. (Although iterators become very annoying for fallible code that you want to return a Result, so sometimes it's cleaner not to use them.)

However this problem does still come up in iterator contexts. For example Iterator::take takes a usize.

While you maybe "shouldn't" be indexing collections often (which I also don't agree with, there is a reason that we have more collections then linked lists, lookup is important) even just getting the size of a collection which is often very related to business logic can be quite annoying.
For data that needs to be looked up mostly I want a hashtable. Not always, but mostly. It's rare that I want to look up something but its position in a list.
An iterator works if you're sequentially visiting every item in the collection, in the order they're stored. It's terrible if you need random access, though.

Concrete example: pulling a single item out of a zip file, which supports random access, is O(1). Pulling a single item out of a *.tar.gz file, which can only be accessed by iterating it, is O(N).

History lesson for the cheap seats in the back:

Compressed tars are terrible for random access because the compression occurs after the concatenation and so knows nothing about inner file metadata, but it's good for streaming and backups. Uncompressed tars are much better for random access. (Tar was a used as a backup mechanism to tape (tape archive).)

Zips are terrible for streaming because their metadata is stored at the end, but are better for 1-pass creation and on-disk random access. (Remember that zip files and programs were created in an era of multiple floppy disk-based backups.)

When fast tar enumeration is desired, at the cost of compatibility and compression potential, it might be worth compressing files and then taring them when and if zipping alone isn't achieving enough compression and/or decompression performance. FUSE compressed tar mounting gets to be really expensive with terabyte archives.

> compressing files and then taring them

Just use squashfs if that is the functionality that you need.

In C++, random access iterators are a thing. Indeed, raw pointers satisfy the requirements of a random access iterator concept. Is that not the case in Rust?
I'm no game dev but I have had friends who do it professionally.

Long story short, yes, it's very different in game dev. It's very common to pre-allocate space for all your working data as large statically sized arrays because dynamic allocation is bad for performance. Oftentimes the data gets organized in parallel arrays (https://en.wikipedia.org/wiki/Parallel_array) instead of in collections of structs. This can save a lot of memory (because the data gets packed more densely) be more cache-friendly, and makes it much easier to make efficient use of SIMD instructions.

This is also fairly common in scientific computing (which is more my wheelhouse), and for the same reason: it's good for performance.

> Oftentimes the data gets organized in parallel arrays (https://en.wikipedia.org/wiki/Parallel_array) instead of in collections of structs. This can save a lot of memory (because the data gets packed more densely) be more cache-friendly, and makes it much easier to make efficient use of SIMD instructions.

That seems like something that could very easily be turned into a compiler optimisation and enabled with something like an annotation. Would have some issue when calling across library boundaries ( a lot like the handling of gradual types), but within the codebase that'd be easy.

Meh. I've tried "SIMD magic wand" tools before, and found them to be verschlimmbessern.

At least on the scientific computing side of things, having the way the code says the data is organized match the way the data is actually organized ends up being a lot easier in the long run than organizing it in a way that gives frontend developers warm fuzzies and then doing constant mental gymnastics to keep track of what the program is actually doing under the hood.

I think it's probably like sock knitting. People who do a lot of sock knitting tend to use double-pointed needles. They take some getting used to and look intimidating, though. So people who are just learning to knit socks tend to jump through all sorts of hoops and use clever tricks to allow them to continue using the same kind of knitting needles they're already used to. From there it can go two ways: either they get frustrated, decide sock knitting is not for them, and go back to knitting other things; or they get frustrated, decide magic loop is not for them, and learn how to use double-pointed needles.

Very much agree and love your analogy but there is a third option - make a sock knitting machine.
It's not at all easy to implement as an optimisation, because it changes a lot of semantics, especially around references and pointers. It is something that you can e.g. implement using rust procedural macros, but it's far from transparent to switch between the two representations.

(It's also not always a win: it can work really well if you primarily operate on the 'columns', and on each column more or less once per update loop, but otherwise you can run into memory bandwidth limitations. For example, games with a lot of heavily interacting systems and an entity list that doesn't fit in cache will probably be better off with trying to load and update each entity exactly once per loop. Factorio is a good example of a game which is limited by this, though it is a bit of an outlier in terms of simulation size.)

The underlying issue with game engine coding is that the problem is shaped in this way:

* Everything should be random access(because you want to have novel rulesets and interactions)

* It should also be fast to iterate over per-frame(since it's real-time)

* It should have some degree of late-binding so that you can reuse behaviors and assets and plug them together in various ways

* There are no ideal data structures to fulfill all of this across all types of scene, so you start hacking away at something good enough with what you have

* Pretty soon you have some notion of queries and optional caching and memory layouts to make specific iterations easier. Also it all changes when the hardware does.

* Congratulations, you are now the maintainer of a bespoken database engine

You can succeed at automating parts of it, but note that parent said "oftentimes", not "always". It's a treadmill of whack-a-mole engineering, just like every other optimizing compiler; the problem never fully generalizes into a right answer for all scenarios. And realistically, gamedevs probably haven't come close to maxing out what is possible in a systems-level sense of things since the 90's. Instead we have a few key algorithms that go really fast and then a muddle of glue for the rest of it.

I'm not a game dev, but what's a straightforward way of adjusting some channel of a pixel at coordinate X,Y without indexing the underlying raster array? Iterators are fine when you want to perform some operation on every item in a collection but that is far from the only thing you ever might want to do with a collection.
(comment deleted)
Game dev here. If you’re concerned about performance the only answer to this is a pixel shader, as anything else involves either cpu based rendering or a texture copy back and forth.
A compute shader could update some subset of pixels in a texture. It's on the programmer to prevent race conditions though. However that would again involve explicit indexing.

In general I think GP is correct. There is some subset of problems that absolutely requires indexing to express efficiently.

You can manipulate texture coordinate derivatives in order to just sample a subset of the whole texture on a pixel shader and only shade those pixels (basically the same as mipmapping, but you can have the "window" wherever you want really).

This is something you can't do on a compute shader, given you don't have access to the built-in derivative methods (building your own won't be cheaper either).

Still, if you want those changes to persist, a compute shader would be the way to go. You _can_ do it using a pixel shader but it really is less clean and more hacky.

That is true. Hadn't occurred to me because I'd had in mind pixel sorting stuff I did in the past where the fetches and stores aren't contiguous.

Interestingly enough the derivative functions are available to compute shaders as of SM 6.6. [0] Oddly SPIR-V only makes the associated opcodes [1] available to the fragment execution model for some reason. I'm not sure how something like DXVK handles that.

I'm not clear if the associated DXIL or SPIR-V opcodes are actually implemented in hardware. I couldn't immediately find anything relevant in the particular ISA I checked and I'm nowhere near motivated enough to go digging through the Mesa source code to see how the magic happens. Relevant because since you mentioned it I'm curious how much of a perf hit rolling your own is.

[0] https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_6_De...

[1] https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.htm...

Huh wasn't aware of that. Nice.

About the performance question, during the frag shader phase neighbouring pixels are already being tracked, so calling those is almost free. It would be difficult to match that performance when already on the compute phase.

That's just a matter of what's in cache. If your compute shader operates in coherent blocks it should generally be on par with the equivalent fragment shader. The potential exceptions are where access to dedicated hardware functionality is concerned.

What I'm curious about is if there's a hardware intrinsic that computes derivatives or if the implementation of those opcodes is generally in software.

I chose to focus on the fact the frag stage is already tracking those changes because at that point it's basically free. And you don't need to worry too much.

To answer your question, which is very pertinent, they seem to use different hardware accelerated mechanisms. In the compute stage, wave based derivatives are used, and you need to account for different lane counts between GPU architectures.

Understanding that now makes me believe you're right. But one needs to benchmark them to be sure.

You're right - I should have just said "shader" and left it at that.

> There is some subset of problems that absolutely requires indexing to express efficiently.

Sure. But it's almost certainly quicker to run a shader over them, and ignore the values you don't want to operate on than it is to copy the data back, modify it in a safe bounds checked array in rust, and then copy it again.

> run a shader over them, and ignore the values you don't want to operate on

Use a compute shader. Run only as many invocations as you care about. Use explicit indexing in the shader to fetch and store.

Obviously that doesn't make sense if you're targeting 90% of the slots in the array. But if you're only targeting 10% or if the offsets aren't a monotonic sequence it will probably be more efficient - and it involves explicit indexing.

On the contrary, I find indices to be the most natural way to represent anything that resembles a graph in Rust. They allow you to sidestep the usual issues that arise with ownership and borrowing, particularly with mutability, by handing ownership to the collection and using indices to allow nodes to refer to one another. It's delightfully simple compared to the mess of Arc and RefCell that tends to result when one tries to apply patterns from languages that leave "shared XOR mutable" as the programmer's responsibility. That's not to say that Vec and usize are appropriate for the task, but Rust's type system can be used to do a lot better.
The actual problem with this is how to add it without breaking type inference for literal numbers.
Thats a feature not an annoyance. We need to keep Rust like it is to preserve its core value delivey: Robust software quality in exchange for development & compile time/pain, in other words: "the pain is moved from production to development" you can not have joy in both at the same time.

Not sure if Rust should be promoted to build games, i prefer it being pushed to build mission critical software.

What I mean is, I want to be able to use i32/i64/u32/u64/f32/f64s interchangeably, including (and especially!) in libraries I don't own.

I'm usually working with positive values, and almost always with values within the range of integers f32 can safely represent (+- 16777216.0).

I want to be able to write `draw(x, y)` instead of `draw(x as u32, y as u32)`. I want to write "3" instead of "3.0". I want to stop writing "as".

It sounds silly, but it's enough to kill that gamedev flow loop. I'd love if the Rust compiler could (optionally) do that work for me.

Please correct me if I'm wrong, but I don't think this would let me, say, pass an i32 returned from one method directly as an f64 argument in another method.
No, it would not. Even conversions using "as" are discouraged in favor of conversion traits such as From and TryFrom. Rust's goals of being explicit and correct are at odds with people wanting things to be immediately simple and easy to use.
I used to hate the language but statically typed GDscript feels like the perfect weight for indie development
Yeah I haven't really used it much but from what I've seen it's kind of what Python should have been. Looks way better than Lua too.
I like it better than python now, but it's still got some quirks. The lack of structs and typed callables are the biggest holes right now imo but you can work around those
It is indeed great for creating a prototype. After that, one can gradually migrate to Rust go benefit from faster execution times. The Rust bindings are in a pretty decent shape by now

https://godot-rust.github.io/

Nowadays we have the luxury of LLMs to help migrate projects/code from one language to another. I would imagine a pipeline with Rust as an intermediate “compiled” step might be possible. LLM accuracy isn’t there yet, but I can dream.
It is not that complicated or time-consuming to do the transformation manually. On the contrary, it's even fun and a good practice (but admittedly, I do have a rather conservative view on the matter)
String conversions too
I wish more languages would lean into having a really permissive compiler that emits a lot of warnings. I have CI so I'm never going to actually merge anything that makes warnings. But when testing, just let me do whatever I want!

GHC has an -fdefer-type-errors option that lets you compile and run this code:

    a :: Int
    a = 'a'
    main = print "b"

Which obviously doesn't typecheck since 'a' is not an Int, but will run just fine since the value of `a` is not observed by this program. (If it were observed, -fdefer-type-errors guarantees that you get a runtime panic when it happens.) This basically gives you the no-types Python experience when iterating, then you clean it all up when you're done.

This would be even better in cases where it can be automatically fixed. Just like how `cargo clippy --fix` will automatically fix lint errors whenever it can, there's no reason it couldn't also add explicit coercions of numeric types for you.

Yeah this is my absolute dream language. Something that lets you prototype as easily as Python but then compile as efficiently and safely as Rust. I thought Rust might actually fit the bill here and it is quite good but it's still far from easy to prototype in - lots of sharp edges with say modifying arrays while iterating, complex types, concurrency. Maybe Rust can be something like this with enough unsafe but I haven't tried. I've also been meaning to try more Typescript for this kind of thing.
Some Common Lisp implementations like SBCL have supported this style of development for many years. Everything is dynamically typed by default but as you specify more and more types the compiler uses them to make the generated code more efficient.
I quite like common lisp but I don't believe any existing implementation gets you anywhere near the same level of compile time safety. Maybe something like typed racket but that's still only doing a fraction of what rust does.
I think OCaml could be such a language personally. Its like rust-lite or a functional go.
You should give Julia a shot. That’s basically that. You can start with super dynamic code in a REPL and gradually hammer it into stricter and hyper efficient code. It doesn’t have a borrow checker, but it’s expressive enough that you can write something similar as a package (see BorrowChecker.jl).
Unless you would like to AOT-deploy your code, then good luck with using this 3rd party package with scarce documentation.

Or even enums, which are a joke in Julia.

Julia had so much potential, and such poor implementation.

> I wish more languages would lean into having a really permissive compiler that emits a lot of warnings. I have CI so I'm never going to actually merge anything that makes warnings. But when testing, just let me do whatever I want!

I’d go even further and say I wish my whole development stack had a switch I can use to say “I’m not done iterating on this idea yet, cool it with the warnings.”

Unused imports, I’m looking at you… stop bitching that I’m not using this import line simply because I commented out the line that uses it in order to test something.

Stop complaining about dead code just because I haven’t finished wiring it up yet, I just want to unit test it before I go that far.

Stop complaining about unreachable code because I put a quick early return line in this function so that I could mock it to chase down this other bug. I’ll get around to fixing it later, I’m trying to think!

In rust I can go to lib.rs somewhere and #![allow(unused_imports,dead_code,etc)] and then remember to drop it by the time I get the branch ready for review, but that’s more cumbersome than it ought to be. My whole IDE/build/other tooling should have a universal understanding of “this is a work in progress please let me express my thoughts with minimal obstructions” mode.

(comment deleted)
On the other hand, I can't count how many times I've written some code like

    let iteration_1_id = 10;
    dostuff(iteration_1_id);
    let iteration_2_id = 11; // warning, unused variable!!
    dostuff(iteration_1_id);
and then spent 10 minutes debugging why iteration_2 wasn't working, when it would have been resolved instantly if I had paid attention to the warnings.
Yeh, I've been tinkering around a year with a Bevy-competitor, Amethyst until that project shut down. By now, I just don't think Rust is good for client-side or desktop game development.

In my book, Rust is good at moving runtime-risk to compile-time pain and effort. For the space of C-Code running nuclear reactors, robots and missiles, that's a good tradeoff.

For the space of making an enemy move the other direction of the player in 80% of the cases, except for that story choice, and also inverted and spawning impossible enemies a dozen times if you killed that cute enemy over yonder, and.... and the worst case is a crash of a game and a revert to a save at level start.... less so.

And these are very regular requirements in a game, tbh.

And a lot of _very_silly_physics_exploits_ are safely typed float interactions going entirely nuts, btw. Type safety doesn't help there.

(comment deleted)
> Yeh, I've been tinkering around a year with a Bevy-competitor, Amethyst until that project shut down. By now, I just don't think Rust is good for client-side or desktop game development.

I don't think your experience with Amethyst merits your conclusion of the state of gamedev in rust, especially given Amethysts own take on Bevy [1, 2].

1: https://web.archive.org/web/20220719130541mp_/https://commun...

2: https://web.archive.org/web/20240202140023/https://amethyst....

> Just a mode to automatically coerce between numeric types would make Rust so much more ergonomic for gamedev.

C# is stricter about float vs. double for literals than Rust is, and the default in C# (double) is the opposite of the one you want for gamedev. That hasn't stopped Unity from gaining enormous market share. I don't think this is remotely near the top issue.

I have written a lot of C# and I would very much not want to use it for gamedev either. I can only speak for my own personal preference.
> I failed to fairly evaluate my options at the start of the project.

The more projects I do, the more time I find that I dedicate to just planning things up front. Sometimes it's fun to just open a game engine and start playing with it (I too have an unfair bias in this area, but towards Godot [https://godotengine.org/]), but if I ever want to build something to release, I start with a spreadsheet.

Do you think you needed to have those times to play around in the engine? Can a beginner possibly even know what to plan for if they don't fully understand the game engine itself? I am older so I know the benefits of planning, but I sometimes find that I need to persuade myself to plan a little less, just to get myself more in tune with the idioms and behaviors of the tool I am working in.
I think even if you don't have much experience with tools, you can still plan effectively, especially now with LLMs that can give you an idea of what you're in for.

But if you're doing something for fun, then you definitely don't need much planning, if any - the project will probably be abandoned halfway through anyways :)

Related: https://news.ycombinator.com/item?id=40172033 - Leaving Rust gamedev after 3 years (982 comments) - 4/26/2024
https://loglog.games/blog/leaving-rust-gamedev/#hot-reloadin...

Hot reloading! Iteration!

A friend of mine wrote an article 25+ years ago about using C++ based scripting (compiles to C++). My friend is super smart engineer, but I don't think he was thinking of those poor scripters that would have to wait on iteration times. Granted 25 years ago the teams were small, but nowadays the amount of scripters you would have on AAA game is probably dozen if not two or three dozen and even more!

Imagine all of them waiting on compile... Or trying to deal with correctness, etc.

Anyone else get an empty page on mobile Firefox when they try to go the article? All that renders for me is a comment entry box. If I go back to news I can see the article list just fine.
Same on mobile safari
(comment deleted)
GC isn't a big problem for many types of apps/games, and most games don't care about memory safety. Rust's advantages aren't so important in this domain, while its complexity remains. No surprise he prefers C# for this.
Except that C# is memory safe.
Not just GC -- performance in general is a total non-issue for a 2d tile-based game. You just don't need the low-level control that Rust or C++ gives you.
I wouldn't say it's a non-issue. I've played 2D tile-based, pixel art games where the framerate dropped noticeably with too many sprites on screen, even though it felt like a 3DS should have been able to run it, and my computer isn't super low-end, either. You have more leeway, but it's possible to badly make optimized 2D games to the point where performance becomes an issue again.
These are gross, macro-level design problems; not the kind of thing where C# vs C++/Rust makes any difference.
Disagree on both points. Anyone who has shipped a game in unity has dealt with object pooling, flipping to structs instead of classes, string interpolation, and replacing idiomatic APIs with out parameters of reused collections.

Similarly, anyone who has shipped a game in unreal will know that memory issues are absolutely rampant during development.

But, the cure rust presents to solve these for games is worse than the disease it seems. I don’t have a magic bullet either..

This is a mostly Unity-specific issue. Unity unfortunately has a potato for a GC. This is not even an exaggeration - it uses Boehm GC. Unity does not support Mono's better GC (SGen). .NET has an even better GC (and JIT) that Unity can't take advantage of because they are built on Mono still.

Other game engines exist which use C# with .NET or at least Mono's better GC. When using these engines a few allocations won't turn your game into a stuttery mess.

Just wanted to make it clear that C# is not the issue - just the engine most people use, including the topic of this thread, is the main issue.

I'm shocked that Beat Saber is written in C# & Unity. That's probably the most timing sensitive game in the world, and they've somehow pulled it off.
There's another highly sensitive to timing game - Osu!, which is written in C# too (on top of custom engine).
GC isn't something to be afraid of, it's a tool like any other tool. It can be used well or poorly. The defaults are just that - defaults. If I was going to write a rhythm game in Unity, I would use some of the options to control when GC happens [0], and play around with the idea of running a GC before and after a song but having it disabled during the actual interactive part (as an example).

[0] https://docs.unity3d.com/6000.0/Documentation/Manual/perform...

Using poor quality AI suggestions as a reason not to use Rust is a super weird argument. Something is very wrong with such idea. What's going to be next, avoiding everything where AI performs poorly?

Scripting being flexible is a proper idea, but that's not an argument against Rust either. Rather it's an argument for more separation between scripting machinery and the core engine.

For example Godot allows using Rust for game logic if you don't want to use GDScript, and it's not really messing up the design of their core engine. It's just more work to allow such flexibility of course.

The rest of the arguments are more in the familiarity / learning curve group, so nothing new in that sense (Rust is not the easiest language).

Yes, a lot of people are reasonably going to decide to work in environments that are more legible to LLMs. Why would that surprise you?

The rest of your comment boils down to "skills issue". I mean, OK. But you can say that about any programming environment, including writing in raw assembly.

First argument sounds like a major fallacy to me. It doesn't surprise me, but it find it extremely wrong.
Why?
Because it's a discouragement of learning based on mediocrity of AI. I find such idea perpetuating the mediocrity (not just of AI itself but of whatever it's used for).

It's like imagine saying, I don't want to learn how write a good story because AI always suggests me writing a bad one anyway. May be that delivers the idea better.

It's not at all clear to me what this has to do with the practical delivery of software. In languages that LLMs handle well, with a careful user (ie, not a vibe coder; someone reading every line of output and subjecting most of it to multiple cycles of prompting) the code you end up with is basically indistinguishable from the replacement-level code of an expert in the language. It won't hit that human expert's peaks, but it won't generally sink below their median. That's a huge accelerator for actually delivering projects, because, for most projects, most of the code need only be replacement-grade.

Why would I valorize discarding this kind of automation? Is this just a craft vs. production thing? Like, the same reason I'd use only hand tools when doing joinery in Japanese-style woodworking? There's a place for that! But most woodworkers... use table saws and routers.

It's not about delivery of software, it's about avoidance of learning based on mediocrity of AI. I.e. original post literally brings LLMs being poor at suggestions for Rust as a reason to avoid it.

That implies that proponents of such approach don't want to pursue learning which requires them to do something that exceeds the mediocrity level set by the AI they rely on.

For me it's obvious that it has a major negative impact on many things.

Your premise here being that any software not written in Rust must be mediocre? Wouldn't it be more productive to just figure out how to evolve LLM tooling to work well with Rust? Most people do not write Rust, so this is not a very compelling argument.
Rust is just an example in this case, not essential to the point. If someone will evolve LLM to work with Rust better, it will still be mediocre at something else, and using this as an excuse to avoid it is problematic in itself, that's what I'm saying.

Basically, learn Rust based on whether it's helping solve your issues better, not on whether some LLM is useless or not useless in this case.

> Why would I valorize discarding this kind of automation? Is this just a craft vs. production thing?

The strongest reason I can think of to discard this kind of automation, and do so proudly, is that it's effectively plagiarizing from all of the experts whose code was used in the training data set without their permission.

No plausible advance in nanotechnology could produce a violin small enough to capture how badly I feel about out professional being "plagiarized" after decades of rationalizing about the importance of Star Wars to the culture justifying movie piracy.

Artists can come at me with this concern all they want, and I feel bad for them. No software developer can.

I disagree with you about the "plagiaristic" aspect of LLM code generation. But I also don't think our field has a moral leg to stand on here, even if I didn't disagree with you.

I'm not making an argument from grievance about my own code being plagiarized. I actually don't care if my own code is used without even the attribution required by the permissive licenses it's released under; I just want it to be used. I do also write proprietary code, but that's not in the training datasets, as far as I know. But the training datasets do include code under a variety of open-source licenses, both permissive and copyleft, and some of those developers do care how their code is used. We should respect that.

As for our tendency to disrespect the copyrights of art, clearly we've always been in the wrong about this, and we should respect the rights of artists. The fact that we've been in the wrong about this doesn't mean we should redouble the offense by also plagiarizing from other programmers.

And there is evidence that LLMs do plagiarize when generating code. I'll just list the most relevant citations from Baldur Bjarnason's book _The Intelligence Illusion_ (https://illusion.baldurbjarnason.com/), without quoting from that copyrighted work.

https://arxiv.org/abs/2202.07646

https://dl.acm.org/doi/10.1145/3447548.3467198

https://papers.nips.cc/paper/2020/hash/1e14bfe2714193e7af5ab...

I don't mean to attribute the overwhelmingly common sentiment about intellectual property claims for things other than code to you, and I'm sorry that I communicated that (you didn't call me on it, but you'd have had every right to).

I stand by that argument, but acknowledge it isn't relevant here.

My bigger thing is just, having the experience of writing many thousands of lines of backend code with an LLM (just yesterday), none of what I'm looking at can meaningfully be described as "plagiarized". It's specific to my problem domain (indeed, to my extremely custom stack) and what isn't domain-specific is just extremely generic stuff (opening a boltdb, printing a table with lipgloss), just assembled precisely.

it could be a weird argument, but as a rust newcomer, i have to say it's really something that jumps to your face. LLMs are practically useless for anything non-basic, and rust contains a lot non-basic things.
So, what are the chances that the pendulum swings to lower-level programming via LLM-generated C/C++ if LLM-generated Rust doesn't emerge? Note that this question is a context switch from gaming to something larger. For gaming, it could easily be that the engine and culture around it (frequent regressions, etc) are the bigger problems than the language.
I haven't coded in C/C++ in years but friends who do and worked on non-trivial codebase in those languages had a really crappy experience with LLMs too.

A friend of mine only understood why i was so impressed by LLMs once he had to start coding a website for his new project.

My feeling is that low-level / system programming is currently at the edge of what LLMs can do. So i'd say that languages that manage to provide nice abstractions around those types of problems will thrive. The others will have a hard time gaining support among young developers.

Developers often pick languages and libraries based on the strength of their developer tools. Having great dev tools was a major reason Ruby on Rails took off, for example.

Why exclude AI dev tools from this decision making? If you don’t find such tools useful, then great, don’t use them. But not everybody feels the same way.

It's a weird idea now, but it won't be weird soon. As devs and organizations further buy into AI-first coding, anything not well-served by AI will be treated as second-class. Another thread here brought up the risk that AI will limit innovation by not being well-trained on new things.
I agree that such trend exists, but it's extremely unhealthy and if anyone, developers should have more clue how bad it is.
(comment deleted)
That's an excellent article - it's great when people share not only their victories, but mistakes, and what they learned from them.

That said regarding both rapid gameplay mechanic iteration and modding - would that not generally be solved via a scripting language on top of the core engine? Or is Rust + Bevy not supposed to be engine-level development, and actually supposed to solve the gameplay development use-case too? This is very much not my area of expertise, I'm just genuinely curious.

It does solve the gameplay development use case too. Bevy encourages using lots of small 'systems' to build out logic. These are functions that can spawn entities or query for entities in the game world and modify them and there's also a way to schedule when these systems should run.

I don't think Bevy has a built-in way to integrate with other languages like Godot does, it's probably too early in the project's life for that to be on the roadmap.

The "Learning" point drives home a concern my brother-in-law and I were talking about recently. As LLMs become more entrenched as a tool, they may inevitably become the crutch that actually holds back innovation. Individuals and teams may be hesitant to explore or adopt bleeding edge technologies specifically because LLMs don't know about them or don't know enough about them yet.
I was actually meaning to post this as an Ask HN question, but never found the time to word it well. Basically, what happens to new frameworks and technologies in the age of widespread LLM-assisted coding? Will users be reluctants to adopt bleeding-edge tools because the LLMs can't assist as well? Will companies behind the big frameworks put more resources towards documenting them in a way that makes it easy for LLMs to learn from?
Another way to look at it: working bleeding edge will become a competitive advantage and a signal to how competent the team is. „Do they consume it” vs „do they own it”.
Or a signal that, someone did not think about the bus factor and future of the project when most of the teams jumped ship.
Constantly chasing the latest tech trends has probably done more harm than good, because more often than not, it turns out that the latest hype technology actually does not deliver what the marketing had promised. Look at NoSQL and MongoDB especially as recent examples. Most people who blindly jumped on the MDB bandwagon would have probably been better off just using Postgres, and they later had to spend a lot of resources migrating away from Mongo.

To me constantly chasing the latest trends means lack of experience in a team and absence of focus on what is actually important, which is delivering the product.

There’s another future where reasoning models get better with larger context windows, and you can throw a new programming language or framework at it and it will do a pretty good job.
Actually, here in my corner of EU, only the prominent big tech backed well documented and battle tested tools are most marketable skills. So, React, 50 new jobs, but you worked with Svelte/Solidjs, what is that? Java/PHP/Python/Ruby/JS, adequate jobs. Go/Rust/Zig/Crystal/Nim, what are these? While Go has some popularity in recent years and I can spot Rust once in a blue moon. Anything involving requiring near metal work is always C/C++.

Availability of documentation and tooling, widespread adaptation and access to already-trained-at-someone-else's-dime possibility is deemed safe for hiring decision. Sometimes, the narrow tech is spotted in the wild, but it was mostly some senior/staff engineer wanted to experiment something which became part of production because management saw no issue, will sometimes open some doors for practitioners of those stack but the probability is akin to getting hit by lightning strike.

This is just reality outside of the early stage startup. The US tech industry and its social networks are very dominated by trendy startup ideas, but the reality is still the major tried-and-true platforms.
Maybe it is not the regulations what is holding EU back.
This already happens. Is your new framework popular on GitHub and on Stack Overflow is a metric people use. LLMs are currently mostly capable of just adapting documentation, blog posts, and answers on SO. So they add a thin veneer on top of those resources.
Hopefully, tools can adapt to integrate documentation better. I've already run into this with GitHub Copilot, trying to use Svelte 5 with it is a battle despite it being released most of a year ago.
I expect it will wind up like search engines where you either submit urls for indexing/inclusion or wait for a crawl to pick your information up.

Until the tech catches up it will have a stifling effect on progress toward and adoption of new things (which imo is pretty common of new/immature tech, eg how culture has more generally kind of stagnated since the early 2000s)

This is already happening.

On one hand, yes, when it comes to picking tools for new projects, LLM awareness of them is now a consideration in large companies.

And at the same time, those same companies are willing to spend time and effort to ensure that their own tooling is well-represented in the training sets for SOTA models. To the point where they work directly with the corresponding teams at OpenAI etc.

And yes, it does mean that the barrier to entry for new competitors is that much higher, especially when they don't have the resources to do the same.

How is that different from choosing not to adopt a technology because it’s not widely used therefore not widely documented? It’s the timeless mantra of “use boring tech” that seems to resurface every once in a while. It’s all about the goal: do you want to build a viable product, quickly, or do you want to learn and contribute to a specific tech stack? That’s the trade off most of the time.
It's a lot worse. A high quality project can have great documentation and guides that make it easy to use for a human, but an LLM won't until there's a lot of code and documents out there using it.

And if it's not already popular, that won't happen.

No, this doesn't ring true: long before there were LLMs, people were selecting languages and stacks because of the quality and depth of their community.

But also: there is a lot of Rust code out there! And a cubic fuckload of high-quality written material about the language, its idioms, and its libraries, many of which are pretty famous. I don't think this issue is as simple as it's being out to be.

Isn't this article an example of that. There might be a lot of rust code but if the apis are changing frequently it's all outdated and leads to unusable outputs.
It's not Rust in particular, but Bevy the game engine which is much newer than Rust and still has many breaking changes between version.

It's a bit like Rust in 2014, you would never have had enough material for LLMs to train on.

New languages / packages / frameworks may need to collaborate with LLM providers to provide good training material. LLM-able training material may be the next important documentation thing.

Another potentially interesting avenue of research would be to explore allowing LLMs to use "self-play" to explore new things.

How can it compete with vast amount of trained codebases on Github? For LLMs, more data equals better results, so people will naturally be driven to better completion with already established frameworks and languages. It would be hard to produce organic data on all ways your technology can be (ab)used.
Allegedly one of the ways they've been training LLMs to get better at logic and reasoning, as well as factual accuracy, is to use LLMs themselves to generate synthetic training data. The idea here would be similar: generate synthetic training data. Generating this could be aided by LLMs, perhaps with a "playground" of some sort where LLMs could compile / run / render various things, to help select out things that work and things that don't work (as well as if you see error X, what the problem might be).
In a similar way to how this works for natural languages. Turns out that if you train the model on e.g. vast quantities of English, teaching it other languages doesn't require nearly as much, because it has already internalized all the "shared" parts (and there's a lot more of those than there are surface differences).

But, yes, it does mean that new things that are drastic breaks with old practices are much harder to teach compared to incremental improvements.

A showerthought I had recently was that newly-written software may have a perverse incentive to be intentionally buggy such that there will be more public complaints/solutions for said software, which gives LLMs more training data to work with.
I don’t think we will have a lack of people who explore and know beyond others how to things.

LLMs will make people productive. But it will at the same time elevate those with real skill and passion to create good software. In the meantime there will be some maker confusion, and some engineers who are mediocre might find them selfs in demand like top end engineers. But over the time companies and markets will realize and top dollar will go to those select engineers who know how to do things with and without LLMs.

Lots of people are afraid of LLMs and think it is the end of the software engineer. It is and it is not. It’s the end of the “CLI engineer” or the “Front end engineer” and all those specializations that were attempt to require less skill to pay less. But the systems engineers who know how computers work, can take all week long describing what happens when you press enter on a keyboard at google.com will only be pressed into higher demand. This is because the single skill “engineer” wont really be a thing.

tldr; LLMs wont kill software engineering its a reset, it will cull those who chose such a path on a rubric only because it paid well.

We already have quite a lot of that effect with tooling. A language can't really get much traction until its got a build, packaging and all the IDE support we expect or however productive the language is it looses out in practice because its hard to work with and doesn't just fit into our CI/CD systems.
It’s the same now. I’ve spent arguably too much time trying to avoid Python and it has cost me a whole lot of time. You keep running into bugs and have to implement much more yourself if you go off the beaten path (see also [1]). I don’t regret it since I learned a lot, but it’s definitively not always the easiest path. To this day I wonder whether maybe I should have taken the simple route.

[1]: https://huijzer.xyz/posts/killer-domain/

I think it's a good point and I experienced the same thing when playing with SDL3 the other day. So even established languages with new API's can be problematic.

However, I had a different takeaway when playing with Rust+AI. Having a language that has strict compile-time checks gave me more confidence in the code the AI was producing.

I did see Cursor get in an infinite loop where it couldn't solve a borrow checker problem and it eventually asked me for help. I prefer that to burying a bug.

I had the same issue a few months ago when I was trying to ask LLMs about Box2D 3.0. I kept getting answers that were either for Box2D 2.x, or some horrific mashup of 2.x and 3.0.

Now Box2D 3.1 has been released and there's zero chance any of the LLMs are going to emit any useful answers that integrate the newly introduced features and changes.

Almost every time I've run into similar problems with LLMs I've mostly managed to solve them by uploading the documentation to the version of the library I'm using to the LLM and instructing it do use that documentation when answering questions about the library.
I see this quite a bit with Rust. I honestly cringe when people get up in arms about someone taking their project out of the rust community.

The same can be said of books as of programming languages:

"Not every ___ deserves to be read/used"

If the documentation or learning curve is so high and/or convoluted that it's disparaging to newcomers then perhaps it's just not a language that's fit for widespread adoption. That's actually fine.

"Thanks for your work on the language, but this one just isn't for me" "Thanks for writing that awfully long book, but this one just isn't for me"

There's no harm in saying either of those statements. You shouldn't be disparaged for saying that rust just didn't work out for your case. More power to the author.

Rust attracts a religious fervour that you'll almost never see associated with any other language. That's why posts like this make the front page and receive over 200 comments.

If you switched from Java to C# or vice versa, nobody would care.

A religious fervor against it: no one is in the comments telling the OP he’s wrong.
What innovation? Languages with curly braces versus BEGIN/END? There is no innovation going on in computer languages. Rust is C with better ergonomics and rigorous memory management. This was made possible with better processors which made more elaborate compilers practical. It all gets compiled by LLVM down to the same object code. I think we are moving to an era of "read-only" languages. Languages that have horrible writing ergonomics yet are easy to understand when read. Humans won't write code. They will review code.
Its not even innovation. I had a new Laravel project that i was chopping around to play with some new library and I couldn't the the dumbest stuff to work. Of course I went back to read the docs and - ah Laravel 19 or whatever is using config/boostrap.php again and no matter what chatgpt, or myself had figured, could understand why it wasnt working.

unfortunately, a lot of libraries and services - well I don't think chatGPT understands the differences or it would be hard to. At least I have found that with writing scriplets for RT, PHP tooling, etc. The web world seems to move fast enough (and RT moves hella slow) that its confusing libraries and interfaces through the versions.

It'd really need a wider project context where it can go look at how those includes, or functions, or whatever work instead of relying on 'built in' knowledge.

"Assume you know nothing, go look at this tool, api endpoint or, whatever, read the code, and tell me how to use it"

Unity was a better choice for game engine long before the existence of LLMs.
I have that worry as well, but it may not be as bad as I feared. I am currently developing a Python serialization/deserialization library based on advanced multiple dispatch, so it is fairly different from how existing libraries work. Nonetheless, if I ask LLMs (using Cursor) to write new functionality or plugins within my framework, they are surprisingly adept at it, even with limited guidance. I expect it'll only get better in the next few years. Perhaps a set of AI directives and examples for new technologies would suffice.

In any case, there has always been a strong bias towards established technologies that have a lot of available help online. LLMs will remain better at using them, but as long as they are not completely useless on new technologies, they will also help enthusiasts and early adopters work with them and fill in the gaps.

I've noticed this effect even with well established tech but just in degrees of popularity. I've recently been working on a Swift/SwiftUI project and the experience with LLM's compared to something like web dev stuff with React, etc is noticeably different/worse which I mostly attribute to there probably being at least 20 times less Swift specific content on the web in comparison.
There are a ton of Swift /SwiftUI tutorials out there for every new technology.

The problem is, they’re all blogspam rehashes of the same few WWDC talks. So they all have the same blindspots and limitations, usually very surface level.

Is that different from what is happening already? A lot of people won't adopt a language/technology unless it has a huge repository of answers on StackOverflow, mature tooling, and a decent hiring pool.

I'm not saying you're definitely wrong, but if you think that LLMs are going to bring qualitative change rather than just another thing to consider, then I'm interested in why.

Doesn't this mean that new tech will have to demonstrate material advantages, such that outweigh the LLM inertia, in order to be adopted? This sounds good to me; so much framework churn seems to be code fashion rather than function. Now if someone releases a new framework, they need to demonstrate real value first. People that are smart enough to read the docs and absorb the material of a new, better, framework will now have a competitive advantage; this all seems good.
(comment deleted)
For anyone considering Rust for gamedev check out the Fyrox engine

https://fyrox.rs/

here's a web demo

https://fyrox.rs/assets/demo/animation/index.html

Sorry but this engine had(s) problems rendenring a simple rectangle with alpha channel texture, not longer than 3 months ago (I'm assuming it was fixed).

Is it normal for Rust ecosystem to suggest software with this level of maturity?

https://github.com/FyroxEngine/Fyrox/discussions/725

> Is it normal for Rust ecosystem to suggest software with this level of maturity?

Yeah, all Rust programmers are obligated by a blood pact to do this.