Required Components, Curves, and the Bevy CLI Working Group
2024-09-02
Welcome back to This Week in Bevy!
This week we've got some great progress on Scenes/UI work with Required Components merging, a new Bevy CLI working group, and some great progress in the Curves group.
We've also got some exciting crate releases including an official bevy_magic_light_2d crates.io release and a new Avian Pickup plugin for portal-like shenanigans.
Required Components
Required Components is part of the recent Scenes/bsn! work and has been merged! This has a huge impact on Bundle use cases, although Bundles have not gone anywhere. (note: do not worry, the team is putting great thought into how these APIs will evolve and this is the beginning work, not the end-state).
Required Components show up in end-user APIs as a require
attribute macro on Components
.
#[require(Node, UiImage)]
As is common when talking about work that was just merged, Required Components are a beginning step in the Next Generation Scene / UI Proposal so expect further work in this area before official release.
The most succinct way I've seen to show the difference Required Component makes is to show the impact on an existing bundle, like the ButtonBundle
.
#[derive(Component)]
#[require(Node, UiImage)]
struct Button;
commands.spawn((
Button,
Style {
width: Val::Px(100.0),
height: Val::Px(50.0),
..default()
},
FocusPolicy::Block,
));
Note that generally, required components are for invariants. That is, additional components that the component in question does not work without. This is especially relevant when considering library code but it is worth noting that as with any new functionality, the lines are still being drawn.
Meshlet software raster
meshlet debug output overlaid on a rendered scene
Meshlets see improvements in #14623, which includes work towards faster meshlet rasterization path for small triangles, avoiding having to allocate and write out a triangle buffer, and more. The PR is wonderfully documented and includes technical details for changes.
The MeshletPlugin
now comes with a cluster_buffer_slots
MeshletPlugin {
cluster_buffer_slots: 8192,
}
The rough tldr; on cluster_buffer_slots
is that it needs to be set to the worst case amount of clusters per pass in your scene over all cameras, which is a number that can obviously vary per-user. If you get the number wrong (as in, too low), you'll notice missing or flickering areas.
Observers
Debug for Trigger
#14857 introduces a Debug
implementation for Trigger
, which enables a more streamlined developer experience when debugging scaffolded Observers.
.observe(|e: Trigger<OnAdd, Skeleton>| {
dbg!(e);
});
The output includes the event information, propagation, and ObserverTrigger
.
on_add_mine: Trigger {
event: OnAdd,
propagate: false,
trigger: ObserverTrigger {
observer: 2v1#4294967298,
event_type: ComponentId(
0,
),
entity: 454v1#4294967750,
},
_marker: PhantomData<observers::Mine>,
}
on_unimplemented for IntoObserverSystem
Observer systems must have a Trigger
as their first argument and in #14840 the error message when this isn't the case includes a reminder.
for function
ObserverSystem
s, ensure the first argument is aTrigger<T>
and any subsequent ones areSystemParam
The Type type
#14838 introduces the Type
struct to bevy_reflect
. This type contains both the TypeId
and the TypePathTable
of the given type, allowing it to be used like TypeId
but have the debugging capacity of TypePath
.
Screenshots
As of #14833, screenshots can now use any RenderTarget
and have a new Component-and-Observer-based API.
use bevy_render::view::screenshot::{save_to_disk, Screenshot};
commands
.spawn(Screenshot::primary_window())
.observe(save_to_disk(path));
New Run Conditions
In #14917 two new Condition
s were introduced including:
condition_changed
, which changes whenever the inner condition changescondition_changed_to
, which returns true whenever the inner condition changes to match true or false, depending on user configuration
Plane3d Gizmo updates
As of #14650 the Plane3d primitive gizmo now displays as a grid to better show the existence of a plane. Previously it was axes which had some issues when trying to view distant or off-axis plane locations.
gizmos
.primitive_3d(
&Plane3d {
normal: Dir3::Y,
half_size: Vec2::splat(1.0),
},
Isometry3d::new(
Vec3::ONE * 4.0 + Vec2::from(time.elapsed_seconds().sin_cos()).extend(0.0),
Quat::from_rotation_x(PI / 2. + time.elapsed_seconds()),
),
GREEN,
)
.cell_count(UVec2::new(5, 10))
.spacing(Vec2::new(0.2, 0.1));
Binary Size Reductions
#14865 is a GitHub Discussion that takes a look at generic/monomorphized code to see where there could be some savings in final binary size by moving some code around without changing existing APIs. #14865 is the first follow up on this research by splitting GenericTypeCell::get_or_insert
up.
This work results in a 2% size reduction (approx 428KiB) of the final binary when building the 3d_scene
example.
Further work is happening in #14934 which is seeing even more improvements already (which we'll cover in the future when/if it merges).
atomicow
#11478 details the desire to shrink the bevy_utils crate and put the functionality inside it in better places. As part of this, CowArc
was moved to the new, generally usable outside Bevy, atomicow crate and its usage inside Bevy was replaced with the new crate in #14975.
CowArc
is an enum that represents owned, borrowed, or static data, that is: cheap immutable references that can be converted into an owned form when mutation or ownership is required.
pub enum CowArc<'a, T: ?Sized + 'static> {
Borrowed(&'a T),
Static(&'static T),
Owned(Arc<T>),
}
IMO: It should really have an atomic cow logo... :laughing:
Working Groups
bevy_mod_picking: the upstreamening
#14757 adds a sprite backend to the upstreamed bevy_picking
and adds a new example in examples/picking/sprite_picking.rs
showing off the functionality. Go click some bevy birds!
Curve Crew
New curve gizmos have been added for 2d and 3d in #14971 based on the previous bevy_math Curve
work.
As of #14815 you can now sample curves from IntoIterator
types. This allows sampling a curve at specific times t
.
let times = [-0.5, 0.0, 0.5, 1.0, 1.5];
let finite_curve = function_curve(Interval::new(0.0, 1.0).unwrap(), |t| t * 3.0 + 1.0);
let samples = finite_curve.sample_iter(times).collect::<Vec<_>>();
let [y0, y1, y2, y3, y4] = samples.try_into().unwrap();
assert_eq!(y0, None);
assert_eq!(y1, Some(0.0 * 3.0 + 1.0));
assert_eq!(y2, Some(0.5 * 3.0 + 1.0));
assert_eq!(y3, Some(1.0 * 3.0 + 1.0));
assert_eq!(y4, None);
clap
bevy_cli: please A new working group dedicated to building a Bevy CLI has been created! The working group's initial scope can be found on hackmd and includes a bunch of relevant information. Give it a read if you're interested in what a Bevy CLI might look like!
The working group's discussions can be found in the official Bevy Discord, as can be all of the other working groups.
Alice's Merge Train is a maintainer-level view into active PRs, both those that are merging and those that need work.
Showcase
Bevy work from the #showcase channel in Discord and around the internet. Use hashtag #bevyengine.
Vehicle Physics
showcase
Early progress on a vehicle physics demo. It currently involves the forces needed to drive the car back and forth with steering.
Collide and Slide: Avian Physics
showcase
If you implement enough character controllers, you'll eventually come across the term "Collide and Slide". Functionally, this means when your character hits an angled wall it shouldn't stop, but rather continue sliding along that wall.
The goal of this project is to make an FPS example project that others can learn from and today's showcase is the collide-and-slide implementation.
Dr Luke's VJ Set
showcase
We've previously covered Dr Luke's VJ set, which now has a full recording uploaded on YouTube to enjoy.
Pokemon-style Shooter
showcase
This scene in this Pokemon-style shooter has about 770,000 faces. The loading time is about 16 seconds and there are some great comments about serializing the computed colliders to optimize that loading time.
Ominous, Brutalist Building WIP
showcase
This ominous, brutalist building is being loaded using Qevy from a Quake .map
.
Spore-like Creatures
showcase
These spore-like creatures are procedurally created (inspired by this talk), and use 3d segments of a cylinder on particles, which will make more sense if you watch the talk.
Top Down Shooter
showcase
Progress on this top-down shooter which uses gizmos instead of meshes to focus on the game logic. It started off with the bevy quickstart template and continued with a basic character controller, 2D rotation and Avian Physics Colliders and RigidBodies
4x terrain
showcase
Terrain generation for this 4x game was recently overhauled including the author's first wgsl shader.
Crates
New releases to crates.io and substantial updates to existing projects
bevy_capture
crate_release
bevy_capture
is a plugin for capturing frames from a Bevy application. It comes with some built-in encoders, e.g. for creating gifs or videos, and can be extended with custom encoders.
bevy_web_popups
crate_release
bevy_web_popups
enables alert boxes on the web and on phones. That means you can use alerts with or without text boxes using a unified API across platforms.
fn bevy_system() {
alert("important msg");
show_textinput("set nickname:", "ok", "cancel", true);
}
// system processing events coming from the web plugin
fn process_events(
mut events: EventReader<WebAlertResponse>,
) {
for e in events.read() {
if let WebAlertResponse::InputOk(text) = e {
info!("user confirmed with text: {text}");
}
}
}
Bevy Foliage Tool
crate_release
Bevy Foliage Tool crate allows you to set height maps on a Foliage Scene, then paint density on foliage layers (each corresponding to one type of foliage) using events. Instanced mesh entities are spawned in chunks (for render distance occlusion) based on the heightmap + density + noise
avian_pickup
crate_release
Avian Pickup is a plugin for picking up, manipulating and throwing dynamic RigidBody
props in Avian Physics.
Pick up nearby dynamic rigid bodies, pull far away ones towards you, and throw them around or drop them gently.
bevy_magic_light_2d 0.8.0
crate_release
bevy_magic_light_2d is a dynamic 2D global illumination system for Bevy, based on SDF ray-marching and screen space irradiance cache probes.
Two new maintainers have been added to bevy_magic_light_2d
(congrats if you're watching) and they've put in work to get a 0.8 release out for Bevy 0.14.1. This is effectively the first official crates.io release for the library, even though the code has been around awhile and powers the lighting in Jarl.
Refactor `AsBindGroup` to use a associated `SystemParam`. authored by tychedelia
bevy_reflect: Add `Type` type authored by MrGVSV
Implement `std::fmt::Debug` for `ecs::observer::Trigger` authored by Sorseg
Add `AnimationGraph::from_clips` and simplify `animated_fox` example authored by rparrett
Rename `Commands::register_one_shot_system` -> `register_system` authored by benfrankel
Replace the `wgpu_trace` feature with a field in `bevy_render::settings::WgpuSettings` authored by LikeLakers2
Make ActiveAnimation::set_weight return &mut Self authored by aecsocket
Fix Gizmo joint rendering in webgpu authored by akimakinai
SystemParamBuilder - Support dynamic system parameters authored by chescock
Added `on_unimplemented` Diagnostic for `IntoObserverSystem` authored by bushrat011899
Simplify render_to_texture examples authored by IceSentry
Rewrite screenshots. authored by tychedelia
Fix underflow panic in `InitTriInfo` authored by kumikaya
Make the field of `ParamSetBuilder` pub so it's actually usable. authored by chescock
Fix tiny seam in Annulus geometry. authored by komadori
Add `VertexBufferLayout::offset_locations` authored by SludgePhD
Add `condition_changed` and `condition_changed_to` to `common_conditions` authored by Azorlogh
add `Interval::UNIT` constant authored by RobWalt
rename Drop to bevy::picking::events::DragDrop to unclash std::ops:Drop authored by kivi
Add methods to sample curves from `IntoIterator` types authored by RobWalt
Fix `arc_2d` Gizmos authored by RobWalt
Have EntityCommands methods consume self for easier chaining authored by Luminoth
Split `GenericTypeCell::get_or_insert` into smaller pieces authored by bushrat011899
Add bevy_picking sprite backend authored by jnhyatt
ImageSampler::init_descriptor authored by stepancheg
Meshlet software raster + start of cleanup authored by JMS55
Allow removing asset from embedded asset registry authored by extrawurst
Required Components authored by cart
don't use padding for layout authored by mockersf
drop pending asset loads authored by robtfm
Fix Adreno 642L crash authored by sampettersson
Fixing Curve trait not being object safe. authored by eckz
SystemParamBuilder - Support buildable Vec parameters authored by chescock
Commands::send_event authored by robtfm
Fix query transmute from table to archetype iteration unsoundness authored by SkiFire13
SystemParamBuilder - Enable type inference of closure parameter when building dynamic systems authored by chescock
Use `Isometry` in `bevy_gizmos` wherever we can authored by RobWalt
Remove unnecessary muts in `RenderSet::QueueMeshes` authored by AllenPocketGamer
Updated `FromWorld` Documentation to mention `Default` authored by bushrat011899
Gizmos: `arc_2d` utility helpers authored by RobWalt
SystemParamBuilder - Allow deriving a SystemParamBuilder struct when deriving SystemParam. authored by chescock
Make TrackedRenderPass::set_vertex_buffer aware of slice size authored by akimakinai
Improve the gizmo for `Plane3d`, reusing grid authored by RobWalt
Move the default LogPlugin filter to a public constant authored by Luminoth
`Curve` gizmos integration authored by RobWalt
Remove some asset examples from web showcase authored by akimakinai
Fix compile error caused by incorrect feature flag in `bevy_state` authored by BigWingBeat
Fix observer unregistering unsetting archetype flags authored by Azorlogh
Use CowArc::Static authored by akimakinai
Reorganize some of `bevy_animation`'s imports into a more consistent style authored by LikeLakers2
Migrated `NonZero*` to `NonZero<*>` authored by bushrat011899
Replace `bevy_utils::CowArc` with `atomicow` authored by chrisjuchem
Don't require going through `bevy_animation::prelude` to get to certain items in `bevy_animation` authored by LikeLakers2
Ensure more explicit system ordering for preparing view target. authored by tychedelia
Want to contribute to Bevy?
Here you can find two types of potential contribution: Pull Requests that might need review and Issues that might need to be worked on.
Pull Requests Opened this week
Hide `fixed_update` behind a feature flag authored by Lubba-64
Adopt #9770: `Result`ify `Camera` methods authored by RobWalt
Remove sparse set in Table storage authored by cBournhonesque
Add `run_system_cached` API authored by benfrankel
Safer dynamic event handling for observers authored by ItsDoot
`TrackedRenderPass` internal tracking state reset authored by PPakalns
Resolve UI outlines using the correct target's viewport size authored by ickshonpe
Various De-Bloating Optimisations authored by bushrat011899
Migrate `bevy_transform` to required components authored by ecoskey
Use `#[doc(fake_variadic)]` for `SystemParamBuilder` tuple impls. authored by chescock
Ignore clicks on uinodes outside of rounded corners authored by ickshonpe
Color gradient curve authored by RobWalt
Asset SIMO/one-to-many PoC authored by MScottMcBee
Reflect `SmolStr`'s `Deserialize` implementation authored by bushrat011899
Interpolate `WorldQuery` path in docs of generated types authored by no-materials
Updated `LogPlugin` Documentation with Performance Warning authored by bushrat011899
Return `Result`s from `Camera`'s world/viewport conversion methods authored by chrisjuchem
Split Main world and Render world Entity space authored by re0312
Improve schedule note of .after/.before & encourage to use .chain ins… authored by kivi
Reduce allocations in ui_layout_system authored by UkoeHB
Don't reallocate scale factors in measure_text_system authored by UkoeHB
Reuse TextLayoutInfo in queue_text authored by UkoeHB
Gizmos Billboards authored by lynn-lumen
Use cosmic-text shaping buffer authored by UkoeHB
UI texture atlas slice shader authored by ickshonpe
Issues Opened this week
Linker error 1189 when building a clean project with dynamic linking enabled. authored by Syst3mz
Add support for alpha-testing in sprite picking backend authored by alice-i-cecile
Support Overriding Required Components at Runtime authored by omaskery
`IntoObserverSystem` is implemented for any `IntoSystem`, but observers actually only work with non-exclusive systems authored by SkiFire13
Observers get a `'static` `Trigger` and that's unsound authored by SkiFire13
UI outline geometry is always resolved using the size of the `PrimaryWindow` regardless of target authored by ickshonpe
UI ninepatch border geometry should match the borders in the layout (maybe) authored by ickshonpe
Camera2dBundle doesn't apply Transform authored by KamyaPA
Don't count picking hits on button rounded corners authored by alice-i-cecile
ID3D12CommandQueue errors cause blank screen and error spam authored by redstonerti
"Editor-Like" AssetSaver example authored by viridia
Optional `SystemParam` (especially gizmos) authored by Aceeri
Change Detection Logic Bug in Point/Spot Light Frustra Update authored by coreh
Bevy doesn't build on macOS authored by lynn-lumen
Incorrectly rendered border radius authored by ickshonpe
System ambiguity CI is too verbose authored by alice-i-cecile
Broken doc links in querydata derive macro authored by BigWingBeat
Border fills node and ignores radius for wasm32 authored by oscrim
SmolStr doesn't have ReflectDeserialize authored by UkoeHB
Warn users that runtime log filtering can be expensive authored by alice-i-cecile
Consider making check for unregistering observers faster authored by alice-i-cecile
use custom material 2d, with same logic draw part of texture, get different result with wgpu. authored by alexniver