5 ms·
> I think a bigger issue is that Rust just isn't a good language to write a game engine or a UI in. Here's my hot take of the day, as a Rust dev/fan/proponent
by Klonoar 3y ago
> I think a bigger issue is that Rust just isn't a good language to write a game engine or a UI in.
Here's my hot take of the day, as a Rust dev/fan/proponent who's done a few different GUI projects in the language: it's actually mostly fine, but Rust developers won't just settle for "just make it work".
There is true value in a cross-platform common wrapper of native widgets that nobody is really hitting. So many of these GUI attempts are scenarios where it feels like someone stumbled into "how do I build a GUI" and got fascinated by the problem, iterating until they hit a "good enough" point. The problem is that that level of "good enough" isn't actually good enough for a general purpose framework.
Arc/Rc the hell out of it, stop trying to get cute with the borrow checker and lifetime handling, and just make it work. 99% of applications that ship today don't need your novel approach to some virtual DOM diffing algorithm, they just need to reliably shit stuff out on a screen in a way that interacts cross-platform well enough.
- flohofwoe 3y ago> Arc/Rc the hell out of it... Ooof, and now were back to what's a fundamental problem in a lot of "traditional" C++ game code bases I've seen (including my own stuff I wrote in the late 90's to early 2010's). Refcounting overhead cannot be ignored when performance matters, and since refcounting usually 'infects' the entire code base, it's impossible to fix once it becomes a performance problem - because then it's too late since it would mean rewriting everything from scratch with a new approach to lifetime management.
- pjmlp 3y agoYet, not only does the number one C++ engine use refcounting, plenty of commercial engines now have C++ relegated to the core engine, with a scripting language using some form of automatic memory management on top, that drives most of the game code.
- flohofwoe 3y agoDespite all the fancy rendering-tech features, Unreal Engine's "core design ideas" are still deeply rooted in the late 90s and early 2000's (just as Unity's, CryEngine/Lumberyard/O3DE's or whatever it is called nowadays - and most of the other big engines that survived from that era). That's also exactly what I wrote above, refcounting is usually entangled so deeply into those engine designs that it can't be fixed without a complete rewrite (Unity attempted it with their new ECS system, but I have no idea how successful that was, AFAIK it still feels like bolted on to the side).
- Klonoar 3y ago> what's a fundamental problem in a lot of "traditional" C++ game code bases I'll be more clear that I consider the needs of games and the needs of general apps to be very different, and I am particularly discussing the latter and not the former. > Refcounting overhead cannot be ignored when performance matters, People throw around the meme of "performance matters" in the GUI space when we've had mostly working solutions for the 99% percentile of applications for decades now. You're going to throw pretty much all your work to a background thread and send some updates over, or you're going to draw to a canvas of sorts that will likely bypass things altogether. Refcounting is fine for a GUI framework and I am arguing that there is more value in something that ships and works today than waiting around for the next research project GUI framework approach to take off. Note that I am not saying there's no value in the exploration of a GUI framework that feels "right" for Rust, I'm just saying that the insistence on that being the only goal is odd and ultimately holding the community back.
- flohofwoe 3y agoIf you treat every UI widget as its own refcounted object (or even multiple), maybe even uniquely heap-allocated, arranged in deep hierarchies, and share references to those objects within and outside the UI code, then the situation isn't much different from a typical OOP game code base (just replace "UI widget" with "game object") The most important 'technical quality' of both application types is that user interaction latency must be low, and everything animates smoothly with the display refresh rate without hickups. Refcounting overhead isn't much of a problem if the number of refcounted objects is in the low hundreds or low thousands (e.g. a simple game or UI application), but it will become one with tens- or hundreds-of-thousands of refcounted objects which are frequently created, destroyed or "shared" (and with a naive approach those numbers are easily in reach as soon as UI table views come into play) - one typical problem for instance is destroying an object at the root of a large dependency tree, which then may 'ripple outward' and cause the destruction of thousands of other objects, causing noticeable hickups (not much different from garbage collection spikes).
- Klonoar 3y ago> but it will become one with tens- or hundreds-of-thousands of refcounted objects which are frequently created and destroyed (and with a naive approach those numbers are easily in reach as soon as table views come into play) Look, I'm sorry but it's just bananas to throw around "hundreds of thousands of refcounted objects" when I've already bluntly pointed out that I'm discussing general application building. Joe Schmoe wanting to put together an email client should be able to slap a column view somewhere that can render a virtualized list and move on with their life. This has been fine in multiple different native widget kits for some time now. It is not as intensive as what some games want to do UI-wise. The current situation does lead to overly complex UI approaches and contributes to the general approach of "smack it with a web browser" that we all collectively bemoan.
- dathinab 3y agoyes, except thats why you use stuff like ECS systems which involve fundamental data structures so writing them might involve unsafe rust code but using them doesn't and they work as well in rust as outside similar resource/allocation pools in combination with handles into them are a common practice to improve performance, and they work well in rust too (through like e.g. an ECS they often are unsafe to write but safe to use) So while I would agree that "Arc the hell out" doesn't work for game engines (but IMHO does work for GUIs), I also would argue that if you use common patterns you anyway might have used anyway for better performance, complexity handling and/or reduction of the consequences of buggy code (e.g. prevent crashes) you don't have a problem with using rust. Through I guess that makes writing "toy" games where you normally wouldn't bother with such patterns a much less nice experience to write in rust.
- kaba0 3y agoAt that point, why Rust? Like, ARC has a much higher overhead than a good GC.
- Klonoar 3y agoThere are a litany of benefits to Rust that include, but are not limited to: - Cargo and the general ecosystem - The relative ease of integrating with just about any other system - The ability to just build a binary rather than dealing with bundling interpreted languages (like with general Python/Ruby/JS/etc) See my other comment in this thread for why I consider that "higher overhead" to be meaningless for general applications.
- rewmie 3y ago> There are a litany of benefits to Rust that include, but are not limited to Other than Cargo, none of the advantages you mentioned are actually advantages, and are just basic features that are shared by multiple programming languages for decades. If it's hard to justify Rust's use, why insist it's a decent tech stack for this sort of applications in spite of all of the evidence to the contrary?
- Klonoar 3y agoI thought I made it clear - but apparently I should have been far more blunt - that I don't particularly value going in to a comment chain regarding "justify Rust's use for $X". I say this to point out that you're trying to imply: > If it's hard to justify Rust's use I don't consider it hard, I'm just not spending time on it because it's not worth it to me. If I felt it was worth it, I could discuss language features or so on (error handling, functional programming idioms, etc). It's covered fine elsewhere. ;P > Why insist it's a decent tech stack for this sort of applications in spite of all of the evidence to the contrary? This entire thread is due to my not buying the "evidence" that it's hard. Go write in whatever language you want. I want to write in Rust, and I want a functioning GUI framework and I think people are overthinking it. shrug
- 3y ago
- Animats 3y ago> Arc/Rc the hell out of it The pattern I keep needing is single ownership with back pointers. That can be done with Rc and Weak, which pushes the checking to run time. I think it might be possible to do this statically with some extensions to the borrow checker. It's not keeping the forward and back links consistent that is hard. It's making sure that all code sections either have read access to owner and owned, or write access to owner or owned. That's a static analysis kind of problem.
- telotortium 3y agoHave you submitted a proposal to the Rust team about this? It would be interesting to read.