A year of bevy, past and future
Recently, bevy celebrated its third anniversary.
I (Nicola) started using bevy around November 2021. This was under the impulse
of our project mushroom prototype. Since then, I invested myself more and more
in bevy. I contributed large features such as morph targets and
parallax mapping, and I created useful plugins such as
bevy-debug-text-overlay
, bevy-scene-hook
, and cuicui_layout
.
I also take a lot of time reviewing and giving feedback on community-provided pull requests. During the last 12 months, according to GitHub, I submitted 200 PR reviews on bevy projects and opened 90 pull requests. This means I am responsible for 5% of all bevy PRs in the past year, and reviewed 10% of them (though GitHub might count multiple reviews on the same PR).
How did bevy evolve in the past 12 months?
I’m spending way too much time on bevy for my own good. While my wallet doesn’t thank me for that, I have a clear idea of the health of the project.
So let’s share here what I see.
Code reviews
I was impressed at the speed at which bevy was capable of processing pull requests and integrate them. However, in the past three months, I see a drastic slowdown in PR reviews. I think a lot of active members are focusing on other things currently and don’t have as much time to review code.
It’s a shame, because this is blocking amazing features such as:
- Cosmic text integration
- GPU picking
- System stepping (aka: time machine)
- dynamic queries (aka: efficient script queries)
- archetype invariants
- batched queries (aka: SIMD query iters)
I’m also frustrated with the snail pace at which my own PRs gets reviewed. It’s sad to open a PR or design suggestion and get no feedback on it for several weeks.
I’ve no solution for this. I review a lot of PRs and it’s not enough to compensate the PRs I open! The only option I see is a call to action: please review bevy PRs, it will make bevy move much faster, and it might attract more contributors who themselves may become reviewers in time.
Rendering
I’m extremely surprised at the insane speed at which bevy’s renderer progressed in the past twelve months.
I’ve no background in graphic programming, yet my most meaningful contributions to bevy are rendering features.
This is thanks to Rob and James, and their excellent support in introducing me to bevy’s gnarly rendering system.
Yet, I think anyone who worked on bevy’s rendering system understands how complex and error prone the code is:
I wrote down in the bevy GitHub discussion forum a “guide” on how to navigate the render code, but it’s still incomplete and glosses over major concepts.
UI
bevy_ui
has been seeing steady improvement in the past few months thanks to
ickshonpe. Current day bevy UI might look bad, but you don’t realize how
awful it was 12 months ago, especially looking at the internals. Thank you
ickshonpe for improving bevy_ui
internals! It’s a very thankless work, they
deserve the shout out.
A bevy of bevy plugins exists to make handling UI easier. I’m personally
responsible for a few of those. Recently, lumex and cuicui_layout
came
out. Both try to abstract UI from UI rendering. I think it’s a viable path.
Re-using the sprite renderer also has the advantage of culling a lot of
duplicate code.
It’s also important to note bevy-ui-dsl
. It was a breakthrough in bevy UI
declaration ergonomics, cuicui_dsl
is mostly derived from bevy-ui-dsl
.
Performance
Performance and code size has been steadily declining in the past 12 months. It’s currently difficult to know how much performance impact your PR has, and it’s currently too burdensome to benchmark changes outside of perf-focused PRs. We need to have better benchmarking (or any benchmarking at all) in order to avoid the trap of steady bloat and perf decline.
Other engines fell out of relevance partially due to this kind of bloat. This is a threat to bevy and we should be careful to avoid it.
What’s next for bevy
UI
I suspect bevy is going to see a lot of change in UI in the near future.
ickshonpe has been doing stellar work on bevy’s UI.
IDEDARY ported their longstanding game UI toolkit recently to bevy.
I broke ground on cuicui_richtext
and started work on cuicui_layout
.
Cart mentioned they want to focus on UI next.
I really hope we get an ECS-based solution for UI state. The only difference between storing state in the ECS and passing state to a sort of react/tauri-like framework is that you won’t be able to query UI state outside of UI code.
My wish list for UI is:
- Easy, hot reloadable, UI declaration syntax. Should have the ability to integrate with rust logic, while not itself containing logic (so that it is hot-reloadable)
- A rust-based UI declaration API with good error messages and trivial
layouting algo, such that it’s easy to know the end result from the code
(yes, this is the
cuicui_layout
tagline) - Tool to build visually a UI. But the tool in question should follow closely the UI declaration syntax
- Debugging tools similar to
cuicui_layout
- A way to use UI with sprites, and maybe within 3D worlds if possible. (also
a
cuicui_layout
tagline) - Good integration in ECS, so that interoperability between bevy systems and
the UI are trivial (I have in mind the
cuicui_bevy_fab
query system). - Way to also define logic based on inlined rust code (not sure why people think it’s mutually exclusive with bevy systems)
- Amazing richtext module (
cuicui_richtext
cough cough) - Setting up gamepad and keyboard-based UI navigation without headaches.
What's the plan for your UI crates?
bevy-ui-navigation
should be split up, so that it focuses entirely on
keyboard/gamepad driven navigation, and leave pointer-based UI to other crates.
cuicui_richtext
is on hiatus. Its scope has exploded and I’m not sure what the
way forward is.
I’m still working on cuicui_layout
. I’m working on an even better debugging
view, with more detailed text information on container state. A hot-reloadable
UI declaration syntax is on the roadmap.
Currently I’m taken up in other duties and progress on those crates are stalled for the next month or so.
Reflection
I also see a lot of potential for reflection. Currently it depends a lot on
rust’s trait objects. This is safe and easy to validate. But I see a future
where bevy_reflect
works on a much lower level, leveraging pointer offsets
and memory layout.
This would make bevy_reflect
viable on a much broader set of use cases. I
suspect it could help us reduce the binary size of bevy apps, as a lot of the
code size (10%) are instantiation of generic functions, such as FromType<T>
and App::init_resource
. Hopefully we can move most of the code into erased
function that works on bits rather than specific types.
My wish list for reflection:
- Dynamic queries: makes it possible to construct in non-rust code queries,
submit them to bevy and get
&dyn Reflect
in response. - Offset-based field dereference. So that accessing a field of a struct is literally as efficient as just doing it in rust. Currently it calls a dynamic trait object method. With path-based reflection, it may do it several times.
- Fast, efficient World se/deser based on reflection. I designed
bvyfst
as a testbed for a max performance bevy scene format, but it requires deriving additional stuff on components. - The Unique Reflect RFC is implemented.
What's up with unique reflect?
The Unique Reflect RFC is more a set of guidelines on how to think and
document bevy_reflect
features. I’m already satisfied with it, in that it has
been helpful to bevy contributors to design and document their code.
Rendering
There is still two major rendering PRs open: PCF shadows and light transmission. They will be merged quickly before 0.12. Those are amazing features to have!
Otherwise, I think it’s time to rethink bevy’s rendering system. Griffin worked on a deferred renderer for bevy. JMS55 have been considering ways to simplify our gnarly rendering systems. My personal wish list is:
- A less indirect rendering approach, make obvious when rendering code runs
- Shortcuts for bind group & bind group layout creation. Currently, most of the rendering code is bind group creation boilerplate.
- Better handling of shader defs. We could track what bind group layout each shader def requires, so that errors are more easily surfaced.
- Vertex attribute generation. This is a requirement for arbitrary morph targets.
- Better error messages. I suspect keeping track of bind groups, entity and comparing them to the shader of render pipeline would be very helpful. But in a prefect world, we would track and tell the users which line (in rust and their shader) is causing the error.
Strangely, I have the presentiment that such improvements are dependent on better understanding of what would make a great bevy UI framework, and better reflection.
Why I'm not working on adding parallax mapping to the prepass
Ideally we run parallax mapping in the prepass. We would update the depth buffer so that shadow mapping, TAA, SSAO, and proper object occlusion follows the visuals of the geometry with parallax mapping applied. But parallax mapping is fairly costly, and running it once per shadow-casting source, and bloating the perpass with it is bad.
Editor
The editor is blocked on better UI. There has been a lot of discussion on the editor. Whether it should use IPC or be an in-game bevy plugin. What design guidelines to follow, etc. However, for my part, I refuse to partake in such speculative discussions before the UI story is resolved.
I designed the klod editor so I may comment on it. To me, the Klod editor was useful because:
- It let me place visually objects in scenes, fixing up at the last minute levels I designed in Blender.
- I could extend it to bring my own key mapping (I prefer Blender’s keymaps)
Gizmos
Bevy’s gizmos are still very limited. As a result, gizmos from one plugin do not play well with gizmos from other plugins. As more crates adopt gizmos, we might see more and more conflicts. My amazing gizmos tracking issue is already a wish list, so I won’t write one here.
The bevy book
This has been cooking forever and it’s a major failure of the project IMO. But we finally started work on it, and I’m expecting to see an amazing high quality guide for newcomers taking shape in the next 12 months.
Bevy CI
I think bevy has now outgrown the capabilities of GitHub CI and needs dedicated CI hardware. I would love to see a bevy build server for the following reasons:
- Faster CI for PRs & merges. Faster site deployment, all the goodies!
- Regular benchmarks to track bevy’s performance and compiled binary size. We do love graphs, let’s make graphs.
Rustc has an excellent benchmarking setup, and it would be lovely if we had a similar one.
In short
Bevy has been moving forward at an incredible pace. The only negative thing I can say about it is that it didn’t move even faster. It’s already an incredible pace because it’s far beyond any expectation. So it would be ridiculous to complain about it not being faster.
I have nothing but positive things to say of cart and the community. Just “let’s go!!!”
And remember, please review bevy PRs!!!!!