HackerTrans
TopNewTrendsCommentsPastAskShowJobs

james7132

no profile record

comments

james7132
·9 ay önce·discuss
Zig has not hit 1.0 yet, and as recently as a few months ago completely reworked how every form of IO is written. AFAIK, this wasn't a syntax change, but it changed the function signature or type definition of every piece of code that reads/writes a file, establishes a connection, etc. At the current time, there is little guarantee that the code you write today will still work in 5-10 years time.
james7132
·9 ay önce·discuss
Once you understand that a crate is the translation unit in Rust, it doesn't feel as bad. Most medium to large Rust project's will separate out their code into separate crates for both organization and compile time.

I've definitely cloned down my fair share of C projects, mashed the make command into my terminal, and watched the gcc/clang logs fly by and never batted an eye beyond checking the sha256sum on any downloaded tarballs.

There's a valid argument to be made about supply chain attacks, but there does exist tooling to lock that down, and I would argue that any serious software development firm should be auditing every third party dependency they take on.
james7132
·9 ay önce·discuss
Not cart, but another maintainer of Bevy here.

More traditional game engines tend to be a giant tangle of pointers with much more complex lifetimes than what Rust's borrows would allow. For example, the skeleton used to animate your character is reliant on a centralized hierarchy of transforms, which is deeply interwoven with physics, rendering, gameplay scripting, etc. These relationships and lifetimes is difficult or impossible to model with Rust's borrows, forcing the use of unsafe, and makes it harder to expose safe Rust interfaces to engine users due to Rust's aliasing rules around borrows and essentially forces the use of a scripting runtime. These factors also make it very hard to make performant multithreaded code without littering locks or channels everywhere, in any language or runtime, not just with Rust.

Bevy's ECS handles this by flattening these relationships. Instead of pointer chasing through the physics system to fetch rigidbodies which then point to the transforms, you expose the backing ECS memory as a query view: `Query<(&mut Transform, &Rigidbody)>` directly fetches all entities that have the two components without relying on one to hold a reference to the other. The lifetimes of the queried components is strictly bound to the surrounding function (a system in ECS terminology) by the borrow checker, and all of the unsafe used to create those borrows is neatly packaged behind the ECS crate boundary. This is so effective that the majority of Bevy's crates can have `forbid(unsafe_code)` enabled.

The downside here is that all of the complexity is now centralized into the bevy_ecs crate: there are many parts in it that are basically C written in Rust, but that does mean that we can focus all of our memory safety efforts on that one crate instead of making that collective responsibility of everyone in the ecosystem.

Of course, we do expose unsafe APIs from the ECS, but the use of this escape hatch explicitly demarcated, and generally you'll only see incremental performance improvements (no big-O algorithmic gains) over their safe variants. With the sole exception of `Query::get_unchecked_mut` allowing parallel access to mutable components that cannot be proven to be safe from static analysis (e.g. parallel hierarchy traversals), which enables parallelism where it otherwise would not be feasible.