Having tried writing a game engine in Rust, I can't imagine that Rust would become the future of game development. Lack of safety is a feature in game development, because the optimizations required are typically unorthodox and a super strict language slows development down. Additionally, object ownership can be unclear in a game development setting, which typically makes use of global variables for state. The benefits of using Rust over C++ for game development are unclear in these regards.
Isn't this basically saying that you can't have the compiler guaranteeing you aren't including bugs in those optimizations / global variable usage because it's more efficient to just write and then ultimately ship some bugs?
To me it seems like this would require a significant adjustment in how certain problems are approached, but the outcome would likely be more effective development as you could eliminate a lot of cost that's spent dealing with bugs in the future.
Game development problems are very often global state manipulation problems. In a given game, many things may have genuine need to be able to read and write to multiple global variables once per frame (that's usually somewhere between 30 and 240 times per second), and that is after all unnecessary global state has been removed.
Enterprise developers often look very poorly upon the solutions that game developers come up with, but game development is an entirely different realm, very far away from any enterprise software development stuff I've worked on, or even heard of. I've looked. I didn't believe this myself for a long time.
Games have very strict performance requirements that enterprise software simply does not have. Virtually no one in enterprise software cares about performance, really, and certainly not as a primary concern. Enterprise developers will often just throw more RAM or CPU at the problem until it goes away. I mean why not, that's an option that is on the table. Of course they're going to take that route sometimes. Game developers can't do this, because they're not in control of the hardware that their game is run on.
Games are often scored on how good they look, and how well they perform. Game sales are a function (at least partially) of the score/rating that the title attains, and game developers are paid out of the money that game sales provide. Concerns that do not result in an improved critical game rating are secondary. So, there is a very strong hunger there for performance which simply does not exist in other software development fields. Until enterprise software developers are paid based on the performance of the applications they write, no one who has NOT developed a game and fought performance problems along the way can ever understand.
There are games which consume nearly the entire bandwidth between CPU and RAM on a modern PC -- continuously -- and this is after many optimization passes to prune the data that is needed from RAM at any particular moment in time and make it as small as possible.
Game development is just an entirely different thing than any other kind of software development. Languages created with general purpose use in mind may achieve (and have achieved) some success in game development, but those languages will get in the way of the developer at least as often as they aid the developer. Same rule applies for general software engineering rules.
The one thing I will note is that most of what you have said about performance is relevant primarily in the AAA game space (and in higher end mobile titles, which increasingly look like AAA games).
In the indie space, you see a lot more titles where performance is a secondary consideration. The concept (and the style of the visuals) is often more important than having cutting edge graphics.
There are also segments of the business that are more like enterprise software. If you look at something like League or WoW, you have titles that are continuously evolved over many many years, and getting the infrastructure right matters a lot.
But for a lot of indie games smooth running is not a significant problem, because simply their scenes are not complex enough and it is not a big deal even if they are written on some programming language which is not of the highest performance ones like C# or Java (The original version of Minecraft for example is written in Java). There are many successful indie games which are even not 3D (FTL or Darkest Dungeon for example).
if your game is riddled with bugs... you make no money or at least less.
further, the whole point of rust is that is fast and safe.
safe doesn't imply slow.
a lot of game development is entity component systems, and there are several of those for rust - it will be a matter of time until these are good and fast enough to be used in larger and larger games.
The new AC:Valhalla as well. Pretty much any new sport EA game too. Wasteland 3 has been riddled with game breaking bugs on launch and still people have been buying it like there is no tomorrow.
In enterprise, if you introduce a bug that causes a business to not function, you must fix it right away because you may receive lost business and possibly a lawsuit.
In game development, if you introduce a bug that causes a game to not function, you must fix it right away because you may receive lost business and possibly a death threat.
Most of the remarks here emphasized performance, but I believe the actual thing that is "lost" in Rust's model is the ability to quickly rearrange the data dependencies.
A lot of the time, a game's bug surfaces in a way that will never cause a crash: it's just undesired behavior. At some level, the behavior can be defined in terms of "must" and "cannot" constraints, RFC-style.
And in theory you could do some kind of automatic verification of each behavior. But...the majority of the plumbing of the game isn't in the rule logic itself - almost all of the rules are simple. It's in making sure that the mutations produced by one rule will flow neatly into the next, without introducing some form of synchronization bug. This is a real minefield because you're often iterating over lots of similar elements, and it can look like you can bundle their update code to look "clean" or present an opaque interface, but then in practice, you need to split out the iteration differently to resolve a dependency issue.
Developers responded to this by introducing an event-bus abstraction, with bubbling and priorities and all the bells and whistles. But that doesn't really solve having dependencies, it just presents another way to surface a scripting layer.
Repeat this class of problem enough times and you will start inlining the bulk of the update into a single main loop, because that makes manual review of the dependencies more of a spatially engaging process, one where you don't have to provide new boilerplate so that the build process can tell you that you screwed up: instead you just look carefully, see that the ordering is wrong, and shovel around the block of code. Done.
And while you can do this in Rust, it renders a great deal of the language irrelevant, because the features it helps most with are those parts where you want tighter access control across function boundaries. When you start leveraging that access model, behavioral changes can start to take hours instead of seconds, which makes it appropriate for inner-layer backends that need deep optimization, but ergonomically terrible for the greenfield case, which is what games need to bend towards early in production when major features might be changing.
That's counter productive when it comes to gamedev. Most of the code you write for a game is going to be thrown out at some point. Being able to get the idea onto the screen and iterate rapidly is worth a lot more than not having a dev build crash after a while. Make it work, make it right, make it fast except the last two are usually transposed in gamedev.
> iterate rapidly is worth a lot more than not having a dev build crash after a while
You are missing the part about wasting hours or days to investigate the crash, easily offsetting the time saved with fast and loose coding.
It would be nice to see examples to judge whether a stricter language like Rust can save more time on the debugging and fixing side (by reducing mistakes) than it costs with verbose syntax and "unnecessary" safety mechanisms on the design and coding side.
You only have to debug the code if you're going to keep it. I'm not going to spend days debugging a prototype made of spaghetti, it'll have served its purpose and I'll start over with optimization in mind and refine the idea. If you wanted a programming language that would be a real win for game development you'd choose something that had the option of no type or memory safety and no boilerplate for prototyping with an option to turn those options on for when you actually integrate the feature with the rest of the code.
rustc emits a branch to test if v1 and v2 point to the same thing, which is unnecessary (it can never be true!) and can ruin loop vectorization, etc. The useless branch is not serving any safety purpose but requires unsafe to avoid.
I know this is only responding to your one example, and perhaps your statement is still true generally, but I think that in this particular case it is not.
In this godbolt [0] I tried using the safe version of equals with two values (from stdin so it can't just optimize the computation away, though I don't think it would) and it seems that when the compiler inlines the equals function, the inefficiencies are removed (which can be seen in the example::main section of the output; lines 212-216 look nearly identical, if not identical, to equals_unsafe in your example).
Please let me know if I'm missing something or if there are any other safe APIs to be wary of.
Right, the branch may or may not be optimized out; probably it depends on llvm's alias analysis. That's not good, it means you might break it accidentally.
IME Rust is more dependent than C++ on these fragile optimizations. I think it is because idiomatic Rust is more abstract, and also because C++ has more advanced specialization features which allows implementing optimizations directly. For example in C++ you can say "if the type is uint8_t then do this instead..." but this is harder in Rust.
You asked for other examples: consider a simple operation over an array, like bitwise not. A C-style for-loop does the obvious thing but idiomatic Rust emits a gazillion one-byte 'not' instructions. This doesn't involve 'unsafe' but it does illustrate that you really do have to babysit Rust to get efficient codegen. https://rust.godbolt.org/z/PjW5vo
> you really do have to babysit Rust to get efficient codegen
Reminds me of the time we had to write a high performance SQL engine at university. In Java, and it boiled down to exactly the same realization: We spent a lot of time babysitting the GC instead of actually making the actual SQL engine better.
The plan was to use C++ instead, but that option was dropped by the lecturer shortly before the project started :/
That's true, and while I agree that it is a concern, is there ever a way to gain both ergonomics and optimization? In other words, aren't we always leaving it up to the compiler one way or another? You mention C++'s specialization, and I suppose that is a solution, but then you are (potentially, I can't say for certain) sacrificing compile times. Although I will admit that this is probably a fair trade for certainty of optimization, and it would be nice if Rust at least offered some amount of specializing.
Oh wow, that is interesting. Yeah, that probably speaks to Rust still being a relatively new language, although I would have expected LLVM to do something about that... In any case, that's certainly no zero-cost abstraction.
I'm curious; is the extra cmp something that's actually required by Rust's semantics, or is this more along the lines of an optimizer bug/missed optimization?
This particular case is because array delegates to slice for Eq, and slice has the pointer comparison - though it looks like there's some churn here with 'guaranteed_eq' so it may be fixed soon [1].
Actually "won't let you do" or "makes you clearly mark where you did those things"? That is, are you referring to things it doesn't actually support doing that you want/need to do, or just that it's unsafe?
I'm not familiar with rust or if their `unsafe` block mitigates the issue somewhat - I know that for example with memory management, you'd rather ship a game that leaks a bit of memory (since games are generally only open for a few hours at a time, not a lot of memory should be leaked) in exchange for less stutter/performance issues from the GC.
Unfortunately, Rust has limitation on what it can prove to be safe using the ownership and lifetimes approach. One of the simplest things which can't safely be done in Rust is a doubly-linked list.
I'm certain that Rust will help some parts of game development a lot, but I'm also certain that game developers sometimes use tricks safety of which cannot be proven by Rust's type system.
You can do these things safely, you just can't do them safely and efficiently at the same time. You could do a doubly linked list with reference counting, and it would be in safe code, it just wouldn't be classic implementation you'd be imagining, and not as efficient.
You can do circular structures like doubly linked lists in Rust. You can do them efficiently. But you do need to use "unsafe". Of course you do, a moments thought shows you why.
It is not as "safe" as Rust without "unsafe" blocks, but it is still reasonably safe.
I haven't found any problem where a linked list could not be replaced with a vector of index-element pairs (or triples) with a reductions in allocationd.
I'm open for discussion as I haven't been able to convince myself of the use of any linked list.
>Unfortunately, Rust has limitation on what it can prove to be safe using the ownership and lifetimes approach. One of the simplest things which can't safely be done in Rust is a doubly-linked list.
It can be done "safely" in Rust, as in without actual bugs; it can't be done in "safe Rust", that is, Rust without `unsafe{}` blocks. But it's reasonable to assume that any Rust game would make liberal use of `unsafe{}` blocks, because as we have all agreed, game developers don't actually care that much about memory safety anyway.
As such it seems wrong to suggest that the primary barrier to Rust in games development is its memory safety. Perhaps the culture of today's Rust community that shuns `unsafe{}` is unsuitable for games development, but Rust offers plenty of advantages beyond memory safety, and in contrast with C++ the particular advantages I would see as most relevant are:
- no legacy types/structures, important when you have a large team on a shoestring budget working late nights with sporadic communication; there will be fewer discrepancies in code styles
- potentially faster compile times than C++ when Rust is more mature
- distant future item, but there's the possibility for better FFI with game scripting languages when Rust is more mature
None of the above really depends on memory safety except kinda the FFI, but it's all relevant for a game dev.
While the adoption of "safe Rust" has left the tarmac, the best practices and widespread use of "unsafe Rust", a perfectly reasonable language in itself, have barely begun to develop. It's likely that any Rust games will generally be written with lots of `unsafe{}` and while nobody would learn Rust to use `unsafe{}` specifically, game developers might learn mostly safe Rust in CS courses that cover systems programming and then take those skills to the game industry and already know most of what they need to ramp up on an unsafe Rust codebase.
That last sentence is also why I think the Rust games era is at least a decade away; game shops don't usually want to retrain their employees on new languages; they'll just use what's in the field. That's also why Rust will probably beat out Zig (or Nim/Jai), since even though the latter is a little more suited for games, the former is much more likely to be taught in schools.
The technical progress will be unpredictable as usual, but at the level of the problem definition, I think it's safe to say compiling Rust is easier than compiling C++.
Jai used to be interesting, but after a while it feels like Jon believes his language is a competitive advantage, and will never come out. It's either that or he painted himself into a corner and needed years to get some must-have feature working.
Jonathan Blow has a reputation for taking a rather long time to release something eagerly awaited, and the result being impressive and critically acclaimed.
I hope Jai will be the same way. We'll see what happens.
Sure, but that works for a game where you can release it once and then everyone consumes it.
Languages are ecosystems. They have tools, and libraries, and shims to integrate with other tools. They need evangelism. They grow with community involvement. As far as I know, no one has ever released a new language that was perfect in its initial release - there has always been feedback and syntax quirks that get addressed in future versions.
If a "0.1" compiler with warts was out there for people to play with and improve on, I'd have faith. But if you can't get a demo that you're willing to share within 5+ years, then I have very little faith you'll ever release anything, and absolutely zero faith that you'll be able to compromise your mental idea of perfection enough to build a thriving community around a product.
Lack of safety is a feature in game development, because the optimizations required are typically unorthodox and a super strict language slows development down.
One of my first experiences interacting with a golang programmer, was in the context of my game server project. As an optimization, I had a race condition in the code that disconnected clients. After all, if the connection is about to die, I don't care if it dies in frame n, n+1, n+2...etc. This golang programmer was totally out to tell me I'm stupid, ugly, and bad, because I should always be using -race and always have 0 race conditions.
Like, it would have been one thing if he could've had a cogent discussion around how the build should be free of warnings, because that makes such signals super clear, but no, it was just pure dogmatism.
Additionally, object ownership can be unclear in a game development setting, which typically makes use of global variables for state.
In ECS, why should object ownership be an issue? The Systems can just own everything.
given that a behavior in a race condition can be undefined, he or she may have been right. You might get the merely delayed behavior your want now, but something else on a future version of the compiler.
Perhaps you are aware of all these subtleties and knew it was ok in this case.
given that a behavior in a race condition can be undefined, he or she may have been right
If the other party really had an interest in understanding, and not just condemning, he would've looked for more facts. He wouldn't have been talking over me and cutting me off.
The main problem which global state introduces, is making the bad assumption that there will only be one example of a given sort of data.
In games, that's a safe assumption for many parts of the system, since you're definitely only going to be running one instance of the game world at a time. So making that state private just means you have to pass around references to it on the stack, and keep track of what you're doing.
Classic webcrap is near-stateless, with state in the database only. That way, any server in the farm can handle the next client request. Games have a consistent world to maintain in memory. Sometimes a really big consistent world.
I feel like this is an underrated sentiment. A lot of Rust’s design decisions (lack of inheritance, borrow checking, immutability by default) are complete non-issues when you’re reading a JSON string into some business struct or an enum and then serializing it back out to a DB again. Everything can be flat data types and functions can be pure and stateless.
But not if you actually have to keep things around in-memory. Then all the sudden your functions can’t be pure, you have to add additional parameters to each method to account for additional state, and you can’t design flat structs anymore since you have many different object types and they have to go somewhere and you can’t just declare N variables line by line. So you have to grapple with the limited definition of trait objects, or non-extensible enums, or throw everything out and use Any. It gets complicated.
Rust is just one of the current Silicon Valley memes at the moment. You could hit the front page with an article titled "Why Rust could mean you'll never run into another broken McDonald's ice cream machine again".
"Machine learning let me train my dog twice as fast."
"How AI will revolutionize marriage counseling"
"Study: Using Go results in 10% better senior programmer retention"
> Lack of safety is a feature in game development,
Bullshit.
How many games have had releases delayed and major wrenches thrown into marketing plans because of progress ruining heisenbugs? How many failed certification passes from banal data races and other undefined behavior?
We trap UI in actionscript or javascript, and gameplay programmers in other scripting languages - perhaps python or lua - for faster iteration times, hot reloading, and safety. Because it's difficult enough to keep the build stable when it's merely all the engine programmers who should know better screwing things up with C++.
This results in large messes of poorly performing, poorly optimized, garbage-collector laden code that Rust would handle much faster. We're leaving lots of performance on the table, often for little other purpouse than "safety".
Console first day patches may have taken off some of the pressure for getting the first release right, but handhelds aren't always online and still have a pretty high bar.
> the optimizations required are typically unorthodox
Rust's `unsafe` keyword and intrinsics let you do all the unaligned intrinsic-laden data-racey technically-undefined-behavior micro-optimizations you might want to do in C++ in Rust just fine.
It'll hopefully trigger a more stringent code review and force you to justify your pile of bugs, but that's a good thing. Or you can skip the code review if your entire company really disagrees.
> a super strict language slows development down
C++ is also super strict, just in an unenforced-at-compile-time way that result in plenty of late nights chasing heisenbugs. Don't get me wrong - language strictness can slow development down - but that's one of the reasons people eschew C++, too.
As for C++ vs Rust? I'm going to spend more time and be far less certain of catching the issues in a C++ code review than I would be in a Rust code review. And while it took a few months for my development speed in Rust to catch up with my development speed in C++, it did happen.
Rust merely forces you to acknowledge when you're being sloppy.
> Additionally, object ownership can be unclear in a game development setting, which typically makes use of global variables for state.
I have solved so many sources of endless heisenbugs by eliminating some of these global variables. John Carmack as far back as 2013 was using phrases like "horror show" to describe similar parts of his own codebases[1] and has been agitating for more functional styles.
An unclear mudball of global variables is entirely possible - and easy - in Rust if you really want that. You merely need to make it either thread safe, or resort to `unsafe` if you really can't tolerate the overhead of not having threading-related heisenbugs.
Just counting my personal experience, I've seen multiple titles fail cert and delay release thanks to bug backlogs that were mostly filled with memory issues, even after months of working to reduce the backlog of crash bugs. Perhaps you can't blame that entirely on the C++ codebase, but you sure can't absolve it entirely either.
At every single studio I've worked at I've helped build out crash collecting, symbolizing, or deduplicating infrastructure just to get a lead on where shit is exploding, and seen major productivity outages when tooling crashed frequently enough to disrupt the workflows of my coworkers. Address sanitizer, valgrind, extra debug allocators - I've sunk a lot of time into just making these crashes shallower to debug and quicker to catch.
One of the smallest and quickest projects that comes to mind was an NDS -> iOS and Android port. Do you think most of the time was spent in porting APIs and control schemes? More than half the time on that project was spent just chasing down really stupid memory related crash bugs that were exacerbated in frequency and time by the port. I made damn sure to communicate my concerns about the schedule, and if my memory serves me correctly, we managed to soft launch "only" a week or two late.
C++'s strengths are it's lean portability, speed, and huge existing codebases and tallent pools. Undefined behavior is simply the cost we begrudgingly pay, not it's strength, and even that we often mitigate by trying to figure out ways to write as little C++ as possible - keeping it only for the parts of our codebase that are actually performance sensitive. Tooling is often C#, Python, anything but C++. UB is a pox and constant time sink.
Whenever people call out C++'s UB as it's strength, I'm left wondering how many of their bugs do they actually fix, and how many are begrudgingly fixed by their coworkers. Most of the people whom I've worked with with that attitude don't pull their own weight in the debugging department, so they don't see the full costs of it.
I don't share the same experience. Crashes do happen but I wouldn't call the time sunk there a lot. If you get a ctd, usually a callstack and a bit of thought is enough for figuring out what is going on. At worst case you have valgrind. Very rarely it goes beyond that but even with that I would say it is a well trade off on how relaxed C++'s memory management is compared to Rust. And I believe C++ is relatively safe when you have well designed systems where ownership is clear enough. I have a feeling that if my company suddenly flipped to Rust now, the struggling against borrow checker would be a bigger time sink
For me majority of game development is feature development and fixing gameplay related bugs. Which will be same regardless of language you use. And depending on language feature development might be even slower
> If you get a ctd, usually a callstack and a bit of thought is enough for figuring out what is going on.
Very different experiences. Sometimes that happens.
Sometimes the symbols have been evicted from the symbol server. Sometimes the minidump didn't capture relevant memory (and the full dump would be a couple dozen gigs, making external QA reluctant to constantly capture those). Sometimes the crash is the result of memory corruption from unrelated systems minutes ago that doesn't reproduce when you enable any of your debug allocators because reproing relies on pointer reuse in a hashtable. Frequently custom allocators defeat tools like valgrind and address sanitizer, requiring extra work to either bypass or explicitly annotate valid/invalid memory ranges. Sometimes the process only exit(3)s (technically not even a crash!) from an unrelated thread on a specific bit of UI with no relevant callstacks nor logging, and if you open up the windows charm bar for more than 10 seconds without a debugger attached, and you resort to bisecting p4 history once you've spent the several days even figuring out repo steps.
That wasn't even our bug, but it was our workaround... even when the codebase is good, the middleware often isn't! And that is but one of many I've had to deal with.
> C++ is relatively safe when you have well designed systems where ownership is clear enough.
Meanwhile, the poster I was originally replying was pointing out that you can have unclear object ownership full of globals and C++ is somehow supposedly good at dealing with this. Hopefully you're at least agreeing with me here, in disagreeing with that! :)
A lot of gamedev code isn't very well designed, IME, and "relatively" safe can be suprisingly unsafe as well.
> I have a feeling that if my company suddenly flipped to Rust now, the struggling against borrow checker would be a bigger time sink
The first couple months after I picked up Rust, I had that phase. Now it's quite easy for me - sometimes it requires a deep `.clone()` or two, but in the equivalent C++ codebase you wouldn't have even dreamed of not making the deep copy - because in equivalent C++ code it'd be impossible to do the equivalent fancy zero-copy borrowing nonsense even remotely safely.
Rust over C++ for single player games is definitely of questionable benefit right now. For multiplayer games I think a much more compelling case can be made, certainly on the server if not both server and client.
I think a number of companies, like mine, are working with Rust internally. But articles like these don’t provide any insight into those efforts, which are kept private.
Game development at large-scale is a mix of systems programming of the kind that Rust excels at and gameplay logic programming which has loose performance requirements and may be written by people who are not primarily coders. So you see a lot of codebases split between two languages, like a C++ core with Lua bindings or something like that.
If we see Rust adoption here I’m expecting it to be from a kind of skunkworks inside the company replacing specific, carefully-chosen systems with Rust code. At my company, that’s how it’s done, and it’s a very slow process. (I don’t work in the game industry, so all I hear is rumors from people that used to work in the game industry.)
Right now, I'm writing something 3D game related. It needs considerable parallelism. The existing tool in this area is mostly single threaded, it's a mess internally, and everyone who looks at it is scared to try to parallelize it.
So I'm writing in Rust. Safe concurrency is a plus. There are some other wins. You can be bolder about not copying things. When decoding an incoming packet with a lot of structure, I'm creating linked data structures where most of the big byte array stuff is borrowed from a packet buffer that went into the structure creator. No allocations; it's all on stack. There's no risk of someone using an item from one of those structures and keeping a reference to data that's going to go away. Wouldn't dare do that in C++.
I get along with the borrow checker just fine. Once you realize that single ownership is a tree, it makes sense. It's the type inference system that causes headaches. Rust has type inference in both directions. There are places where the result type influences what goes in. When the inference system guesses right, it's great. When it can't solve the problem on its own, trying to figure out what it wants is annoying. Go and C++ only have forward type inference; result types are computed by the compiler.
Rust is really a single assignment language, not a functional one. There's a lot of "let foo =", and not much "let mut foo =". After a while, you get the idea that if you write "let mut", you're doing it wrong. Single assignment has most of the benefits of functional, but without multi-line expressions that go on to infinity. Plus you're not limited to a tree of results; you can have directed acyclic graphs, because you can usually re-use the value from a "let".
The type of error objects is still a mess. Rust needs something like Python's exception type hierarchy and a consistent way to convert special error types into more general ones. I notice there's a Rust working group on error handling, again.
Rust needs a good book. Not "The Rust Programming Language". That's too hard for an introductory book and not detailed enough for a reference manual. A book by someone who didn't develop the language is needed.
The library situation has improved quite a bit since the last time I tried Rust, a few years ago. Back then, finding a library to do HTTP was "No, the one you're using is obsolete, use ...". Now I'm finding usable libraries for obscure things like analyzing files from "tcpdump".
They missed a chance on something important to 3D work. Each library which uses 3D vectors has its own structure for them. There's a proposal for a common format, "mint", but it's not getting traction. This is an old headache in 3D programs with components from different sources. Back when I was developing ragdoll physics, I had four 3D vector types in one C++ program.
> The type of error objects is still a mess. Rust needs something like Python's exception type hierarchy and a consistent way to convert special error types into more general ones. I notice there's a Rust working group on error handling, again.
This article doesn't actually talk about "Why Rust Is the Future of Game Development." You could have taken out the game development piece, and it still doesn't talk about "Why Rust Is the Future of Development," more than talking about Rust features themselves.
I should be able to complete the sentence, "Rust is the future of game development because...," but I can't in any meaningful way.
Here are the highlights of the article, instead:
Rust is the future of game development because Rust has the performance of C++ with the convenience of C#.
Rust is the future of game development because Rust has ownership based memory.
Rust is the future of game development because Rust is popular. (The article doesn't say this explicitly, but implies it is.)
Rust is the future of game development because Rust is still an immature language. (This doesn't actually sell the point, and I'm not sure why the author bothers talking about this.)
What's weird, too, is that the article talks about how hard networking is, but _cart has specifically said in the past, "Yup! High level and low level networking is definitely on our radar, but it also isn't our immediate priority."
It may come as a surprise, but you basically have to bake networking into the engine. It's not easy as an afterthought. Rust doesn't help with this. In fact, multiplayer and all its challenges have nothing to do with Rust.
We had modern client-side prediction roughly 20 years ago, and people still don't take multiplayer seriously.
> It may come as a surprise, but you basically have to bake networking into the engine. It's not easy as an afterthought. Rust doesn't help with this. In fact, multiplayer and all its challenges have nothing to do with Rust.
I think multiplayer is an area where you'd want "fearless concurrency". Rust could do well here.
> Not really, a tremendous amount of game code doesn't benefit from multithreading. So, this also doesn't have anything to do with Rust.
Is that it doesn't benefit, or is it that the benefits are too hard to achieve given the nature of memory issues with games that like to have global state and are written in C++? A lot of games do a bunch of things every frame and then increment state. Those can all be parallelized as they only depend on the previous frame's state.
Games code is very often about objects interacting. Especially the expensive stuff (collision/physics and then probably AI). Games don't use global state, because they use C++ and everyone is so bad at programming, but because that's what fits the problem domain.
Not to be condecending, but you should try making a game and see how well that parallelization idea of yours turns out.
You can't just take any type of game logic and parallelize it either, since there are types of game logic that aren't just dependent on the previous frame. You may be wholly dependent on something that has just occurred earlier in the frame, but has not been networked to clients yet.
I believe Bevy (rust game engine) does leverage multi-threading for running game code (most 'data oriented' frameworks do). The most popular older engines like Unity do not (unless using the experimental DOTS framework).
So, the phrase "a tremendous amount of game code doesn't benefit from multithreading" is actually true since most game code is in unreal/unity, but it's not a hard constraint for all game engines.
I think there is without a doubt a space for it. Multithreading in today's game engines should be commonplace, I think. And that's outside of the obvious threads like main and audio.
The problem is that most naive "game engines" which provide nothing more than bindings to OpenGL/bgfx, OpenAL, Box2D, etc. and are really just "game libraries," don't even provide things like out-of-the-box multiplayer or level loading, so the idea that they're going to make the leap from providing basically nothing to providing mechanisms for multithreaded game logic, which requires some sort of gamerules/gamemode abstraction first is not something I think you'll see in practice.
Most game libraries or game frameworks like these only provide things like load, update, draw callbacks with some nice bindings.
I'm not making comments about bevy. I'm talking about game engines in general.
> Not to mention that you evidently don't _have to_ do this, seeing as how in Unity you're basically forced to work with raw sockets.
I don't know how old you are, but by the time 1999 rolled around, id Software had produced essentially the same multiplayer client-side prediction model that has been in major use to this day. It hasn't fundamentally changed.
The fact that Unity cannot reproduce 20+ year old tech is a joke, not an example. In fact, UNET was such a joke it basically tried to ignore this fundamentally unchangeable architecture and they ended up canning it in the end.[1]
> Let me tell you that the future of game development ...
> Does anyone care what language were any particular games that keep being replayed
That seems to be a non-sequitur to me.
What does what people play have to do with what developers are using to create? That's like asking if users care what language serves the web pages at Facebook. The users don't care, but people that make web sites/applications (the developers) might.
Do you know what brand of guitar/piano/keyboard etc your favorite musicians use? I bet other musicians care about that.
It is important: I have very good memories of flash games. But those are now unplayable. (Well, I guess you can still run flash. But it doesn’t work out of the box.) The technology in which a game is made does matter a bit.
I think this is actually a key to why Rust will do well in the (possibly distant) future.
Rust has one of the best Lang->WASM stories out there. The thing that made Flash games so popular was the "You just load up the page in your browser". I see rust fitting very well into that role in the future.
Further, because WASM is a part of the web standard, I don't see it going away anytime soon. Those WASM games will work for a long time into the future.
Rust likey won't help here. Will just be in a place where things won't compile in the future despite being the same language.
This is something our industry seems bent on doing. To hell with stability at the foundational level. Progress is measured in features. And those have gotten pushed to the foundation.
Thanks to Unity Mod Manager and Harmony (C# Monkey patching Framework), unity games even get mods pretty much for free without the devs doing anything to support them.
Minecraft is a good example where people talk about the programming language.
The portability of Java was a benefit for both Server and Client. But it was also critized because of the inefficiency of Java.
I dont know if all this would have been better in Rust or other languages.
Microsoft now has a second parallel implementation of Minecraft in C++. They've ported this to numerous platforms, but notably not MacOS or Linux desktops.
(It's also substantially faster, but comparing it to Java edition is sort of unfair because there are a myriad of differences between the two in game mechanics, with many of the differences probably being relevant to performance.)
I don't know for certain, but Java might be one of the reasons for Minecraft being as good as it is as a game. The comparatively minimalistic high level nature of that language leaves few possibilities to get lost in system level optimizations. And iterating in Java is a lot quicker than in C++ or Rust. It is an environment that helps focussing on game logic.
Eventually Microsoft rewrote it in C++ so they could run it effectively on things like iOS and Android. It took them a while to reach feature parity and some level of compatibility between them.
The C++ one didn't have all the same features as the Java one for a while, but it ran fine on weaker hardware than the Java version needed.
Is it me or are you bringing up something completely unrelated there? because it baffles me why
I don't think the writer was talking about the the language somehow directly being related to a gamers experience.
He's talking about building complex game engines and the like and the benefits he thinks Rust provides there...
I agree with you, but there are plenty of poorly educated gamers who think that 'developed in Unity' or Gamemaker means the game can't possibly be good. (All evidence to the contrary.)
The future of Game Development is about democratization of tools. With tools like Unity, GameMaker, and RPG maker it has become easier and easier for anyone to make a game. While Rust might be a good foundation for some performance critical code, I'd hardly say it's the "Future of Game Development".
Already, games use tools like Blueprints in Unreal to make games with limited to no coding experience, and I expect those tools will continue to get better and better over time.
Right-- but that democratization is the scripting level of games, where a lot of work and value is added. The underlying plumbing for graphics, AI and physics are not going to be done in in a visual programming language in the foreseeable future.
It is important to understand the difference between parts of a game that are expected to be performant and parts of a game that are expected to be easily changed or modded.
But Pfhreak's point is that most people don't want to "build their own engine", they just want something that lets them make a game, and Unity and GameMaker are very good at giving you that running start, even if you know very little programming. The Rust gamedev community, so far, hasn't even tried to create that experience.
Most people don't want to build their engines since it's hard in cpp. If building an engine consists of selecting a couple of crates, people might have a different opinion.
No, most people don't want to build their engines because building engines is a different thing than making a game. People want to build just the part that's unique to their game. Very, very game devs care about how things are drawn to the screen or what's happening in their physics engine -- they just expect those things to be easy to use default features.
one te driver tend to be write in c or c++ make it mor reasonable to use the same langues, ogre3d for (c++), heaps( for haxe i love it compiled to c++), mono(for c#/ c++), raylib (c/c++), i dont know why you want spend at of time in make a engine that need some of this frameworks, whit weird interface to use rust
Not directly relevant, but the use of the phrase “democratization” to describe a process that has nothing whatsoever to do with democracy (“anarchization”?) has become a pet peeve of mine.
Democratic has a well established meaning of 'being available or appealing to a broad group of people'. Democratization is the process of making something democratic and my use (and the wider use of the term to mean 'make accessible broadly') has been pretty well established for a long time now.
The printing press (and printmaking in general) are both examples of democratic art -- making art accessible to the masses.
I'm assuming it means getting public involvement? Getting people to participate in the process.
That said, I do feel most of the examples are not that. The old shareware scene was much closer to the spirit. Now that we are pushing winners only, feels more like corporate control than it does people control. :(
Go visit http://itch.io/ and search around for a bit. There are thousands of games to explore here made by people from all walks of life. Most of these will see zero to minor financial success, but people are still making them because they are inspired to share some experience.
Even on the major platforms, you'll find stuff like Umurangi Generation, a game about taking photographs in a surreal autocratic environment. That game is not a 'winner only', but it's fascinating and only exists because people who want to make that experience had access to tools they could understand and use.
Democratic processes and tools are tools that are widely available to the public. It's not only AAA studios making games, everyone around the world is making games.
In this case, the meaning is orthogonal -- it's about accessibility to the tools, and the accessibility of the tools. That could be centralized or decentralized, as long as the tools are easy and available to the masses.
But I think where that doesn't match is democratization means the masses have some critical decision input into the tools. Being able to get the tools on a wide scale, I would say is just plain consumerism or market reach.
alot of critical parts of a game engine are already made in c or c++, and mono(the default stand for closs plataform for not engine user is not compatible whit rust)
Ditto. Also your debugger of choice (Windows again). I can debug C#/C++ in one app (or other .NET language). It's bit of pain for anything else (granted, Rust, I'm told should be good).
Then you have the build process, vendorizing your packages (so you don't fetch them off internet), etc. Right now .sln files and MSBuild rule there (like it or not).
There are some AAA game engine and graphics developers actively using Rust in their main codebase like RAD and Embark, and many are Rust curious and using Rust for side projects or tools. It's true that it will be a while before wide Rust adoption happens in the game industry (if ever) and C++ will stay around for a while. As for tech in games moving slowly... there is some truth to that but some things also move much faster than web dev due to new consoles cycles with new hardware capabilities. It will take a LONG time for a SV startup to fully embrace WebGPU even when browser support is decent, on the other hand every AAA game engine has HW raytracing support
I'm aware of Chucklefish's usage of Rust, but they aren't a good AAA example even if they've shipped some of the most successful indie titles of all time. Also, as mentioned in a sibling comment they have abandoned Rust because the lead programmer that was driving it moved on.
Do you have any articles or any info on why they decided to stop using Rust? I remember seeing things about them using Rust but never saw anything about them not using it and I'm curious.
They made a few offhand comments on Reddit, but that's it.
They decided that having a unified tech stack for the games themselves was worth more than Rust's advantages. Basically, they decided to re-build Witchbrook on top of Wargroove's engine.
That being said, I guess I should have put an asterisk on there; they aren't using Rust in game anymore, but they are still (apparently, last we heard) using Rust for server-side components. Wargroove's servers are implemented in Rust.
> Let me tell you that most C++ game dev never heard of Rust
Why would you say that? I have no reason to believe it.
C++ and Rust discussions frequently overlap so it's unlikely anyone who uses C++ hasn't heard of it. Game developers, in particular, are exposed to a larger segment of programming languages simply out of necessity. Searching for solutions or functionality will usually lead to esoteric options and the ever-present gamedev talks about how language X solves a portion of your gamedev woes.
If you count Unreal engine game devs then I could see it being true. Many devs script with blueprints or work on art or sound or level design etc. Not every Unreal dev codes with C++ daily.
If you openly admit in a public internet forum that you use C++, you WILL be reminded that Rust exists and it vastly superior to your choice of tool. I find your statement very questionable and don't personally know any game developer (though I know a good number) that hasn't heard of Rust. So I would like to know if you actually know this from experience or are just guessing.
It means they aren't curious about progress. Not someone you want to hire, unless those who run projects don't care about anything either. And sure, you can explain to them what better tools can offer. That was the point of the linked post. And if they don't want to hear the answer, then again someone probably hired wrong people there.
Game development shops are notoriously cheap. They have to hire people willing to work for peanuts. Like the circus, they take who they can get, from among people who need to be a part of the magic.
Meanwhile, game developers, as a rule, are interested in (surprise!) game development, not languages. What Rust brings to the table, few game developers are looking for. But Rust builds are notoriously glacial, where game developers are wedded to the edit-build-test cycle.
So, gaming will be one of the last places for Rust to thrive. That doesn't mean no games will be in Rust. Rust coders will compete for jobs using it, rather than game shops competing for Rust coders.
Also: you assume you are the arbiter of progress. Not everybody agrees with your assessment.
For example: spending an extra hour or three each day, waiting for the compiler, might not seem like progress to everybody. Their assessment is as valid as yours.
Furthermore: you assume that people who hire must also agree with you. But, some people who hire want coders coding more and waiting for builds less. That is a legitimate desire.
The issue of intrinsic merit is nowhere near as settled as you imagine, even leaving aside time wasted by Rust's extremely slow compiler.
The fact remains, and will remain, that C++ can encapsulate in libraries semantics that Rust cannot, and according to the Rust core language developers will not. As a direct consequence, it is possible to program at a higher level in C++ than in Rust. This gap will get larger as more libraries are written that exercise the difference, and as C++ adopts new features that expand the difference.
Within the HN echo chamber, the apparent situation is muddier because technical merits carry little weight vs. trendiness and surface sheen.
How likely game programmers are to use the greater capabilities is neither here nor there; they probably see more effect from the extremely slow compiler.
Numerous features, with more arriving every third year. Operator overloading, exceptions, partial specialization, template function overloading, overridden move constructors, concepts...
Yes, there are many features that C++ has that Rust doesn't have, but "the devs say there never will be" is a different story. For example:
* Operator overloading: Rust already does this
* Exceptions: this is true, Rust will not do this.
* Partial specialization: is in nightly, will be made stable
* Template function overloading: not in Rust, nobody has said "never" though it is controversial
* overridden move constructors: this is true, it won't happen
* concepts: traits are already concepts and exist today.
The situation is significantly different than you've presented. We do have several features that we need to catch up to C++ in areas, but the big ones are on the way. It's more minor or stylistic, rather than capabilities, that are maybe not gonna be a thing.
Two weeks ago Rust was the future of embedded systems (it is not) and now it is the future of Game Development (it is not). I'm starting to think that people's opinion shouldn't be taken seriously unless they have like at least 20 years of experience in a particular field.
> Yup! Rust has mature and production ready frameworks in Actix Web and Rocket, and newer ones like Warp and Tide. These provide everything you’d expect from a web framework, from routing and middleware, to templating, and JSON/form handling. There are crates for everything, and more!
I would pay for a reality show where a big Rails application needs to be replaced by Rust by the same engineers who built it.
I mean C and CPP are used in both fields so it's not hard to imagine that since Rust is trying to replace both languages, that it would become popular in the two fields as well.
I haven't worked in the games industry so please correct me if I'm wrong, but isn't game development culture one of rushing crude hacks out the door at the last minute? Rust seems like a poor 'culture fit' in this regard.
From what I can gather (from the outside) this has changed over the years. Games are not monoliths anymore and some parts have to work for successors or other games based on the same tools, so "things work for more than the bare minimum" has become more important over time. I'm sure there's still more than enough throwaway code, but that is probably not done in C++ currently either, but in some kind of scripting language.
Q: What does a game company call a teetering tower of ugly hacks on top of ugly hacks?
A: Shipped!
Source: 5 years in the games business. The game development process can get messy. My studio doesn't crunch, but elsewhere crunch is the norm, and does anyone think the code is gonna stay beautiful during endless crunch? The old-timers here all have their war stories they tell of last minute ugly hacks tossed in just to get a game out the door on time.
The article sorely misses code examples: any demonstration of something that can be done better, or at least differently, in Rust than in C++. Without concrete details, only worthless hype remains.
I have never made a serious attempt to develop a game, but it has always seemed to me like a problem that inherently breaks a lot of software engineering concepts.
A lot of what makes games fun are the exceptions to the rules. An extra game mechanic in a special circumstance that allows you to do something that the basic rules don't. Or just a mechanic that stops something un-fun from happening (getting stuck, or it being too easy to trick an enemy).
But clean code always follows the rules, and makes it harder to introduce special cases.
I'm not saying software engineering has no place in a game, nor that rust would be bad it it. Just that it's less clear how software engineering will help a game, or if the game will be nudged toward a different style by the language somehow.
> The performance of C++ with the convenience of C#
Convenience is a relative term. Convenience to what ? Personally, I find that far from the truth. Rust is very powerful, offers lots of flexibility in memory managing and allocation, which makes a difference in gamedev, but overall it's far slower to code in, because of that. And that is very bad for gamedev, in which fast iteration times is crucial. You code something, test it. Scratch it. Fix it. Test it. And so on.
Not in a game business, but I could tell you - until Rust is supported (down to debugging) in Visual Studio, there would be no C#/Rust apps, and plenty C#/C++ apps.
Debugging in VS actually works pretty well already, the msvc target generates PDB files. It's what I use when need to attach a debugger to something.
Actual language support would be really nice, though. Hopefully MS are already working on this.
> even though Rust seems like a rising star, it won't reach C# levels of tooling for quite some time.
Just curious; what's the tooling gap between Rust and C#, according to you?
I work in C# profesionally, and dabble in Rust, and haven't really found Rust tooling lacking yet -- but maybe that's because I'm only working on small hobby projects.
Aren't you using refactoring tools like ReSharper?
Also, what about debugging? C# does edit & continue and allows arbitrary statement execution during debugging. Does Rust debugger even allow moving the instruction pointer at will?
Personally, I'm betting on Haskell - for indie dev in particular where I want to manage huge amounts of complexity as an individual. This is partially because I've been programming Haskell professionally for 5+ years so I'm over the learning curve and well into the realm of efficiency gains.
The GHC RTS is akin to the Lua layer and handles all the high-level logic. For storage and compute-intensive things, we can drop to lower-level primitives for performance and then easily hook into them in our scripting layer. I wouldn't be surprised if fleshing out this domain hints at future useful GHC extensions as well.
I like Rust a lot, but I honestly think the ability to do highly-abstract programming is worth having to deal with a non-literal compilation pipeline. For gamedev at least.
I honestly think it will be astounding what scale of game a single developer will be able to build in Haskell in 3-5 years once all the pioneering is out of the way. Programming a game the size Blasphemous could easily be managed by a single Haskeller I'm pretty sure - leaving resources to focus on art, sound, and storytelling. And that's an easy call - it'll be fun to see just how big and complicated of game logic we can make cheap thanks to good abstractions.
I could see this with Idris, but Haskell's lazyness is just too unpredictable for anything you wouldn't use a scripting language for. People have been trying to get gamedev done in Haskell for like a decade with virtually nothing to show for. The LambdaCube 3D guys have been working on it for ~8 years and last I've seen they couldn't even get quake 3 graphics to render smoothly.I haven't seen any noticeable development in recent times, so I don't expect that to change in the next few years.
The only thing I could realistically see happening anytime soon would be people using it as a scripting language for Godot, but I'm not convinced that working with the Godot abstractions won't rob you off most of the gains you make by using Haskell.
Laziness really isn't an issue. Especially when writing FFI/low-level Haskell. I suspect the heavy-lifting will be written in a more performance-conscious style. And a lot of it will be deferring to industry-standard C libraries. And then you're right, idiomatic Haskell would have its place in the scripting layer.
I honestly don't think there's anything inherent to Haskell that stops it from being used to make high-quality commercial video games. So my plan is to try to build those in Haskell and let the libraries and infrastructure fall out (as it always nicely does using Haskell in my experience.) Honestly, developing high-quality games is more bound by art & creativity than Haskell.
One of the problems with Haskell for game development is, because of the novelty of lazy evaluation, it's very difficult to learn what causes space leaks, and it's difficult to learn how to debug them. If you're already an expert in Haskell this might not seem like a big deal, but it certainly makes adoption a lot harder.
Another related issue is the level of abstraction is so high that it makes it harder to be extremely optimal with memory usage and access, which is something game developers love doing, even sometimes when they don't strictly have to.
I love programming in Haskell, but I'm highly suspect that it will ever be a widely used game programming language. It's very good at expressing computations in the abstract at the expense of being good at telling a physical computer exactly what to do. Game programmers tend to prefer languages that fall in the latter category in my experience.
Yeah I agree it'll never be mainstream for gamedev. Haskell is not really built to have runaway adoption. It's a strength as much as it's a weakness.
But I think it'll allow me to be insanely efficient as a gamedev. So I'm a Haskeller-turned-gamedev. Not a gamedev-turned-Haskeller.
Haskell performance and memory usage is kind of like JVM programming. You need a mental model of how GHC and its RTS & GC operate. Having frame-oriented code honestly makes it easier to reason about. We Do need more learning materials about this stuff, but first we need more experience!
But idt it's any different than using GC for gamedev. And manual memory management is well within Haskell's capabilities.
Haskell profiling IME makes space leaks very obvious. That's a too-common paper cut, but once you get cut once you don't make the mistake again :)
I think Rust is actually pretty cool and I have tried it myself for a few small things, but it's definitely the most obnoxious programming language community out there (which does not mean, at all, that everyone that is a part of that community is obnoxious). Remember that "Rewrite it in rust" is a meme.
I really liked the community chat of Rust. For all beginner questions there is someone standing by to answer it in under 10 minutes. Sure, Rust is hard but having people explain everything to you in a chat when you're stuck is worth gold.
I suggest this person writes a game in rust and then writes this article, otherwise what's the point?
Is the main issue in game development memory safety? Cos if it isn't then why would rust be better?
Whenever I see people programming in rust they are usually having to work around the borrow checker, which arguably makes them reason in a better way about their programs and also arguably wastes loads of their time doing something they know is correct but the rust compiler can't reason about.
I don't think rust has "fixed" reliability or performance issues in Firefox has it?
Full disclosure: game development beyond the cli-based games and some simple asteroids-like games are the most I've ever done with games. I find them incredibly boring, both to make and play(kind of ironic considering up untilrecently I was working as a developer for a company that made games and I worked there for 8 and a half years). But 3 weeks ago I switched jobs and I am using rust in my current workplace, again, not for gaming but for data processing. I have no idea if rust will ever go deep inside the game development business but if it does, I feel like it will be in the very distant future. The main problem being the limited ecosystem compared to the big players. I do however believe it has the potential to give C++ a run for it's money should the ecosystem ever catch up. For starters it sits on top of llvm, so out of the box you have windows, linux, mac, ios and android covered and the tooling is the most batteries-included beast I've ever seen(namely cargo). I guess only time will tell but my bet is it won't happen in the next 5-10 years.
Indeed, but that's also it's Achilles' heel at this point: it is progressing incredibly fast and most people will have a second thought about using something that might change drastically six months down the line. As I said I love rust and I'm incredibly happy to be using it on daily basis and the company has voted enough confidence in the project but if I were to start something on my own, I will most likely have this fact lurking at the back of my mind.
But rebuilding seems faster since the Rust Compiler is smarter about caching things. I think that the way the Rust module system works also makes things faster.
It really depends on which part of "Game Development" you are talking about. What most of the people agree is that Rust can deliver value to the core and to the performance focused components in the game engine. I assume that's what this article is talking about too. But beyond that it's hard to see it eating the market in other areas.
You really want to have some easy to find average coders that can pretty much script your game on top of an engine and framework, and you don't want to spend way too much on them. It could be a different story for some multiplayer AAA games since they have enough lifetime to become mature and start to take every optimization opportunity.
I don't think so. You need a load of libraries to make a simple 3D: Model loader(Assimp), some GUI(imgui), input/window manager(glfw/SDL), image loader(OpenImageIO), animation engine(OZZ Animation), some interface to the GPU API like OpenGL/Vulkan(bgfx), physics engine(Bullet Physics), sound library, etc.
Sorry, but the learning curve of a programming language matters a lot. It's already hard enough for people to read and write code, so to learn another hard language like rust is not something you do lightly.
Rust is a cool language, but it's a cool tool, nothing more. I'd rather see the ownership process implemented in some C/C++ dialect. I'm not entirely sure, but I think that C++ concepts, in a way, have the same goals than ownership.
Safety doesn't always matter. It matters for a company like Mozilla and anything that's network/system related, that's for sure, but for games, I'm not so sure.
Also, statically typed languages that compiles to machine code are a niche now, new languages in that area don't really matter. You either have kernel code, or interpreted languages. A big quantity of C/C++ userspace code is fossilized code. Computers are quite fast for a lot of interpreted languages.
The future is game development is GaaS and putting as much as p2w/gacha elements into the title as much as you can get away with it (on top of selling the game for $70)
Crating is horrible. How about that to start with. String -> Str() -> String. Macros? Really Macros? Bindgen doesn't work, exceptions are not handled properly, creating a thin layer between Rust and Ogre3D was seriously inconvienant.
I heard all of the hype, and I completely fell for it. This is not a language for game developers (35 years experience in game development here).
Oh, how about some simple data structures you need. Like developing dynamic graphs with pointers needed to and fro. What a serious PIA.
Realistically, do current practices even work for game development? Obviously many games are wildly profitable, but the amount of human suffering and crunch time that goes into the release of an AAA title, and indeed into its day zero multi-gigabyte patch to make it actually playable, seems to imply that we should at least be open minded. But also I suspect many of the issues aren't just your choice of language.
Crunch time has nothing to do with the language. We're not fighting the language. We're fighting last minute requirements, design changes, etc. My favorite that always happens, a complete change to the UI. I've never been on a project were it didn't happen.
Is it though? I feel like most people compare Rust to C++98 and if you do that, certainly Rust looks really good. The benefits of Rust compared to, say, C++17 are not as pronounced.
I'm try to not sound rude, but I don't think I can. Every C++ developer with even some significant amount of experience will identify this as bad code with one eye closed. Of course this looks wrong to someone that doesn't know the language. People freak out because it crashes your program, but in the end it's just a bug and producing bugs that are not obvious to someone that doesn't use the language much is very easy with every language.
I remember people prophesizing the end of C++ because of the introduction of string_views. When writing a text editor over a couple of weeks (a lot of text manipulation) I used string_views extensively and purposely over-used them (returned them a lot or kept them for a long time), because I wanted to see how dangerous they could be and I never got a bug/crash that was related to them. Of course you have to think about what you are doing, but you should be doing that anyway.
What I am trying to say is that while it's never "free" to not write bad code, if you get used to it, you don't have to think as hard about it, as you might think.
There are way more common examples of easy ways to break your code, like storing references/pointers to elements in vectors, which then resize or capturing objects in lambdas that get destroyed before the lambda is executed and stuff like that. Even out-of-bounds access to arrays/vectors is a lot more common than that, I think personally.
> People freak out because it crashes your program
People freak out because it _doesn't_ crash your program (until it's running in production of course). On my system without optimizations it prints "xyz" just fine, with optimizations it prints nothing, even though I'm accessing to the middle of memory. I think on most systems this will not actually crash unless you have explicit out of bounds memory tracking inserted into code by the compiler every access slowing down your code.
The point is in Rust this wouldn't even compile.
I'd be curious if you ran your text editor through a memory sanitizer like valgrind and how many issues it points out.
OK i'll bite. What's wrong with this? It functions as expected or am I missing something.
Edit: NVM, for those wondering the std::string constructor copies the string when it doesnt have to. But the solution here is to just initialize the string_view with the char data instead of the std::string instance
The issue isn’t anything to do with copying - the issue is that a string_view is a non-owning reference, and that std::string on the right side is an rvalue. Meaning that when you deref the char* in the string_view you’ll segfault or summon demons or something.
Try putting it inside another function and then return the string_view before printing. The behavior will be more interesting. The first time I got "V", then consistently "f" or "+" after that.
A lot of C++'s (and C's) memory "fun" doesn't readily appear when you're inside a particular function because the memory (like here) is on the stack. So your behavior within that function scope looks like what you want. Then you start returning values and, oops, something was a reference to memory on the stack. In which case it more or may not work depending on what else has happened between the value being placed on the stack and its use (I had to run a fun crash course for EEs on stack vs heap, when your only programming experience is a bit of Matlab this is not a topic you'll be familiar with).
Isn't it a use-after free? (I haven't had time to compile and run it)
You have a temporary std::string, pointed to by a string_view, which means that it's freed, and the view is dangling, and then used when printing things out.
UB can do anything, including something that seems like it works.
Just because the memory has been deallocated doesn't mean that the bytes there were changed. The pointer may still point to them, and it may still "work."
It's undefined behavior, so it'll literally print anything. On my system with my compiler version it'll print xyz without any optimization, but if I use -O3 optimization it prints nothing. But it could just as easily segfault or print garbage from memory.
Edit: If I move the first line into a function and return that string_view, then with optimizations it still prints nothing, but without optimizations it prints random varying garbage each time I run it, different each time.
Rust code has successfully been compiled and ran on every one of the current generation of consoles, and many older consoles too.
Now, many studios would want it to be directly supported by the console developers themselves, and that's obviously not a thing right now... but there's no technical limitations here.
Fundamentally different. ARC involves reference counting, and so is a run-time strategy. Ownership in Rust is at compile-time, instead.
Now, it is true that languages that use ARC can do compile-time analysis to remove some refcount traffic, and that you can use run-time ownership tracking in Rust if you'd like.
The difference is what's built into the languages, what is the default vs what is not, and the kinds of patterns those tend to enable.
It is not, no, although you can choose to have some types to be Arc. By default the compiler can reason about whether a value is accessed mutably in only one place.
I can’t imagine programmers wanting to use Rust for games development, especially when there are plenty of alternative languages.
And remember that Rust must go through an LLVM layer.
Instead, what about Nim? Any hopes for this language to become a mainstream games programming language instead? Since it does transpile down to C code.
When discussing games, where players demand excellent performance but are tolerant of initial startup times (i.e. launching the game from Steam or the Start Menu) being long, then I question why Java isn't the future.
By all accounts Java has the most sophisticated runtime out there, it has all the safety features of Rust without fucking around with the borrow checker which seems like a huge piece of complexity just to avoid garbage collection.
Plus, now that Mozilla has gutted the Rust team, one wonders what future Rust has, if any.
GC is a no-go, as it causes unacceptable frame-rate dips. The kind of people who buy 120Hz screens are unlikely to be impressed. Even Shenandoah etc. are very unlikely to fix that.
Advanced garbage collectors have short pause times. In [1], the author cites Twitter statistics showing approximately two 0.5ms "pause" times per GC cycle for the go language garbage collector, and during the GC cycle only 25% of the CPU was used by the GC. It doesn't seem like this is going to cause frame-rates to dip.
To be fair, every application is going to differ, and perhaps games need tighter control of memory than a high performance GC is capable of, but automatic GC does make programming a lot easier.
I play a lot of minecraft and GC related framerate issues are usually not a problem, but when they are a problem they can be quite annoying. You tune gc performance for your gameplay workload to a certain extent but obviously most players don't.
Those games will have been written in such a way as to avoid allocations like the plague, giving the GC very little to do. Sometimes your game can be written that way -- sometimes it can't.
First, you don't have to avoid malloc() or similar allocators in games necessarily. You should avoid it in performance constrained situations. And you only should avoid calling malloc. It's not necessarily a problem to use these allocations in those situations. That's quite unlike Java, unless you're a GC wizard, and I'm not sure how far even those wizards can circumvent problems.
Second, to my knowledge it's still very cumbersome to avoid GC allocations in Java. By comparison, it's easy to reduce calls to global heap allocators in C.
Yes/no, what hex-rays ida gives you is not worth the effort. It is a guess, and it doesn't do well with complex algorithms. Go try it on libjpeg. Compile it to release, no symbols, and let me know what you can extract. That is what I tested it with, and I didn't get much.
> Way back around 2010, Mozilla was frustrated by the state of development in Firefox, a massive software project written mostly in C++. Despite best practices
> Even so, manual memory manipulation is easy to get wrong,
Even predating C++11, you should not have been doing manual memory management. I don’t think Mozilla was following best practices. IIRC, there were pointers everywhere. Even before C++11 best practices for C++ were to try for value semantics as much as possible. Mozilla code base was more like C with Classes than best practice C++.
I think the criticism, “But you were writing C++ wrong” falls more than a little flat. The Firefox codebase may be old, but even with teams of good, experienced C++ programmers I still see memory errors of the type that Rust is designed to prevent.
Anyway, you are unlikely to avoid pointers completely in a good C++ codebase. Value semantics are very often the wrong semantics for the code you are trying to write. You can end up with dangling references as easily as you can end up with dangling pointers. If you use std::shared_ptr everywhere, then what you have is a slow & inefficient GC.
So what in the language prevented them from doing it that way? What in the community ensured they didn't do it that way? Firefox is open source, and yet it still happened.
"Best practices" is such a red herring. Best practices = don't write bugs, too; yet there are bugs. You can't evaluate a language in theory and ignore what happens in practice any more than you can with any other thing in life. It's the UX, does it do what users expect it to do, and is that the lowest friction path possible to achieve the goal. "You're not following best practices" is basically "you're holding it wrong". While arguably true, it is an attempt to excuse a bad design decision or impedance mismatch.
> "Best practices = don't write bugs"
That's absolutely not what it means. Best practices usually means "don't use these features anymore" and "use these features whenever you can". And that is very reasonable and DOES get rid of a lot of the problems (not all) that are usually associated with C++, but still people don't do it.
I blame it many C++-people actually preferring "C with classes" (various code bases openly prefers this as their coding style - you won't get those people on the Rust train either) and many people just don't know or don't trust it, because some of the newer features are sadly not very easy to understand properly.
You clearly missed the facetious tone of that part, along with the entire rest of the post.
So let me simplify - if to use a language correctly requires knowing the full history of the language, along with explicitly eschewing some of the key features of the language (except in certain cases when you need them! And they're not deprecated or issue warnings or similar by the compiler), and even extremely experienced developers using the language still make mistakes...the issue is with the language.
This is not a theoretical problem, it has been researched and the results are not encouraging even for "modern" C++.
Either some of the biggest software companies (Mozilla, Microsoft, Google) are all incompetent or there is a problem with C++ in the real world which still hasn't changed despite "you only need to follow best practices in C++".