Comment by stephc_int13
9 months ago
As a game developer for about two decades, I've never considered Rust to be a good programming language choice.
My priorities are reasonable performances and the fastest iteration time possible.
Gameplay code should be flexible, we have tons and tons of edge cases _by design_ because this is the best way to create interesting games.
Compilation time is very important, but also a flexible enough programming structure, moving things around and changing your mind about the most desirable approach several times a day is common during heavy development phases.
We almost never have specifications, almost nothing is set until the game is done.
It is a different story for game engines, renderers, physics, audio, asset loaders etc. those are much closer to system programming but this is also not where we usually spend the most time, as a professional you're supposed to either use off-the-shelf engines or already made frameworks and libraries.
Also, ECS is, IMHO, a useful pattern for some systems, but it is a pain in the butt to use with gameplay or UI code.
> It is a different story for game engines, renderers, physics, audio, asset loaders etc. those are much closer to system programming but this is also not where we usually spend the most time, as a professional you're supposed to either use off-the-shelf engines or already made frameworks and libraries.
But this is where industry interest (the little there is) lies for Rust, is it not? This is what the AAA studios that are researching and prototyping are working on.
C++ is not a popular language to implement the actual game in for all the reasons you list. It is too slow to compile and too rigid. The people who actually build the games, make them tick, are all working in visual scripting languages.
Visual scripting languages are easy to use and practical for low-complexity code, but they scale very poorly once the complexity increases.
Gameplay code is still better written with code, C# or C++ or sometimes Lua.
> visual scripting languages
I'm surprised no one has made such a language that is designed from the ground up to be used as such for rust. Nim/coffeescript come to mind, but they target non-rust languages. Lua would be close enough if it weren't so alien to everything people like about rust.
Someone did actually create a scripting language specifically designed to work with rust: https://rhai.rs/
As a non-game dev who uses Rust and Elixir, Rust wouldn't be my first pick for a large gamedev studio for multiple reasons. As for alternatives worth evaluating: Crystal, Cython (compiled Python), or Nim could result in increased gamedev productivity over C++ or C#. Maybe even Go because the iteration and compile times are very fast, and the learning curve is very low.
Often in the past Lua has been used and in my experience it's been quite nice. It's very easy to bind, there's some nice editors out there and the performance is decent.
There's some other game-specific scripting languages that have popped up (angelscript and wren come to mind but there's more). I've not used them in full production products though. Mostly just kicked the tires.
Now that I think about it though, it's been almost 6 years since I've worked on an engine with lua support. Mainly because in the last few years I've been working with unity or unreal.
| Go because the iteration and compile times are very fast
Safety is important and for certain applications, Rust is unrivaled.
But for games, like web apps, where time to market and innovation can be just as if not more important than being free of runtime errors, Go is more suited to rapid development than Rust on compile times alone.
Of course, the libraries and support for both aren't quite there yet, so at this point neither is well suited to game dev.
I agree. We almost have a paradox of choice nowadays because it's easier than ever to create new language platforms. Rust is something different because its thesis is safety and performance by default, more or less optimized for systems development primarily, but at the bargain of making dangerous things more complicated to accomplish somewhat intentionally. Unconventional languages are sometimes used as a conspicuous challenge to attract developers or to attempt to move some parts of an industry into new territory.
> Cython (compiled Python), or Nim could result in increased gamedev productivity over C++ or C#
If you're starting from scratch, then maybe. Having had to crash learn games dev (ex VFX systems person) Unity + c# is just so nice to use. most of the easiness of python, but with proper strict typing. (which you can turn off, if you want)
plus the wealth of documentation, its great. I imagine unreal is quite good in that regard too.
>As for alternatives worth evaluating: Crystal, Cython (compiled Python), or Nim could result in increased gamedev productivity over C++ or C#.
I read on a recent HN thread that Crystal compilation is slow due to its type inference, IIRC.
Does Crystal support Hot Reloading? The slow compilation speed is a non-starter for me.
Gamedev industry already settled on almost perfect language for this task (C#) so there is little profit in trying to reinvent the wheel.
And by perfect I mean not the way Unity uses it but the way pure C# engines use it.
They have an interpreter mode now that is quite good and should be well-suited for these situations
Crystal doesn't support parallelism[1], which is a dealbreaker in this context (and for performance sensitive programs in general).
[1]=production grade; additionally, it seems that no work has been done on it for years.
Haha. Nope. Maybe Nim, V*, Go*, or Elixir would be a better choice for such a use-case.
* So fast, they really don't need HCR.
4 replies →
Go is infamous for its gc latency spikes, which is the thing that games cannot tolerate.
Though 1.18 helped a lot, you'd have to do some major persuasion to game devs that Go's gc is the kind of thing they'd want in their game.
---
EDIT: Not sure the downvote, Go is know for its (historically at least) unsuitability for RTC or game dev.
I’ve heard that go has very low latency gc, i haven’t heard of it having spikes
3 replies →
Your comment is down voted because it is false. Go is not "infamous" for gc latency spikes.
It is probably true for game engine dev, but not generally true for game dev, which is a vast field and not as computationally demanding as many imagine. I believe Go's unwillingness to be less strict about some (non-type) semantics would be a bigger problem for game devs than GC.
That's true. Go ain't C4 (JVM), ORCA (Pony), HiPE (Erlang/OTP BEAM), or CLR (C#). The JVM and CLR runtimes have been beaten on for years at immense scale in server-side business settings. I wished Go supported embedded work (without a GC), had an alternative allocator a bit more like Erlang's, and had alternative implementations that transpiled to other languages, but it doesn't. Ultimately, I left when zillions of noobs poured in because it was seen as "easy" and started wasting my time rather than searching for answers themselves.
If performance were such a huge concern, I don't see any valid resistance to Rust that completely lacks a GC and makes it easy to call C code other than "it's something different", "there's too much hype", or "I don't like it". Recent development tools like RustRover make is really damn easy to see whats a move value or a borrow, debug test cases, run clippy automatically, and check crates versions in Cargo.toml. Throw Copilot in there and let it generate mostly correct, repetitious code for you.
I had similar thoughts, about Rust being a good match for game engines but not games. Maybe it suggests Rust game engines might want to include an interpreter for some higher level language to actually do the gamedev in.
Rust is pretty good for writing PL interpreters (and similar tooling) too, actually.
I know you're not asking for recommendations, but Lisp, particularly SBCL, really seems to check all your boxes. I say this as someone who generally reaches for Scheme when it comes to Lisps too.
There are a few game engines[0] for CL, but most of them seem to be catered specifically to 2D games.
[0] https://github.com/CodyReichert/awesome-cl?tab=readme-ov-fil...
> a flexible enough programming structure, moving things around and changing your mind about the most desirable approach several times a day is common during heavy development phases.
That's the kind of code for which Rust-like languages shine. Rich type systems make it easy to change your mind about things and make large changes to your code with confidence.
(Whether Rust tooling is actually at a level to take advantage of that is another question)
> That's the kind of code for which Rust-like languages shine. Rich type systems make it easy to change your mind about things and make large changes to your code with confidence.
I don't think this is true. Rust makes it easy to get the refactor right (generally speaking 100% right). But that's not what they're describing. They're describing where the ability to make the refactor fast, even if it doesn't work correctly (in the formal sense of correctly). That is to say, memory leaks and race conditions and all sorts of horrible nastiness may be tolerable during the dev process in exchange for trying out an idea more quickly.
This is, of course, significantly more work at the end to patch up all of the things you did, but if you don't have to do the full work on 99/100 iterations, or got to try out more iterations because of the quick turnaround time, that would be considered a win here.
Pretty much every compiled language with a static typesystem has that "large-scale refactoring support" though. That's not Rust's USP, on the contrary: a too strongly typed language can make refactoring actually harder than it needs be. The sweet spot is somewhere in the middle (where exactly is up for discussion of course).
>Rich type systems make it easy to change your mind about things and make large changes to your code with confidence.
To be fair, they need to be able to make large changes with confidence because what would be small changes in other languages tend to end up being very large changes in rust like languages.
> Also, ECS is, IMHO, a useful pattern for some systems, but it is a pain in the butt to use with gameplay or UI code.
Not a game developer, but each time I tried to make one not using ECS(or something at least similar in spirit) I quickly found myself not being able to proceed due to the sheer mess in the codebase.
How does one normally avoid that?
> Also, ECS is, IMHO, a useful pattern for some systems, but it is a pain in the butt to use with gameplay or UI code.
I'd love to see a language built around ECS. I wonder how nice it can be in a language syntax where ECS is the easiest thing you can do.
> My priorities are reasonable performances and the fastest iteration time possible.
I bought Mount & Blade II Bannerlord in 2020-03-30. I love it to death, but come on...
Maybe feeling like you're iterating fast isn't the same as getting to the destination faster.
Edit: Lol guys calm down with the down-vote party. I was counting crashes, not bugs:
Does your C++ not crash, just theirs?
That game (currently) has 88% positive reviews on steam and a 77 metacritic score with over 15.5k people playing the game right now (according to steamcharts.com)
Thats a lot of happy customers.
I can't really comment on the quality of the game or experience or how buggy it feels because I've never played it, but I will say that counting fixed crash situations is a somewhat arbitrary and useless metric. If each of those crashes affected and was reported by a single person or even nobody because no regular person could really encounter it is a vastly different situation than if each of those crashes was experienced by even 1% of the users.
The criteria by which something is decided to mention in the patch notes is not always purely because the users care. Sometimes it's because the developers want to signal effort to user and/or upper management.
Maybe Mount and Blade was super boggy in the past and is still super buggy now so all the crashes fixed are just an indicator of how large the problem is for them and how bad the code still is. I dunno, you didn't really give any information to help on that front.
Mount & Blade 2 was released very early and despite constant improvement (they keep patching it at a strong pace), it's only slowly evolving.
It was even downright unfinished on release, with many game systems claiming to be doing something actually being simply unimplemented.
But despite all that it was and is still fairly playable and enjoyable, even at release. A game only needs a great core gameplay loop to succeed, even if large parts of it are completely broken.
Interestingly, Taleworlds make their own engine with fairly unique capabilities. 200 players can fight in fast paced, precise melee combat on a single server. Even more than in fast-paced shooters, it can be extremely frustrating for players when the game doesn't behave in exactly the way that you would expect (for example, standing undefended just a few centimeters away from the reach of an opponent's swing, or relying on interrupting their attack with your own landing 100 milliseconds before). They've made their own scripting language for everything related to policy. So this scripting language is what modders interact with. And it is absolutely atrocious as a language, but it serves the purpose well enough.
> If each of those crashes affected and was reported by a single person or even nobody
Then do you really think they'd be spending time fixing it?
(Actually, you know what, they probably would.)
1 reply →
With Rust and the exact time iteration times, management and deadlines, you end up with the same amount, just theyre panic!() instead. Thats an improvement, sure, but its fighting a symptom.
There are a bunch of useful clippy lints to completely disable most forms of panicking in CI. We use this at my work since a single panic could cost millions of $ in our case.
With modern languages that take safety more seriously, it's a lot easier to spot places where the code 'goes wrong'.
In an older language, you have nothing to tell you whether you're about to dereference null:
Even if you've coded it 100% correctly, that line of code still looks the same as code which will segfault. You need to look elsewhere in codebase to make sure the right instructions populated those fields at the right time. If I'm scrolling past, I'll slow down everytime to think "Hey, will that crash?"
Compare that with more safety focused languages where you can see the null-dereferences on the page. Unwrap() or whatever it is in Rust. Since they're visually present, you can code fast by using the unsafe variants, come back later, and know that they won't be missed in a code review. You can literally grep for unsafe code to refactor.
I love Rust, but a crashing released game is better than a half-finished "perfect" game, or a game where you couldn't iterate quickly, and ended up with a perfectly tuned, unfun game.
> a crashing released game is better than a half-finished "perfect" game
For who? I, and I'm pretty sure most other gamers, would rather a fully-finished "perfect" game that took twice as long.
24 replies →
Photoshop does crash. Trust me if you do enough image editing you'll know it's not even a super rare event. They're generally doing a poor job handling the situations where you have no enough storage or RAM.
It didn't stop Adobe from being worth 200B.
Hard to know what TaleWorlds are actually optimising for because half the features of Bannerlord feel like they’ve never been played by a dev let alone iterated on.
How many of those crashes were caused by memory safety issues though?
A lot of those crashes might simply be called a "panic" in Rust.
And yet the fact that Bannerlord game logic is entirely in C# makes this possible:
https://github.com/int19h/Bannerlord.CSharp.Scripting
which in turn makes it a lot easier and more convenient to mod. Try that with Rust...
Yeah this is a common problem in the industry, we rarely have enough time to refactor what should be considered prototype-level code into robust code.
The game dev industry could form a consortium to launch its own dedicated general purpose language built from scratch to compile very fast like V or Go, run predictability, be much safer, be more reusable, and be extremely productive with the lessons learned from C, C++, C#, and more.
Also, I think LLMs will be able to run against code bases to suggest mass codemods to clean things up rather than having humans make a zillion changes or refactoring fragile areas of tech debt. LLMs are already being applied to generate test cases.
8 replies →
This comment is nonsense
My impression is that this is due to their non-robust programming style. They do not add fallback behavior when e.g. receiving a null object. It would still be a bug, but could be a log entry instead of crash.
> My impression is that this is due to their non-robust programming style.
It's been 50+ years. I don't think that it's worthwhile just telling the programmer to do a better job.
> They do not add fallback behavior when e.g. receiving a null object. It would still be a bug, but could be a log entry instead of crash.
This is a pretty big feedback loop:
If you don't do the first step, you don't get stuck doing the others either.
3 replies →
Arbitrary recovery to null pointers isn't a good way to do robust programming. I recommend doing the exact opposite actually.
https://en.wikipedia.org/wiki/Crash-only_software
https://medium.com/@vamsimokari/erlang-let-it-crash-philosop...
5 replies →