I was wondering if there is any low hanging fruit for WebGL build size improvements.
I did a Unity test build for comparison against your rect example, with a cube and a single script that does nothing (so they can't e.g. strip out Mono).
Listing sizes uncompressed, 7z Ultra (a decent proxy for Brotli), and wasm-opt + 7z Ultra respectively:
Rect example: 13473kb, 1964kb, 1720kb
Basic Unity: 9528kb, 2304kb, 2291kb
Bevy is still leading, but it's getting uncomfortably close.
The uncompressed sizes matter a lot more than any other asset type, as it's all code that has to be compiled, running poorly until the optimized compiler has finished with it. On a Chromebook, my experience is that much code gives you 30-60s of poor FPS before it comes good.
I understand this is not necessarily a focus of Bevy, but I do think that you have an opportunity here to build the first game engine without significant downsides on any single platform. Filling the code base with a bunch of feature flags may not be worth it to achieve that goal, though.
The modularity of Bevy is super exciting (I've asked you before about WebGL builds on here before and you mentioned this). But Unity ships quite a bit of stuff in a basic build and is probably fairly similar in scope to Bevy with all crates.
I've been sponsoring for close to a year, but haven't kept up with the Discord in many months. Currently I'm just been checking for updates every couple of weeks, and sometimes checking the state of GitHub issues and milestones.
However, is there any better way for me to keep up with progress? If not, has there been any thought about having regular status updates? They don't have to take a lot of your (or someone else's) time, but just a few sentences on what's been decided, what's happened, etc, would be nice! Once every 30 or 60 days would definitely be enough.
Going forward, we will be doing a curated This Month In Bevy newsletter. We've had templates in draft mode for awhile, but getting 0.6 out the door has taken precedence. I'd like to release our first newsletter this month!
That's great to hear! Thank you for all the hard work, I'm looking forward to see Bevy grow, and really hope it'll end up becoming a worthy competitor to Unity/UE/Godot for commercial games some day!
I spent a few days making a (very) basic 2D game engine in Rust for fun. One thing I found is that I didn't find Rust that helpful in preventing bugs due to the nature of game engine code. For instance, I was using a generational array to store components. At some point I had a use-after-free bug in the generational array code that the Rust compiler could never catch. Also, components tend to have circular references to one another, which was very annoying to program in Rust. I'm curious if you've experienced something similar and what your thoughts are now, after many months in the trenches, on Rust's suitability for a game engine.
Although I'm not _cart, I had a similar experience in making a (hobbyist) 2D game engine both in Rust and C++, and the problem you're facing (similar to the ABA problem) is not a memory safety error but more of a logical bug inherent in naively programmed object pools and is totally language-agnostic. When you create an object pool as Vec<Option<T>> and use a single array index as resource IDs, you risk this scenario: "X has a reference to resource A from object pool, A is destroyed and later reused by the object pool for resource B, now X has a reference to resource B". The problem is that the resource IDs will become invalidated as the object pool reuses its slots. The incremental generational counter is a way to check object lifetimes in object pools at runtime, and this is a solution to a logical error (which can be applied regardless if your language has a borrow checker or not). If you've had weird errors while using generational arrays, chances are that 1) you've exhausted your generational counter and it has overflowed 2) your generational array code is incorrect.
The verdict: Rust's lifetimes does not make you safe from non-memory-safety related bugs. It still gives you some really powerful abstractions to fight these bugs (like enums, traits, Option<T> and Result<T, Err> types), but other than that you're on your own.
(About circular references between components... doesn't this also get solved by generational indices? With Arc<T> types you're going to have circular dependencies that don't get freed because of reference counting, but with generational indices you're free from that issue since you're manually managing resource lifetimes anyway. And if you're having trouble figuring out how to manage these dependencies, the solution might be to refactor your code. My experience of using generational arrays was that it will naturally move your code-base towards centrally managing resources in a unified fashion, which is rather different than the usual Rust/C++ model of every object having its own independent ownership. After embracing it I tend to have less of those resource management dependency headaches.)
I want to point out to unfamiliar readers that use-after-free in a rust generational array is a logic bug, where as use-after-free in just about any other non-rust context is undefined behavior. Rust's safety is helping here, not by preventing the bug altogether, but by severely limiting the damage it can cause.
Congrats for the release, looks great! Not a criticism, but model projected shadows (not prebaked on lightmaps) are very jagged or really low-res, reminds me of early Unity shadows. I know Unity worked hard to improve them for years and acquired experts on shaders, because users complained and even moved to Unreal for that reason alone. Not sure if there are now well known solutions to get highly defined shadows, but I'm curious on your plans to improve them.
Yup shadows are notoriously difficult to make pretty in all situations. Fortunately we do have a number of "shadow quality" improvements in progress: https://bevyengine.org/news/bevy-0-6/#more-renderer-features. And we'll probably be improving shadows indefinitely from now on. The tech in that space is constantly evolving.
I'd like to see irregular Z buffers deployed in a modern graphics engine, as they actually provide pixel-perfect shadows without the need for raytracing hardware. They're pretty experimental, though. Maybe I'll take a stab at implementing them in Bevy sometime :)
I'm using Rend3 for a Second Life/Open Simulator client.
The current system with Rend3 has one thread doing nothing but refreshing the screen, while other lower-priority threads are independently changing the scene based on incoming messages from the network. Is that something the Bevy architecture can handle? Should I consider switching to Bevy?
Pipelining allows rendering and app logic to run in parallel. You can adapt to changes from the network when the app logic runs, so in that sense, it seems like a good fit. And you can use bevy_tasks to spawn background tasks (and spawn tasks across different thread pools, if that is required). I think it is worth considering Bevy, but I also think Rend3 is a great piece of software. We discuss rendering with that project's lead constantly :)
Looks really nice! If one was to implement a simple "3d arcball rotator" viewer for 3d formats to get familiar with the engine (i.e. load obj, view) can you suggest which examples would be most relevant (presuming bevy architecture is the only unfamiliar topic here)?
I noticed the short section on changes to Bevy's UI. I expect both GPU rendering and ECS will be important capabilities to consider for new GUI systems, and Bevy does both well. How do you imagine Bevy fitting into the budding Rust GUI story a la https://areweguiyet.com ? An entrant itself? The backend for one? Would you consider pure GUI applications an important use-case for Bevy now, or perhaps some time in the future?
So, I'm not Cart, but I'm a major contributor. My vision for this is as both an entrant and a logic-backend for GUI. In terms of use cases, I expect that: games > servers > scientific simulation > pure GUI, but all four are something we're trying to be actively mindful of. Accessibility matters, but native-look-and-feel is effectively a non-goal at the engine level; there's a lot of other frameworks that can provide this and cross-platform unification is more important.
We're planning to follow Godot and dogfood the UI to build out the editor, so support for pure GUI applications is something that we'll be actively testing.
If I'm a dev looking at engines to use, would now be the time to jump to Bevy, or is there expected to be significant changes to API and data structures moving forward still?
Things have started to stabilize, but unless you're willing to get your hands dirty and deal with regular breaking changes, I don't yet recommend staking your livelihood on it. That being said, by the end of the year I think we will be _much_ closer to our first stable release, and I expect the number of "serious projects" adopting Bevy to increase throughout the year. Now is the right time to start _evaluating_ Bevy for future projects (and experimenting with it).
Thanks for your work. What is the support for low-end and mobile devices? I have tried developing with bevy on my old macbook with an Intel Iris graphics card, maybe not ideal but that is what I have and I want to support most hardware. Last time I tried the simple cube example made my fans spin. Is this something that can be alleviated?
We support low-end devices well (although this is a constant balancing act)! Bevy runs well on iOS currently (and we have WIP Android support ... we're working on re-enabling that asap). Fans spinning is a known issue, but it is generally decoupled from framerates (which tend to be fine). On some machines we are over-engaging cores, even with empty apps that do nothing ... my current theory is that we need to adjust how our task pools are managed.
iPhones have insanely performant GPUs for the form factor. I wouldn’t be surprised if the newer ones get better performance in Bevy than a lot of perfectly usable laptops.
I haven’t tried bevy, so this question may sound naive. Does the new renderer support shadows for 2d rendered games? Something I’ve played around with in Godot and can look quite nice.
Also, I tried to search for the answer to this: is there any information on ways to make a game build with bevy moddable?
I can't speak for cart here, but from my perspective as a contributor to `bevy`, it's extremely useful having freedom from backwards compatibility concerns to improve our APIs.
For example, we want to rework our input handling, asset handling and UI; supporting this current UI solution indefinitely would be frustrating when we hope to make something much better once we can focus on that. As an example of this, we massively changed our rendering APIs for this release, allowing the improvements listed in the blog post to be implemented.
I wondered why the Rust community seemed so averse to 1.0 releases, but Rust for Rustaceans makes the interesting point that there are a lot of cases in the Rust language where adding new features technically qualifies as a breaking change. There doesn't seem to be a lot of room for the minor version number - everything is either a revision or a major release, and people aren't ready to commit to that level of strictness until they're feature-complete.
I was wondering if there is any low hanging fruit for WebGL build size improvements.
I did a Unity test build for comparison against your rect example, with a cube and a single script that does nothing (so they can't e.g. strip out Mono).
Listing sizes uncompressed, 7z Ultra (a decent proxy for Brotli), and wasm-opt + 7z Ultra respectively:
Rect example: 13473kb, 1964kb, 1720kb
Basic Unity: 9528kb, 2304kb, 2291kb
Bevy is still leading, but it's getting uncomfortably close.
The uncompressed sizes matter a lot more than any other asset type, as it's all code that has to be compiled, running poorly until the optimized compiler has finished with it. On a Chromebook, my experience is that much code gives you 30-60s of poor FPS before it comes good.
I understand this is not necessarily a focus of Bevy, but I do think that you have an opportunity here to build the first game engine without significant downsides on any single platform. Filling the code base with a bunch of feature flags may not be worth it to achieve that goal, though.
The modularity of Bevy is super exciting (I've asked you before about WebGL builds on here before and you mentioned this). But Unity ships quite a bit of stuff in a basic build and is probably fairly similar in scope to Bevy with all crates.