Update: when I wrote slow, I meant development pace, not runtime performance
Update: when I wrote slow, I meant development pace, not runtime performance
Such unfinished code can be obviously buggy and unsafe, but in game dev it matters more to have short feedback loop to try how things feel, than to have a perfectly correct code all the time.
Rust doesn't do quick and dirty, and will complain about code quality even when game devs don't even plan to keep the code.
This is a substantially different situation from other domains like application and services development, where it's easier to plan what you're going to implement, correctness is more important, and you don't need to try out 20 different JSON parsers to see which one has the most satisfying feel.
That approach gives you the best of both worlds: high-performance core with high-velocity iterations for gameplay. Don't use Rust or C++ for scripting... madness lies that way.
Such code is of course crappy, but the OP wants to test if things are fun before committing to implementing them properly. Rust wants things done properly on the first try (which usually is a good thing, except throw-away prototypes).
You can do very easily do quick and dirty in C++. (And shoot your foot off also..but that's a different thing)
Also supports is kind of relative,
"CHR is very new and experimental feature of the engine, it is based on wildly unsafe functionality which could result in memory corruption, subtle bugs, etc."
I also think that doc page is a little old. The feature is over 2 years old now and hot reloading is inherently "unsafe" in any compiled language. It's just letting you know that Rust's safety guarantees might go out the window if there are bugs in the code that handles hot-reloading.
Also that was only one example, there are other similar ones.
The problem might just be an aversion to using quick and dirty solutions. Rust does a good job of making it feel wrong to write code that's not production ready, but there's nothing stopping you from using unsafe wherever you want.
I've worked with Bevy, and there's it's incredibly easy to write "quick and dirty" to test stuff. I guess the major "downside" you need to account for is that the type system will try to prote you from crashes. Which can be a bit of a chore since youknow it won't crash with the values you've given it. But if you're comfortable with .unwrap and the occasional unsafe while prototyping, it's honestly fine (at least within Bevy).
Alternatively, they could try "scripting" behaviour first before implementing it in Rust, although from what I understand bevy's scripting support (I don't think it's explicitly supported, but bevy is very extensible) is still very early in development
If you add a scripting language and blueprints, you're shortening the feedback cycles by using Rust less.
I like Bevy, but it seems like Rust currently is much better suited for making game engines than the games themselves. Some "RustScript" is needed.
Can you elaborate? Or did you mean dynamically dispatched?
2. Bevy's entity references are generational IDs, without static lifetime guarantees (and restrictions) of Rust's references.
They do, they're `Entity`, always.
> where you can add and remove properties at will
I don't think this is true for either `Component` or `Entity` in Bevy. You set what fields a `Component` has when writing the code, then it remains so during the runtime. There is no dynamically adding/removing fields at runtime, at least yet.
What you do tend to do in Bevy is adding/removing `Component`s to `Entity`s at runtime, is that maybe where the confusion comes in?
Yes, technically, but in how they're used - no. They're a dynamic type.
> What you do tend to do in Bevy is adding/removing `Component`s to `Entity`s at runtime
Yes, this is dynamic typing. Or, at least, one way to look at it - and what allows games to be iterated on quick.
No, they're really not. Are you talking about Archetypes or something else? Because an Entity is just a ID + a generation, that's it. Nothing more and nothing less. You don't define them as more/less, nor do you use them are more/less either.
> Yes, this is dynamic typing. Or, at least, one way to look at it - and what allows games to be iterated on quick.
I guess a `Vec<u8>` is also then dynamic typing in your mind as you can add/remove elements to the vector? Doesn't really compute for me personally, but whatever floats your boat.
Many people here say that languages like Ruby or frameworks like Rails are dying, or some such, but in reality these languages just carve out their space, settle into it, and become the go-to choice because there's nothing surprising about them any more. If Rust can be considered stable or boring in this way then it will have succeeded where a lot of new and novel languages tend to fade into obscurity.
Outside very specific use cases, we already have Ada like safety on programing languages with automatic memory management.
Development time is absurdly faster, though, since you don't spend much time debugging annoying language-design bugs, and can focus entirely in your code's logic.
I don't mean to be dismissive, but if this was really true we'd all be writing TLA+ specifications/Coq proofs before finalizing our Ada SPARK implementations. In reality, static analysis only improves development time if time_lost_to_debugging > time_lost_to_arm_wrestling_compiler, and in my experience that's not always as common as one would like to believe.
That is if your code satisfies the borrow checker out of the gate, fine. I have seen Rust book authors get derailed for years by apparently simple seeming projects that do not.
What are you referring to here?
There are types in the standard library that, if you use them, do runtime checks. If you run afoul of those checks, then yes, you’ll get a runtime failure. (The primary example being RefCell<T> linked in the article linked there, yes.)
These types are not super common in Rust code generally, but they do exist and are useful at times.
Think of them like Python's metaclasses.
rust can be very frustrating because it forces you to think up front at a level of safety you may not be used to. That's the issue.
I do fairly simple things with rust (i.e. just some threads, no complex data structure (but complex program nonetheless)) and rust safety helps me a lot in reducing the number of bugs.
Sure, once you get your code to compile things may go faster. But getting there is not always easy.
Utter BS. I mainly developing in C++ at the moment (not limited to this single language though) and I do not find myself debugging "language-design bugs". I do not design libraries hence my code and set of used language features is of course simpler. I tend to avoid esoteric code and do not have habit to shove everything into new templates.
Edit: I just noticed that this article is also writen in the archival reason. I'll leave it here anyway for those that miss it.
It turns out that when you need to get the details right and be safe in a systems level language, development can be slow. This is a good thing. Studies with Ada projects compared to C have shown that time and money is saved in the long run due to fewer bugs and less maintenance. You just have to embrace that particular suck because it pays off in the end.