mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
main
163 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cb02e96b6d |
Move bevy_window, bevy_input_focus, custom_cursor features to alternate feature collections (#22488)
Related: Cargo Feature Collections
https://github.com/bevyengine/bevy/pull/21472
## Context:
> If `default_app` is meant to be
> > The core pieces that most apps need. This serves as a baseline
feature set for other higher level feature collections (such as "2d" and
"3d"). It is also useful as a baseline feature set for scenarios like
headless apps that require no rendering (ex: command line tools,
servers, etc).
>
> why should `bevy_window` / `custom_cursor` be there? I would expect
these to be in `common_api`.
\- Me,
https://discord.com/channels/691052431525675048/692572690833473578/1460424003486224517
> Imo this is a mistake. Can you open a PR with a migration guide
please?
\- Alice,
https://discord.com/channels/691052431525675048/692572690833473578/1460429142376845404
## Solution
- <strike>Move `bevy_window`, `bevy_input_focus`, `custom_cursor`
features from `default_app` collection to `common_api`</strike>
- From `default_app` collection move: `bevy_window` to `common_api`,
`bevy_input_focus` to `ui_api`, and `custom_cursor` to
`default_platform`.
## Testing
- Did you test these changes? If so, how?
Confirmed that `default_app` collection no longer introduces the crates
to the dependency tree:
```sh
$ git checkout bevy/main -q
$ cargo tree --no-default-features -Fdefault_app -e normal | grep -e bevy_window -e bevy_input_focus -e custom_cursor
├── bevy_input_focus v0.18.0-dev
│ ├── bevy_window v0.18.0-dev
├── bevy_window v0.18.0-dev (*)
├── bevy_input_focus v0.18.0-dev (*)
├── bevy_window v0.18.0-dev (*)
$ git checkout reduced-feature-group
Previous HEAD position was
|
||
|
|
c757497b27 |
Gate LTC LUTs behind a feature and merge them to a texture array (#24065)
# Objective Alternative to #24004. https://github.com/bevyengine/bevy/pull/23288 adds ltc luts for rect light support which implicitly requires `bevy_image/ktx2` and `bevy_image/zstd` otherwise loading ltc luts will panic. We either accept to always enable area light supoort (#24004), or add a feature to opt out it (this PR). ## Solution Gate ltc luts behind a feature and merge them to a texture array. ## Testing `rect_light` example works. --------- Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com> |
||
|
|
ba7b3c8950 |
Rename bevy_experimental_feathers feature to bevy_feathers (#24108)
# Objective > With the introduction of scene components, the feathers API has now reached its final form. This has a number of consequences: > - There's no longer any reason to keep the experimental flag around > - The effort of migrating the Bevy examples to feathers widgets is unblocked, however I think we should start with migrating just one example - @viridia ## Solution 1. Rename the feature flag. 2. Write a migration guide. This was previously attempted as part of https://github.com/bevyengine/bevy/pull/22934, but I got pushback there. Now that bsn! is more complete (scene components!) things are better. I've opted not to change the default features here, even though it makes it much harder to move our examples over, because that's a much more contentious change. While I feel that Bevy's default features should be example-oriented, that's still up for debate! |
||
|
|
f6ff3c334e |
Remove android game activity from default (#23708)
android handle only one activity, either game or native. To use native, the default could now be used, but all other android need to add the game activity. # Objective android native activities should be able to use the default ## Solution remove android-game-activity from default ## Testing created a default app for android native activity with default ## Important Will be a breaking change for apps using android-game-activity. --------- Co-authored-by: Christian Oelschlegel <oelschle@sciphy.de> Co-authored-by: leomeinel <leo@meinel.dev> |
||
|
|
41f170c0a3 |
Basic clipboard support (#19106)
# Objective Add a platform-agnostic interface for interacting with the clipboard. ## Solution New crate `bevy_clipboard` with a `ClipboardPlugin` that adds a `Clipboard` resource. The clipboard is accessed using the methods `fetch_text`, `fetch_image`, `set_text` and `set_image` on the `Clipboard` resource. `fetch_text` returns a `ClipboardRead` with a `poll_result` method that's used to get the actual value once it's ready. The `windows` and `unix` implementations both use the `arboard` crate. On windows the `Clipboard` resource is a unit struct and a new arboard clipboard instance is created and dropped for each clipboard access. On unix targets the `Clipboard` resource holds a clipboard instance it reuses each time. On both targets the `fetch_*` and `set_*` methods work instantly. On `wasm32` `Clipboard` is a unit struct. The `fetch_text` and `set_text` functions spawn async tasks. The task spawned by `fetch_text` updates the shared arc mutex option once the future is evaluated to get the clipboard text. There is no image support on `wasm32`. Everything seems to work but it feels like the design is a bit clumsy and not very idiomatic. I don't tend to do much asynchronous programming, maybe a reviewer can suggest an improved construction. I also added an alternative `fetch_text_async` function for async access that returns a `Result<String, ClipboardError>` future. ### Notes * Doesn't support android targets yet. * The wasm32 implementation doesn't support images. It's much more complicated and probably best to left to a follow up. ## Testing The PR includes a basic example `clipboard` that can be used for testing. The image display will only work if the image is already in the clipboard before the example starts. --------- Co-authored-by: Gilles Henaux <ghx_github_priv@fastmail.com> Co-authored-by: Andrew Zhurov <zhurov.andrew@gmail.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> |
||
|
|
5927c47b8d |
Use a LUT for F_AB (#23737)
# Objective `F_AB` currently uses a polynomial approximation. This replaces it it with a more precise LUT. ## Solution Add a LUT computed using Monte-Carlo sampling. Generation script is available [here](https://gist.github.com/dylansechet/6086e924266caf8dd975c127f73f1e45). The minimum value was clipped to `1e-6`, which modifies 0.4% of the values that were below that but should help prevent bugs like #22833. Open questions: - Do we want to feature-gate this with the polynomial version as a fallback? ## Testing - White furnace still looks white - Solari example runs - Put a camera at grazing angles in the atmosphere example to make sure we weren't reintroducing #22833 --- ## Showcase ### F_AB tables Current PR uses the Monte-Carlo based LUT, bevy currently uses the polynomial approximation. <img width="600" height="600" alt="f_ab_monte_carlo" src="https://github.com/user-attachments/assets/f5f47c57-94a5-4a3b-886c-ae1cac72d3d5" /> <img width="600" height="600" alt="f_ab_polynomial_approx" src="https://github.com/user-attachments/assets/f946a3a1-7206-4de2-952b-b28d588d0e11" /> <img width="600" height="600" alt="mae" src="https://github.com/user-attachments/assets/70679caf-a9ec-4389-8bc8-d7b8fc24b3b1" /> ### Solari white furnace This new approximation significantly improves the solari white furnace. Main: <img width="1280" height="720" alt="solari_wf_main" src="https://github.com/user-attachments/assets/3a5aed1b-8449-491f-bedf-1d73614b202d" /> With this PR: <img width="1280" height="720" alt="solari_wf_fablut" src="https://github.com/user-attachments/assets/e2d2c585-b201-4194-8c94-5376d8f24706" /> ### LUT size vs error I ended up going with 64x64. <img width="2500" height="600" alt="size_error" src="https://github.com/user-attachments/assets/3d94c2bf-1768-4a04-bc02-e621bf6ad3a9" /> |
||
|
|
efc6464f9b |
Create types to store serializable data about the ECS schedule and provide tools for extracting this data. (#22520)
# Objective - A step towards #10981. - Allow us to extract data from an app about the schedules. Here are also some **non-goals** for this PR. These are left as future work: - Extract every piece of data in the schedule. I've focused on a rough set of information that should let us visualization the most important parts. - Provide utilities for interpreting the data. This PR is focused on just extracting the data, interpreting it comes next. - Any sort of dot graph tools. ## Solution - Create ser/de compatible structs for representing schedule data. - Create a function to get schedule data from an initialized `Schedule`. - Create a plugin to automatically extract the schedule data for every schedule in the `App`. - Note this doesn't include other subapps, I'll also leave that to another PR. - Make `bevy_ecs` return edges that build passes added. - Make `bevy_ecs` return the "build metadata" to the caller, and also trigger as an event. ## Testing - Added tests! - Added an example - it outputs a ron file. I assume its all valid. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com> |
||
|
|
6b0fb37e2c |
Rename bevy_scene2 to bevy_scene (#23668)
# Objective Part 3 of #23619 ## Solution Renames `bevy_scene2` to `bevy_scene` and adds it to the prelude. |
||
|
|
535cf401cc |
Reframe old "scene" terminology as "world serialization" (#23630)
Part 2 of #23619 In **Bevy 0.19** we are landing a subset of Bevy's Next Generation Scene system (often known as BSN), which now lives in the `bevy_scene` / `bevy::scene` crate. However the old `bevy_scene` system still needs to stick around for a bit longer, as it provides some features that Bevy's Next Generation Scene system doesn't (yet!): 1. It is not _yet_ possible to write a World _to_ BSN, so the old system is still necessary for "round trip World serialization". 2. The GLTF scene loader has not yet been ported to BSN, so the old system is still necessary to spawn GLTF scenes in Bevy. For this reason, we have renamed the old `bevy_scene` crate to `bevy_world_serialization`. If you were referencing `bevy_scene::*` or `bevy::scene::*` types, rename those paths to `bevy_world_serialization::*` and `bevy::world_serialization::*` respectively. Additionally, to avoid confusion / conflicts with the new scene system, all "scene" terminology / types have been reframed as "world serialization": - `Scene` -> `WorldAsset` (as this was always just a World wrapper) - `SceneRoot` -> `WorldAssetRoot` - `DynamicScene` -> `DynamicWorld` - `DynamicScene::from_scene` -> `DynamicWorld::from_world_asset` - `DynamicSceneBuilder` -> `DynamicWorldBuilder` - `DynamicSceneRoot` -> `DynamicWorldRoot` - `SceneInstanceReady` -> `WorldInstanceReady` - `SceneLoader` -> `WorldAssetLoader` - `ScenePlugin` -> `WorldSerializationPlugin` - `SceneRootTemplate` -> `WorldAssetRootTemplate` - `SceneSpawner` -> `WorldInstanceSpawner` - `SceneFilter` -> `WorldFilter` - `SceneLoaderError` -> `WorldAssetLoaderError` - `SceneSpawnError` -> `WorldInstanceSpawnError` Note that I went with `bevy_world_serialization` over `bevy_ecs_serialization`, as that is what all of the internal features described themselves as. I think it is both more specific and does a better job of making itself decoupled from `bevy_ecs` proper. |
||
|
|
45e454a83b |
Rename bevy_scene to bevy_ecs_serialization (#23619)
# Objective The first part of #23606. ## Solution Rename `bevy_scene` to `bevy_ecs_serialization`. No other changes were made. ## Testing The `scene` example still works as expected. |
||
|
|
f4d17d9eb2 |
Next Generation Scenes: Core scene system, bsn! macro, Templates (#23413)
After much [iteration](https://github.com/bevyengine/bevy/pull/20158), [designing](https://github.com/bevyengine/bevy/discussions/14437) and [collaborating](https://discord.com/channels/691052431525675048/1264881140007702558), it is finally time to land a baseline featureset of Bevy's Next Generation Scene system, often known by its new scene format name ... BSN (Bevy Scene Notation). This PR adds the following: - **The new scene system**: The core in-memory traits, asset types, and functionality for Bevy's new scene system. Spawn `Scene`s and `SceneList`s. Inherit from other scenes. Patch component fields. Depend on assets before loading as scene. Resolve Entity references throughout your scene. - **The `bsn!` and `bsn_list!` macro**s: Define Bevy scenes in your code using a new ergonomic Rust-ey syntax, which plays nicely with Rust Analyzer and supports autocomplete, go-to definition, semantic highlighting, and doc hover. - **`Template` / `GetTemplate`**: construct types (ex: Components) from a "template context", which includes access to the current entity _and_ access to the `World`. This is a foundational piece of the scene system. Note that this _does not_ include a loader for the BSN asset format, which will be added in a future PR. See the "Whats Next?" section for a roadmap of the future. Part of #23030 ## Review Etiquette This is a big PR. _Please use threaded comments everywhere, not top level comments_. Even if what you have to say is not anchored in code, find a line to leave your comment on. ## Overview This is a reasonably comprehensive conceptual overview / feature list. This uses a "bottom up" approach to illustrate concepts, as they build on each other. If you just want to see what BSN looks like, scroll down a bit! ### Templates `Template` is a simple trait implemented for "template types", which when passed an entity/world context, can produce an output type such as a `Component` or `Bundle`: ```rust pub trait Template { type Output; fn build_template(&mut self, context: &mut TemplateContext) -> Result<Self::Output>; } ``` Template is the cornerstone of the new scene system. It allows us to define types (and hierarchies) that require no `World` context to define, but can _use_ the `World` to produce the final runtime state. Templates are notably: * **Repeatable**: Building a Template does not consume it. This allows us to reuse "baked" scenes / avoid rebuilding scenes each time we want to spawn one. If a Template produces a value this often means some form of cloning is required. * **Clone-able**: Templates can be duplicated via `Template::clone_template`, enabling scenes to be duplicated, supporting copy-on-write behaviors, etc. * **Serializable**: Templates are intended to be easily serialized and deserialized, as they are typically composed of raw data. The poster-child for templates is the asset `Handle<T>`. We now have a `HandleTemplate<T>`, which wraps an `AssetPath`. This can be used to load the requested asset and produce a strong `Handle` for it. ```rust impl<T: Asset> Template for HandleTemplate<T> { type Output = Handle<T>; fn build_template(&mut self, context: &mut TemplateContext) -> Result<Handle<T>> { Ok(context.resource::<AssetServer>().load(&self.path)) } } ``` Types that have a "canonical" `Template` can implement the `GetTemplate` trait, allowing us to correlate to something's `Template` in the type system. ```rust impl<T: Asset> GetTemplate for Handle<T> { type Template = HandleTemplate<T>; } ``` This is where things start to get interesting. `GetTemplate` can be derived for types whose fields also implement `GetTemplate`: ```rust #[derive(Component, GetTemplate)] struct Sprite { image: Handle<Image>, } ``` Internally this produces the following: ```rust #[derive(Template)] struct SpriteTemplate { image: HandleTemplate<Image>, } impl GetTemplate for Sprite { type Template = SpriteTemplate; } ``` Another common use case for templates is `Entity`. With templates we can resolve an identifier of an entity in a scene to the final `Entity` it points to (for example: an entity path or an "entity reference" ... this will be described in detail later). Both `Template` and `GetTemplate` are blanket-implemented for any type that implements both Clone and Default. This means that _most_ types are automatically usable as templates. Neat! ```rust impl<T: Clone + Default> Template for T { type Output = T; fn build_template(&mut self, context: &mut TemplateContext) -> Result<Self::Output> { Ok(self.clone()) } } impl<T: Clone + Default> GetTemplate for T { type Template = T; } ``` It is best to think of `GetTemplate` as an alternative to `Default` for types that require world/spawn context to instantiate. Note that because of the blanket impl, you _cannot_ implement `GetTemplate`, `Default`, and `Clone` together on the same type, as it would result in two conflicting GetTemplate impls. This is also why `Template` has its own `Template::clone_template` method (to avoid using the Clone impl, which would pull in the auto-impl). ### Scenes Templates on their own already check many of the boxes we need for a scene system, but they aren't enough on their own. We want to define scenes as _patches_ of Templates. This allows scenes to inherit from / write on top of other scenes without overwriting fields set in the inherited scene. We want to be able to "resolve" scenes to a final group of templates. This is where the `Scene` trait comes in: ```rust pub trait Scene: Send + Sync + 'static { fn resolve(&self, context: &mut ResolveContext, scene: &mut ResolvedScene) -> Result<(), ResolveSceneError>; fn register_dependencies(&self, _dependencies: &mut Vec<AssetPath<'static>>); } ``` The `ResolvedScene` is a collection of "final" `Template` instances which can be applied to an entity. `Scene::resolve` applies the `Scene` as a "patch" on top of the final `ResolvedScene`. It stores a flat list of templates to be applied to the top-level entity _and_ typed lists of related entities (ex: Children, Observers, etc), which each have their own ResolvedScene. `Scene`s are free to modify these lists, but in most cases they should probably just be pushing to the back of them. `ResolvedScene` can handle both repeated and unique instances of a template of a given type, depending on the context. `Scene::register_dependencies` allows the Scene to register whatever asset dependencies it needs to perform `Scene::resolve`. The scene system will ensure `Scene::resolve` is not called until all of the dependencies have loaded. `Scene` is always _one_ top level / root entity. For "lists of scenes" (such as a list of related entities), we have the `SceneList` trait, which can be used in any place where zero to many scenes are expected. These are separate traits for logical reasons: world.spawn() is a "single entity" action, scene inheritance only makes sense when both scenes are single roots, etc. ### Template Patches The `TemplatePatch` type implements `Scene`, and stores a function that mutates a template. Functionally, a `TemplatePatch` scene will initialize a `Default` value of the patched `Template` if it does not already exist in the `ResolvedScene`, then apply the patch on top of the current Template in the `ResolvedScene`. Types that implement `Template` can generate a `TemplatePatch` like this: ```rust #[derive(Template)] struct MyTemplate { value: usize, } MyTemplate::patch_template(|my_template, context| { my_template.value = 10; }); ``` Likewise, types that implement `GetTemplate` can generate a patch _for their template type_ like this: ```rust #[derive(GetTemplate)] struct Sprite { image: Handle<Image>, } Sprite::patch(|sprite_template| { // note that this is HandleTemplate<Image> sprite.image = "player.png".into(); }) ``` We can now start composing scenes by writing functions that return `impl Scene`! ```rust fn player() -> impl Scene { ( Sprite::patch(|sprite| { sprite.image = "player.png".into(); ), Transform::patch(|transform| { transform.translation.y = 4.0; }), ) } ``` ### The `on()` Observer / event handler Scene `on` is a function that returns a scene that creates an Observer template: ```rust fn player() -> impl Scene { ( Sprite::patch(|sprite| { sprite.image = "player.png".into(); ), on(|jump: On<Jump>| { info!("player jumped!"); }) ) } ``` ### The BSN Format `BSN` is a new specification for defining Bevy Scenes. It is designed to be as Rust-ey as possible, while also eliminating unnecessary syntax and context. The goal is to make defining arbitrary scenes and UIs as easy, delightful, and legible as possible. It is intended to be usable as both an asset format (ex: `level.bsn` files) _and_ defined in code via a `bsn!` macro. These are notably _compatible with each other_. You can define a BSN asset file (ex: in a visual scene editor, such as the upcoming Bevy Editor), then inherit from that and use it in `bsn!` defined in code. ```rust :"player.bsn" Player Sprite { image: "player.png" } Health(10) Transform { translation: Vec3 { y: 4.0 } } on(|jump: On<Jump>| { info!("player jumped!"); }) Children [ ( Hat Sprite { image: "cute_hat.png" } Transform { translation: Vec3 { y: 3.0 } } ) ), (:sword Transform { translation: Vec3 { x: 10. } } ] ``` Note that this PR includes the `bsn!` macro, but it does not include the BSN asset format. It _does_ include all of the in-memory / in-code support for the asset format. All that remains is defining a BSN asset loader, which will be done in a followup. ### The `bsn!` Macro `bsn!` is an _optional_ ergonomic syntax for defining `Scene` expressions. It was built in such a way that Rust Analyzer autocomplete, go-to definition, doc hover, and semantic token syntax highlighting works as expected pretty much everywhere (but there are _some_ gaps and idiosyncrasies at the moment, which I believe we can iron out). It looks like this: ```rust fn player() -> impl Scene { bsn! { Player Sprite { image: "player.png" } Health(10) Transform { translation: Vec3 { y: 4.0 } } on(|jump: On<Jump>| { info!("player jumped!"); }) Children [ ( Hat Sprite { image: "cute_hat.png" } Transform { translation: Vec3 { y: 3.0 } } ) ), (:sword Transform { translation: Vec3 { x: 10. } } ] } } fn sword() -> impl Scene { bsn! { Sword Sprite { image: "sword.png" } } } fn blue_player() -> impl Scene { bsn! { :player Team::Blue Children [ Sprite { image: "blue_shirt.png" } ] } } ``` I'll do a brief overview of each implemented `bsn!` feature now. ### `bsn!`: Patch Syntax When you see a normal "type expression", that resolves to a `TemplatePatch` as defined above. ```rust bsn! { Player { image: "player.png" } } ``` This resolve to the following: ```rust <Player as GetTemplatePatch>::patch(|template| { template.image = "player.png".into(); }) ``` This means you only need to define the fields you actually want to set! Notice the implicit `.into()`. Wherever possible, `bsn!` provides implicit `into()` behavior, which allows developers to skip defining wrapper types, such as the `HandleTemplate<Image>` expected in the example above. This also works for nested struct-style types: ```rust bsn! { Transform { translation: Vec3 { x: 1.0 } } } ``` Note that you can just define the type name if you don't care about setting specific field values / just want to add the component: ```rust bsn! { Transform } ``` To add multiple patches to the entity, just separate them with spaces or newlines: ```rust bsn! { Player Transform } ``` Enum patching is also supported: ```rust #[derive(Component, GetTemplate)] enum Emotion { Happy { amount: usize, quality: HappinessQuality }, Sad(usize), } bsn! { Emotion::Happy { amount: 10. } } ``` Notably, when you derive GetTemplate for an enum, you get default template values for _every_ variant: ```rust // We can skip fields for this variant because they have default values bsn! { Emotion::Happy } // We can also skip fields for this variant bsn! { Emotion::Sad } ``` This means that unlike the `Default` trait, enums that derive `GetTemplate` are "fully patchable". If a patched variant matches the current template variant, it will just write fields on top. If it corresponds to a different variant, it initializes that variant with default values and applies the patch on top. For practical reasons, enums only use this "fully patchable" approach when in "top-level scene entry patch position". _Nested_ enums (aka fields on patches) require specifying _every_ value. This is because the majority of types in the Rust and Bevy ecosystem will not derive `GetTemplate` and therefore will break if we try to create default variants values for them. I think this is the right constraint solve in terms of default behaviors, but we can discuss how to support both nested scenarios effectively. Constructors also work (note that constructor args are _not_ patched. you must specify every argument). A constructor patch will fully overwrite the current value of the Template. ```rust bsn! { Transform::from_xyz(1., 2., 3.) } ``` You can also use type-associated constants, which will also overwrite the current value of the template: ```rust bsn! { Transform::IDENTITY } ``` If you have a type that does not currently implement Template/GetTemplate, you have two options: ```rust bsn! { // This will return a Template that produces the returned type. // `context` has World access! template(|context| { Ok(TextFont { font: context .resource::<AssetServer>() .load("fonts/FiraSans-Bold.ttf").into(), ..default() }) }) // This will return the value as a Template template_value(Foo::Bar) } ``` ### `bsn!` Template patch syntax Types that are expressed using the syntax we learned above are expected to implement `GetTemplate`. If you want to patch a `Template` _directly_ by type name (ex: your Template is not paired with a GetTemplate type), you can do so using `@` syntax: ```rust struct MyTemplate { value: usize, } impl Template for MyTemplate { /* impl here */ } bsn! { @MyTemplate { value: 10. } } ``` In most cases, BSN encourages you to work with the _final_ type names (ex: you type `Sprite`, not `SpriteTemplate`). However in cases where you really want to work with the template type directly (such as custom / manually defined templates), "Template patch syntax" lets you do that! ### `bsn!`: Inline function syntax You can call functions that return `Scene` impls inline. The `on()` function that adds an Observer (described above) is a particularly common use case ```rust bsn! { Player on(|jump: On<Jump>| { info!("Player jumped"); }) } ``` ### `bsn!`: Relationship Syntax `bsn!` provides native support for spawning related entities, in the format `RelationshipTarget [ SCENE_0, ..., SCENE_X ]`: ```rust bsn! { Node { width: Px(10.) } Children [ Node { width: Px(4.0) }, (Node { width: Px(4.0) } BackgroundColor(srgb(1.0, 0.0, 0.0)), ] } ``` Note that related entity scenes are comma separated. Currently they can either be flat _or_ use `()` to group them: ```rust bsn! { Children [ // Child 1 Node BorderRadius::MAX, // Child 2 (Node BorderRadius::MAX), ] } ``` It is generally considered best practice to wrap related entities with more than one entry in `()` to improve legibility. ### `bsn!`: Expression Syntax `bsn!` supports expressions in a number of locations using `{}`: ```rust let x: u32 = 1; let world = "world"; bsn! { // Field position expressions Health({ x + 2 }) Message { text: {format!("hello {world}")} } } ``` Expressions in field position have implicit `into()`. Expressions are also supported in "scene entry" position, enabling nesting `bsn!` inside `bsn!`: ```rust let position = bsn! { Transform { translation: Vec3 { x: 10. } } }; bsn! { Player {position} } ``` ### `bsn!`: Inline variables You can specify variables inline: ```rust let black = Color::BLACK; bsn! { BackgroundColor(black) } ``` This also works in "scene entry" position: ```rust let position = bsn! { Transform { translation: Vec3 { x: 10. } } }; bsn! { Player position } ``` ### Inheritance `bsn!` uses `:` to designate "inheritance". Unlike defining scenes inline (as mentioned above), this will _pre-resolve_ the inherited scene, making your current scene cheaper to spawn. This is great when you inherit from large scene (ex: an asset defined by a visual editor). Scenes can only inherit from one scene at a time, and it must be defined first. You can inherit from scene assets like this: ```rust fn red_button() -> impl Scene { bsn! { :"button.bsn" BackgroundColor(RED) } } ``` Note that while there is currently no implemented `.bsn` asset format, you can still test this using `AssetServer::load_with_path`. You can also inherit from functions that return a `Scene`: ```rust fn button() -> impl Scene { bsn! { Button Children [ Text("Button") ] } } fn red_button() -> impl Scene { bsn! { :button BackgroundColor(RED) } } ``` Note that because inheritance is cached / pre-resolved, function inheritance does not support function parameters. You can still use parameterized scene functions by defining them directly in the scene (rather than using inheritance): ```rust fn button(text: &str) -> impl Scene { bsn! { Button Children [ Text(text) ] } } fn red_button() -> impl Scene { bsn! { button("Click Me") BackgroundColor(RED) } } ``` Related entities can also inherit: ```rust bsn! { Node Children [ (:button BackgroundColor(RED)), (:button BackgroundColor(BLUE)), ] } ``` Inheritance concatenates related entities: ```rust fn a() -> impl Scene { bsn! { Children [ Name("1"), Name("2"), ] } } fn b() -> impl Scene { /// this results in Children [ Name("1"), Name("2"), Name("3") ] bsn! { :a Children [ Name("3"), ] } } ``` ### `bsn_list!` / SceneList Relationship expression syntax `{}` expects a SceneList. Many things, such as `Vec<S: Scene>` implement `SceneList` allowing for some cool patterns: ```rust fn inventory() -> impl Scene { let items = (0..10usize) .map(|i| bsn! {Item { size: {i} }}) .collect::<Vec<_>>(); bsn! { Inventory [ {items} ] } } ``` The `bsn_list!` macro allows defining a list of BSN entries (using the same syntax as relationships). This returns a type that implements `SceneList`, making it useable in relationship expressions! ```rust fn container() -> impl Scene { let children = bsn_list! [ Name("Child1"), Name("Child2"), (Name("Child3") FavoriteChild), ] bsn! { Container [ {children} ] } } ``` This, when combined with inheritance, means you can build abstractions like this: ```rust fn list_widget(children: impl SceneList) -> impl Scene { bsn! { Node { width: Val::Px(1.0) } Children [ Text("My List:") {children} ] } } fn ui() -> impl Scene { bsn! { Node Children [ list_widget({bsn_list! [ Node { width: Px(4.) }, Node { width: Px(5.) }, ]}) ] } } ``` ### `bsn!`: Name Syntax You can quickly define `Name` components using `#Name` shorthand. ```rust bsn! { #Root Node Children [ (#Child1, Node), (#Child2, Node), ] } ``` `#MyName` produces the `Name("MyName")` component output. Within a given `bsn!` or `bsn_list!` scope, `#Name` can _also_ be used in _value position_ as an `Entity` Template: ```rust #[derive(Component, GetTemplate)] struct UiRoot(Entity); #[derive(Component, GetTemplate)] struct CurrentButton(Entity); bsn! { #Root CurrentButton(#MyButton) Children [ ( #MyButton, UiRoot(#Root) ) ] } ``` These behave a bit like variable names. In the context of inheritance and embedded scenes, `#Name` is only valid within the current "scene scope": ```rust fn button() -> impl Scene { bsn! { #Button Node Children [ ButtonRef(#Button) ] } } fn red_button() -> impl Scene { bsn! { :button // #Button is not valid here, but #MyButton // will refer to the same final entity as #Button #MyButton Children [ AnotherReference(#MyButton) ] } } ``` In the example above, because `#MyButton` is defined "last" / is the most "specific" `Name`, the spawned entity will have `Name("MyButton")` Name references are allowed to conflict across inheritance scopes and they will not interfere with each other. `#Name` can also be used in the context of `bsn_list!`, which enables defining graph structures: ```rust bsn_list! [ (#Node1, Sibling(#Node2)), (#Node2, Sibling(#Node1)), ] ``` ### Name Restructure The core name component has also been restructured to play nicer with `bsn!`. The impl on `main` requires `Name::new("MyName")`. By making the name string field public and internalizing the prehash logic on that field, and utilizing implicit `.into()`, we can now define names like this: ```rust bsn! { Name("Root") Children [ Name("Child1"), Name("Child2"), ] } ``` ### BSN Spawning You can spawn scenes using `World::spawn_scene` and `Commands::spawn_scene`: ```rust world.spawn_scene(bsn! { Node Children [ (Node BackgroundColor(RED)) ] })?; commands.spawn_scene(widget()); ``` The `spawn_scene` operation happens _immediately_, and therefore assumes that all of the `Scene`'s dependencies have been loaded (or alternatively, that there are no dependencies). If the scene has a dependency that hasn't been loaded yet, `World::spawn_scene` will return an error (or log an error in the context of `Commands::spawn_scene`). If your scene has dependencies, you can use `World::queue_spawn_scene` and `Commands::queue_spawn_scene`. This will spawn the entity as soon as all of the `Scene`'s dependencies have been loaded. ```rust // This will spawn the entity once the "player.bsn" asset is loaded world.queue_spawn_scene(bsn! { :"player.bsn" Transform { position: Vec3 { x: 10. } } }); ``` There are also `spawn_scene_list` variants for everything above: ```rust world.spawn_scene_list(bsn_list! [ button("Ok"), button("Cancel"), ]) ``` `EntityWorldMut` and `EntityCommands` also have some new functionality: ```rust entity.queue_spawn_related_scene::<Children>(bsn_list! [ (:"player.bsn", #Player1), (:"player.bsn", #Player2), ]); ``` ```rust entity.apply_scene(bsn! { Transform { position: Vec3 { x: 10. } } })?; ``` For scene assets, you can also just add the `ScenePatchInstance(handle)` component, just like the old Bevy scene system. ### VariantDefaults derive `GetTemplate` automatically generates default values for enum Template variants. But for types that don't use `GetTemplate`, I've also implemented a `VariantDefaults` derive that also generates these methods. ## What's Next? ### Must happen before 0.19 - [ ] **Sort out `bevy_scene` vs `bevy_scene2`**: The current plan is to rename `bevy_scene` to `bevy_ecs_serialization`, and remove "scene" terminology from it. That then frees up `bevy_scene2` to be renamed to `bevy_scene`. The current `bevy_scene` will need to exist for awhile in parallel to BSN, as BSN is not yet ready for "full world serialization" scenarios. - [x] ~~**Resolve the Default Handle situation**: Currently, to provide Template support for `Handle`, it implements `GetTemplate`. This of course conflicts with `impl Default for Handle`. This is pretty disruptive to non-BSN users (which is currently everyone). We'll want to sort out a middleground solution in the short term that ideally allows us to keep `impl Default for Handle` during the transition.~~ - Resolved this by using a [specialization trick](https://github.com/bevyengine/bevy/pull/23413#discussion_r2961341173) - [ ] Nested `bsn!` `Scene` tuples to surpass tuple impl limits ### Ideally before 0.19 We likely won't land all of these. The plan is to (ideally) land this PR before Bevy 0.19 RC1, then _maybe_ land a couple more of these before - [ ] **Feathers BSN Port**: Largely already done. Just need to reconcile with current state of main. This will help BSN land well, so landing it alongside BSN is a high priority. - [ ] **ResolvedScene-as-dynamic-bundle**: ResolvedScene should insert all of the components at once as a single bundle, rather than one-by-one, which is really bad from an archetype move perspective. Without this, using `world.spawn_scene(scene)` as a `world.spawn(bundle)` replacement will result in a pretty significant performance reduction. - [ ] **`#Name` references in more places**: The UI eventing scenario _really_ wants `#Name` to be usable in closures. This would functionally be expressed as a template that returns a closure that accesses a specific entity. This unlocks a lot of value for UI devs, so ideally it lands alongside BSN. - [ ] **Top-down vs bottom-up spawn order**: Currently BSN follows the normal bevy top-down spawn order. I think we should heavily consider spawning bottom-up, in the interest of making scene contents available to "higher level" components in their lifecycle events (ex: a `Player` component accessing nested entities like "equipment" when inserted). If we decide to keep things as they are, we probably want to introduce additional "scene ready" entity events that trigger "bottom up". - [ ] **Inline field value expressions**: Support cases such as `px(10).all() - [ ] **Add EntityPath to EntityTemplate**: Support resolving entity paths (ex: `"Root/Child1/GrandChild1"`). This is relatively low hanging fruit, especially if we switch to bottom-up spawning order. - [ ] **Function Inheritance Caching**: Currently only scene asset inheritance is pre-computed / cached. For consistency / predictability / optimizations, function inheritance (ex `:button`) should also be cached. - [ ] **`derive(GetTemplate)` generics ergonomics**: Currently this requires casting spells: `T: GetTemplate<Template: Default + Template<Output = T>>` ### Near Future - [ ] **BSN Asset Format**: Add a `.bsn` parser / AssetLoader that can produce the current `ScenePatch` assets. - [ ] **Struct-style inheritance**: It would be nice to be able to do something like `:Button { prop } ` instead of `:button(prop)`. I'd really like us to explore this being component-tied (ex: associate a scene with a Button component). - [ ] **Descendant Patching**: It should be possible to "reach in" to an inherited scene and patch one of its descendants / children. - [ ] **Optimize Related Entity Spawning**: This currently inserts the relationship component first, then spawns the related scene. This results in an unnecessary archetype move. - [ ] Observers as relationships - [ ] **Scene-owned-entities**: Currently when spawning a `Scene`, every entity defined in the scene is instantiated. Some scenarios would benefit from Scene instances _sharing_ some unique entity. For example: defining assets _inside_ of scenes (this would pair nicely with Assets as Entities) , sharing Observer entities, etc. - [ ] The `touch_type::<Nested>()` approach could be replaced with `let x: &mut Nested` for actual type safety (and probably better autocomplete). - [ ] Fix Rust Analyzer autocomplete bug that fails to resolve functions and enums for `<Transform as GetTemplate>::Template::from_transform()` - [ ] Fix Rust Analyzer autocomplete bug that also suggests function names when type struct field names. This _should_ be fixed by using irrefutable `if let` statements. And it would probably allow us to reuse macro code across enums / structs (and avoid needing to use PathType inference in this case, which has gnarly corner cases). ### Longer Term - [ ] **`bsn!` hot patching via subsecond**: [Proof of concept here](https://github.com/cart/bevy/pull/36) - [ ] **Reactivity**: This has been proven out [here](https://github.com/viridia/bevy_reactor/) - [ ] **BSN Sets**: See the [old design doc](https://github.com/bevyengine/bevy/discussions/14437) for the design space I'm talking about here * This would also allow expressing "flattened" forms of BSN, which makes diffs easier to read in some case - [ ] **World to BSN**: If we can support this, BSN can be used for things like saving Worlds to disk. This might also be useful for building scene editors. --------- Co-authored-by: andriyDev <andriydzikh@gmail.com> Co-authored-by: Nico Zweifel <34443492+NicoZweifel@users.noreply.github.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: copygirl <copygirl@mcft.net> |
||
|
|
525636050f |
Remove ui from the 2d and 3d feature collections (#23180)
# Objective Fixes #23170. ## Solution > Swapping the UI framework for your Bevy project is a common form of customization. > We think that users should be able to do this easily, without having to give up the ease of use (and updates!) > that come with our top-level feature collections. > > To achieve this, the `ui` feature collection is now no longer implied by the `3d` or `2d` feature collection. > > To migrate: > > - If you used all default features before, nothing changes for you. > - If you want to opt out of using `bevy_ui`, it is now as simple as disabling default features, and manually opting into `3d` or `2d` (and optionally `audio`). > - If you already opted into non-default features and want to continue using `bevy_ui`, you will now have to add the `ui` feature. |
||
|
|
a80470f5ec |
Update Rodio to 0.22 (#20323)
# Objective - Closes #19672 ## Solution - Updated both `cpal` and `rodio` to their latest versions. - Updated code to address `rodio`'s breaking changes. - Reworked audio related feature flags. NOTE: `symphonia` will only be the default backend for formats with no alternative fallback. - Added `audio-all-formats` feature collection to easily enable all the available audio formats using their default backends. - Replaced `aarch64-apple-ios-sim` target with `arm64-apple-ios-simulator`. ## Testing - Tested audio related examples. - CI checks passing. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Parrett <robparrett@gmail.com> |
||
|
|
53050f90e2 |
New bevy_settings crate (#23034)
Yet another attempt at implementing bevy preferences. This version uses bevy_reflect serialization to convert resources from toml values into Rust types and vice versa. This is based on the feedback that I got from the earlier attempt in #22770 To indicate that a resource type should be loaded as preferences, you'll need to add the `SettingsGroup` annotation: ```rust #[derive(Resource, SettingsGroup, Reflect, Default)] #[reflect(Resource, SettingsGroup, Default)] struct Counter { count: i32, } ``` This will produce a TOML file that looks like this: ```toml [counter] count = 3 ``` ## Theory of Operation The `PreferencesPlugin` scans the type registry for all resource types that impl `SettingsGroup` and `Default`. Derive attributes can be used to write the resource to a different file (or different key in browser local storage). `PreferencesPlugin` should be added before other plugins. This ensures that any other plugins can have access to the settings data during initialization. The loader checks to see if the resource already exists; if so, it uses that resource instance and patches the toml values into it, preserving any defaults that have been set. If the resource does not exist, it constructs a new one via `ReflectDefault` before applying the toml properties. (There was a suggestion of using `FromWorld` instead of `Default`. This is worth considering, although there may be issues with calling `FromWorld` so early in the app initialization lifecycle, before most resources have been created.) On `wasm` platforms, this uses browser local storage rather than the filesystem to store preferences. On platforms which have neither, preferences are not supported (although it's possible that some platform-specific settings storage could be implemented). ## Note on terminology I've tried to consistently use the term "preferences" rather than "settings" or "config" because those are broader terms. For example, the `xorg.conf` file, commonly used to configure an XWindows display, is technically a "settings" file, but it is not "preferences". However, for end users it's perfectly permissible to use the word "Settings" in menus and navigation elements since that is the term most commonly used in software today. ## Open Issues ### Syncing with non-resources Some important settings are not stored in resources: one of the most common things that users will want to preserve is the window position and size, which exist on the window entity. It's not possible, under my design, to store arbitrary entities as preferences, so in order for the window properties to be saved they will have to be copied to a resource before being serialized. We probably don't want to be continually copying the window size every time the window is dragged or moved, so we'll need some way to know when serialization is about to happen. I'm thinking that possibly some global event could be triggered just before serialization, and the handlers could use this event to make last-minute patches to resources. ## Saving If Changed Because saving involves i/o, we want to only save when preferences have actually changed. This involves two discrete checks: * Whether a save operation needs to be done at all * Which files need to be saved The reason for these two steps is that even checking which files need to be saved is non-trivial and probably should not be done every frame. Rather than check the `is_changed()` field of every preference resource every frame, the code currently relies on the user to issue an explicit `Command` whenever they change a preferences property. This gets especially tricky if the settings to be saved aren't actually in a resource, like the aforementioned window position. There are two forms of the command: `SavePreferences` and `SavePreferencesSync`. The former, which uses an i/o task, is the preferred approach, unless the app is about to exit, in which case the sync version is preferred. Once we know that a save will take place, a second pass can be used to check the timestamp on every resource: if any resource has a tick value later than the last time the file was either loaded or saved, then we know that file is out of date. Also some properties can change at high frequency - for example, dragging the master volume slider changes the volume every frame. For this reason, we will generally want to put in a delay / debounce logic to batch updated together (not present in this PR). However, this delay means that if the user adjusts the setting and then immediately terminates the app, the setting won't be recorded. (There is no chance of the file being corrupted, as it uses standard practices for ensuring file integrity.) Unfortunately, on some platforms, depending on how the user chooses to quit (Command-Q on Mac) there's no opportunity to listen for the `AppExit` event. For this reason, it's best to use a "belt and suspenders" approach which listens for both `AppExit` and autosave timer events. Fixes #23172 Fixes #13311 --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com> |
||
|
|
6ab2b07b90 |
Make it easier to opt out of bevy_audio (#23126)
# Objective
- bevy_seedling is incompatible with `bevy_audio`
- all our profile features (`3d`, `2d`, `ui`) enable the `audio`
collection feature
- That means that a seedling user needs to do this to land at the
current `default`:
```toml
[dependencies]
bevy = { version = "0.18.0", default-features = false, features = [
# 2d
"2d_bevy_render",
"default_app",
"picking",
"scene",
# 3d
"3d_bevy_render",
# ui
"ui_api",
"ui_bevy_render",
# default_platform
"android-game-activity",
"bevy_gilrs",
"bevy_winit",
"default_font",
"multi_threaded",
"std",
"sysinfo_plugin",
"wayland",
"webgl2",
"x11",
] }
```
## Solution
- Disable the `audio` collection features for all profile features and
instead enable it by default
- The new seedling config now looks like this:
```toml
[dependencies]
bevy = { version = "0.18.0", default-features = false, features = [
"2d",
"3d",
"ui",
] }
```
## Testing
- None, CI should take care of this
|
||
|
|
06a444ac65 |
Remove experimental designation from bevy_ui_widgets feature flag (#22934)
# Objective `bevy_ui_widgets is still incomplete and unstable, but the utility of the `experimental` designation is questionable: 1. Running examples with required non-default features suck. This is frustrating for UI examples, and hampers adoption in our other examples even when real UI-based controls would be more elegant. 2. These widgets have proven useful to end users in practice, even in 0.19. 3. These widgets have seen a number of small bug fixes and improvements since their initial release. 4. It's not clear that this label is effective for slowing adoption, or if slowing adoption is currently desirable. Users don't have a ton of other great options: writing their own widgets will waste work *and* still need to be rewritten with BSN. 5. Bevy as a whole is still quite experimental. Unlike e.g. ghost nodes, there's no indication that we are considering wholly reverting these features. ## Solution Amended based on review feedback: > The `experimental_ui_widgets` feature have been renamed to `ui_widgets`. > > The `ui_widgets` feature has been added to the `ui` feature collection (and thus `bevy`'s default features) for ease of use. Previous solution, from the original migration guide: > The `experimental_ui_widgets` and `experimental_bevy_feathers` features have been renamed to `ui_widgets` and `bevy_feathers` respectively. > > The `ui_widgets` feature has been added to the `ui` feature collection (and thus `bevy`'s default features) for ease of use. > The `bevy_feathers` feature remains off by default: it is primarily intended for use in dev tools, and should typically not be included in shipped end-user applications. As a result, it needs to be easy to enable and disable conditionally. This would be very challenging if it were a default feature or in a popular feature collection. > > These crates remain immature, and subject to heavy breaking changes, even relative to Bevy's pre-1.0 standards. > However, they are useful enough to see wider adoption, and this changes substantially improves the user experience when setting up new projects and running Bevy examples. --------- Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com> |
||
|
|
bb60d126c7 |
add bevy_picking back (#22990)
# Objective - #22933 removed the `bevy_picking` feature because it had the same description as `picking` yet a different purpose. I believe this different purpose is worth preserving and the fix is to document them more adequately instead. The rest of the PR was good, i agree with making it not enable `bevy_input_focus` when its enabled. Furthermore, I would be in favor of a `picking_input_focus` feature. ## Solution - Restore `bevy_picking` feature - Adjust docs ## Testing - ci --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> |
||
|
|
052c272f35 |
Condense bevy_picking (input focus) feature into bevy_ui_picking feature (#22933)
# Objective The feature flags "bevy_picking" and "picking" have the same description despite fulfilling different goals. This is very confusing! Fixes #22931. The status quo before this PR. > - picking is a feature collection in bevy, which enables ["bevy_picking", "mesh_picking", "sprite_picking", "ui_picking"]. > - the ui feature collection enables picking itself > - bevy_picking is defined in bevy, which defers to ["bevy_internal/bevy_picking"] > - in bevy_internal, this toggles bevy_picking = ["dep:bevy_picking", "bevy_input_focus?/bevy_picking"] > - this then toggles the bevy_picking dependency (apparently that works as if it were a feature?) in bevy_input_focus > - which is ultimately used to enable mouse / virtual cursor based input focus selection > - @viridia is concerned about making this mandatory because of worries about observer overhead ## Solution Condense bevy_picking at the bevy_internal level into bevy_ui_picking. There's no way someone wants general UI picking but not input focus picking. This fixes the redundancy, and groups functionality more reasonably, while still making it possible to avoid UI picking as a whole off if you're concerned for whatever reason. Users who want even more granularity than that can of course compose the various Bevy crates however they please. ## Alternative 1. Keep this feature around, renaming it to `input_focus_picking`. 2. Enable that feature inside of `ui_picking`. This adds another niche feature flag at the top level, but makes it easier for users who want to use `bevy_input_focus` without `bevy_ui`. I have never met such a user, but maybe they exist! |
||
|
|
48ec375a3a |
bevy_text parley migration (#22879)
# Objective Migrate `bevy_text` from Cosmic Text to Parley. Closes #21940. Fixes #21767, fixes #21768. Part of #21676. ## Solution I came down with the flu yesterday when I was about halfway done. I managed to work through it and drag this to a sort of finished state anyway but there's probably some weird decisions because I haven't been entirely coherent. Most of the significant changes are to the pipeline module. There is also a new `parley_context` module. `FontAtlasKey` has a bunch of new fields, I can't remember why there's both an `id` and a `index` now. ## Testing Weird bug in `testbed_2d`: <img width="893" height="168" alt="symbols" src="https://github.com/user-attachments/assets/29288e16-9c3a-4aee-9ec5-638179b0bac0" /> Most other things seem to work the same as main, ymmv. ## Showcase `testbed_2d`'s text scene on main with Cosmic Text: <img width="1924" height="1127" alt="main-text2d-layout" src="https://github.com/user-attachments/assets/55d0c7b7-7517-4a50-b76f-2a24e7cdc28f" /> `testbed_2d`'s text scene on this PR with Parley: <img width="1924" height="1127" alt="testbed-2d-text" src="https://github.com/user-attachments/assets/c87265fa-6e5f-4c03-aa5e-730f09f83ca3" /> `testbed_ui`'s text scene on main with Cosmic Text: <img width="1924" height="1127" alt="testbed-ui-main" src="https://github.com/user-attachments/assets/ce764891-3ca6-4c63-83af-8fe285a4a229" /> `testbed_ui`'s text scene on this PR with Parley: <img width="1924" height="1127" alt="testbed_ui_parley" src="https://github.com/user-attachments/assets/45bcbfe7-1ce4-44f7-bad7-7fa8f46c66ce" /> --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> |
||
|
|
f3cb87b8fc |
render buffer debug label type prepopulation (#22698)
# Objective
- The vast majority of our buffers are unlabelled. This makes debugging
wgpu errors really annoying, cus they lack context.
## Solution
- We have type information, and buffers predominantly are custom struct
types, and the few cases in which they arent they seem to be manually
named anyways. Let's exploit the type info to populate the buffer names
under a debug gate.
## Testing
- ran occlusion_culling example with and without the debug feature, it
currently crashes due to a wgpu 28 change.
## Showcase
Before:
```
Caused by:
In a CommandEncoder
In a dispatch command, indirect:true
Attempted to use Buffer with '' label with conflicting usages. Current usage BufferUses(STORAGE_READ_WRITE) and new usage BufferUses(INDIRECT). BufferUses(STORAGE_READ_WRITE) is an exclusive usage and cannot be used with any other usages within the usage scope (renderpass or compute dispatch).
```
After:
```
Caused by:
In a CommandEncoder
In a dispatch command, indirect:true
Attempted to use Buffer with 'bevy_render::render_resource::buffer_vec::RawBufferVec<bevy_render::batching::gpu_preprocessing::LatePreprocessWorkItemIndirectParameters>' label with conflicting usages. Current usage BufferUses(STORAGE_READ_WRITE) and new usage BufferUses(INDIRECT). BufferUses(STORAGE_READ_WRITE) is an exclusive usage and cannot be used with any other usages within the usage scope (renderpass or compute dispatch).
```
Note that now we know 1. its a `RawBufferVec`, 2. of
`LatePreprocessWorkItemIndirectParameters`. This lets us greatly narrow
the scope of the search for an offender.
Note: this is the evolution of several different attempts at improving
debug info. First attempt was with `#[track_caller]`, but that doesn't
work in const contexts because Location isnt allowed there. Second
attempt was to prepopulate type name info in constructors, but
`std::any::type_name()` returns a `&'static str`, and label is
`Option<String>`, and `.into()` and `.to_string()` are both not const
because `String` is heap allocated. Finally, i moved it to the buffer
creation site, and then extracted it into a generic function to
deduplicate.
|
||
|
|
51fc15b1a9 |
Fix doc for cargo feature profiles doc (#22566)
# Objective - Bevy 0.17 does not have a feature named `2d`. It was introduced in 0.18. - Feel free to change the PR title if it's ambiguous or close the PR if I'm wrong. ## Solution - Update to 0.18. ## Testing - None |
||
|
|
f478cb3e5b |
Detailed Feature List for Collections (#22506)
# Objective - Make it easier to understand what each feature collection is enabling. ## Solution - Added the list of features that a collection will enable on its description. These are located in the "cargo_features" templated doc page. ## Testing - Running the templated page generator for "features" and checking the resulting markdown. --- ## Showcase <img width="996" height="373" alt="image" src="https://github.com/user-attachments/assets/9b31de60-ef33-4291-bd5f-2d1583467447" /> |
||
|
|
ff376dea7c |
bevy_material (#22426)
# Objective - extract material infrastructure to be usable for scene description without a renderer - rework of #21543 on top of #22408, you can view a clean diff here: https://github.com/tychedelia/bevy/compare/type-erase-more-materials...atlv24:ad/material2?expand=1 - this is the culmination of numerous crate splits and refactors leading up to this point, and the another step towards shared 2d and 3d rendering infrastructure deduplication. ## Solution - new crate bevy_material with MaterialProperties struct that lets one define when a material draws, how it behaves, what shaders it uses, specialization functions, and bind group layouts expected. ## Testing --------- Co-authored-by: charlotte 🌸 <charlotte.c.mcelwain@gmail.com> Co-authored-by: Daniel Skates <zeophlite@gmail.com> |
||
|
|
40c0edbb0b |
Put input sources for bevy_input under features (#21447)
# Objective
`bevy_input` provides primitives for all kinds of input. But on consoles
you usually don't have things like touch. On more obscure platforms,
like GBA, only gamepad input is needed.
## Solution
To avoid including extra stuff, I put each source under a feature. I
didn't enable them by default to avoid typing
```
default-features = false, features = [
"std",
"bevy_reflect",
"bevy_ecs/async_executor",
"smol_str"
]
```
in all places that include `bevy_input`. Instead, I just enabled the
used input sources in `bevy_window` and `bevy_gilrs`. This way, when a
crate that provides hardware support for a specific input source is not
used, the corresponding feature in `bevy_input` also won't be enabled.
For GBA this reduced the binary size for the `game` example from 1.6M to
1.4M.
## Considered alternatives
I also considered doing something like this:
```rust
pub struct InputPlugin {
pub keyboard: bool,
pub mouse: bool,
pub gamepad: bool,
pub touch: bool,
}
```
But this doesn't eliminate extra code even with LTO enabled and might be
confusing for users, since toggling these values could cause a crash due
to a missing resource when a crate like `bevy_window` expects it.
|
||
|
|
f9d59f8206 |
Fix cargo features lint (#22008)
# Objective `markdownlint` fails on `docs/cargo_features.md` as it doesn't like the space before the pipe at the end of this line ## Solution - Add a `.` ## Testing - CI |
||
|
|
9a9817bba1 |
Update PanCam and FreeCam to use full term Camera (#21592)
# Objective This PR fixes #21569, which proposes renaming the newly introduced camera controller modules `FreeCam` and `PanCam` to use the full term `Camera`. ## Solution * Renamed the `PanCam` controller, `PanCamPlugin`, and related methods to use the full term `Camera` instead of the abbreviation `Cam`. * Renamed the module from `pan_cam` to `pan_camera` for consistency with naming conventions. * Updated the example `pan_camera_controller` and adjusted usage of the renamed controller and plugin. * Updated documentation and release notes accordingly. ## Follow-up Work I see two options from here: 1. **Use this PR as a reference** for renaming `FreeCam`. The process is similar and could be a great first issue for someone looking to contribute to the new camera modules or Bevy in general. Most of the changes follow the same pattern, although `FreeCam` has more examples that need updating. One could find them using `grep` (e.g., `grep FreeCam`) or by reviewing the diff from the PR that introduced `FreeCam`: #20215 2. **I can continue and update this PR** to also handle the `FreeCam` renaming, if you'd prefer to resolve the entire issue in one go. --------- Co-authored-by: syszery <syszery@users.noreply.github.com> |
||
|
|
a48d6cd336 |
Rename bevy_reflect's documentation feature to reflect_documentation (#21577)
# Objective Fixes #14309 ## Solution Renamed the `bevy_reflect` feature from `documentation` to `reflect_documentation` to follow the naming convention where features are prefixed with their module name. ## Changes - Renamed feature `documentation` to `reflect_documentation` in: - `bevy_reflect/Cargo.toml` - `bevy_reflect/derive/Cargo.toml` - `bevy_internal/Cargo.toml` - Updated all conditional compilation attributes from `#[cfg(feature = "documentation")]` to `#[cfg(feature = "reflect_documentation")]` - Updated example documentation in `reflect_docs.rs` ## Testing <img width="1414" height="688" alt="截图 2025-10-17 18-52-14" src="https://github.com/user-attachments/assets/461d827a-c958-4c0d-862d-aae25598f2f7" /> |
||
|
|
81d9c88950 |
feat(pan-cam): add scaffolding for 2D pan camera controller (#21520)
# Objective Implements scaffolding for a 2D pan camera controller. Fixes #21468 ## Solution - Introduced a `PanCam` component with settings for panning, zooming, and rotation via keyboard input, following the design of the existing `FreeCam`. - Added a `PanCamPlugin` to register the controller system. - Implemented keyboard-based panning and rotation. ## TODOs - Movement is currently world-axis aligned. - TODO: Consider movement relative to camera rotation. - Zooming support is scaffolded with config fields but not yet implemented. ## Testing Unfortunately, I was unable to fully test this implementation due to issues running graphical output with GPU acceleration under WSL. As a result, zoom behavior and rotation effects remain TODOs, and the whole code could not be fully verified. Once I resolve the GPU passthrough issues, I plan to complete and test the remaining features (with a more meaningful example). --- I'm happy to hear any suggestions or feedback in the meantime! --------- Co-authored-by: syszery <syszery@users.noreply.github.com> Co-authored-by: Janis <130913856+janis-bhm@users.noreply.github.com> |
||
|
|
1e7f4931aa |
Fix typo in features.md.tpl (#21546)
# Objective Fix typo ## Solution Fix typo |
||
|
|
b81dabe433 |
bevy_gizmos_render (#21536)
# Objective - make gizmos render agnostic ## Solution - split crate ## Testing - ci and a few examples --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: François Mockers <francois.mockers@vleue.com> |
||
|
|
f3ec3c070e |
Cargo Feature Collections (#21472)
## Objective Users of the `bevy` crate currently live one of two lifestyles: 1. Use all of Bevy's default features, potentially compiling many features you don't need or don't want. If there is a feature you _cannot have_ in your app, you must move on to option (2) 2. Disable Bevy's default features, and compose the complete list of features yourself. Living in the world of (2) is an exercise in frustration, as the list of required features to accomplish a given task changes regularly across releases as we add and change features. This is an _expert level_ task that requires intimate knowledge of engine internals to get right. Even I, Bevy's lead developer, would struggle here. To the point that I would never voluntarily choose to disable Bevy's default features. Most games/apps are 2D-only, 3D-only, or UI-only and don't require the full set of features. We cannot currently in good conscience recommend that those developers live in the "no default features" world. That is a fast track to pain, suffering, and perhaps a quick exit from the Bevy ecosystem. The same problem exists for developers that want to build their own Bevy renderer or replace Bevy UI with their own framework. Once again, we _cannot_ recommend that those developers manage every Bevy feature themselves. Fixes: #21369 Alternative to: #20741 #21236 ## Solution Define a "standalone" set of features that enable Bevy developers to disable default features, then opt in to the funtionality they want. The "default" `bevy` feature set is now just: ```toml default = ["2d", "3d", "ui"] ``` This enables developers to select only the features they need. For example, a UI-only app would look like this: ```toml bevy = { version = "0.17", default-features = false, features = [ "ui" ] } ``` "2d", "3d", and "ui" each contain the "full" Bevy experience for that domain. This also includes: - `default_platform`: the default "platform support" features (see docs) - `default_app`: the default "app framework" features (see docs) For developers that do not want the default bevy render / platform / app functionality, this breaks down further into: - `common_api`: common / core backend-less user-facing Bevy render api - `2d_api`: common / core backend-less user-facing Bevy 2d api - `3d_api`: common / core backend-less user-facing Bevy 3d api - `ui_api`: common / core backend-less user-facing Bevy ui api (and many others) I've also added the `dev` feature to this PR, which enables the recommended "dev only" features like dynamic linking, asset watching / hot reloading, and dev / debug tools. Including dynamic linking is a bit controversial here given that it doesn't work everywhere. But I'd like to aggressively push people into the dynamic linking workflow wherever possible, as developing without it is signficantly worse. And removing a single `dev` feature is a much simpler release workflow. --------- Co-authored-by: atlv <email@atlasdostal.com> |
||
|
|
44b904ed05 |
Rename bevy_mesh_picking_backend to mesh_picking (#21436)
# Objective - Only prefix features bevy_ if they correspond to a crate - Another step towards #20867 ## Solution - rename it ## Testing - ci |
||
|
|
66e8232412 |
Add bevy_camera_controllers crate and move freecam implementation into it (#20215)
# Objective Moving the camera around is really important to validate that our scenes are rendered correctly. Bevy engine devs currently do this via a fairly cursed "library example" which includes a basic freecam controller (which is technically distinct from a flycam apparently). This has three problems: 1. Oh god why are we taking pseudo-dependencies on other examples. 2. Something like this would be useful for debugging for users. 3. Something like this would be useful for the editor and other tooling. ## Solution Create a new `bevy_camera_controllers` crate, and move the existing freecam implementation into it, nearly verbatim. This cleans up some ugly tech debt in how we do this, makes it easier to add a camera controller to other examples, and also gives us a scaffold for future camera controllers. This PR has been marked `X-Blessed`, as I went over this plan with @cart in a [meeting on 2025-06-23](https://discord.com/channels/691052431525675048/692572690833473578/1386847828923519038), and we both agreed that this was the right first step. ## Testing I've tested the examples that rely on this camera controller: they work just like before. ## Notes for reviewers - I don't intend to land this in Bevy 0.17: the existing example code is not high enough quality for me to be happy shipping this - we're also soft feature-frozen; I was just in the mood to do this today - this PR has some minimal cleanup: just enough naming and docs work to make this code not an active liability. Any more will risk derailing this PR and making it harder to review - I've opted to expose top-level feature flags for the various camera controllers. This is a bit noisy, but it was the only sensible way I could see to both have "no camera controllers by default" and "still easy to use these controllers in examples" - this will not be the only camera controller in this crate, or the Bevy Editor - this is not the place to discuss "what should the default camera controller for the Bevy Editor be" - if you think this crate, or this particular move is the wrong strategy for some other reason though, please do speak up :) - my personal (unblessed) hope is that we continue to add camera controllers to this crate as needed for various first-party tooling. I will probably largely push-back on adding camera controllers that we do not actively use to this crate, since I don't think they make great libraries in general (much better to copy-paste) ## TODO - [x] add release note. I'm waiting until after Bevy 0.17 ships to do this - [x] update the examples/README.md file. I was lazy and didn't want to constantly resolve merge conflicts on that while this PR sits - [x] change to singular crate name ## Future work - split apart the giant camera controller component - make keybinding better, either with or without a real input manager solution - split apart the system to make it more modular - make the system handle fixed timesteps better - use the camera controller in more examples for debugging - add more camera controllers! --------- Co-authored-by: atlv <email@atlasdostal.com> Co-authored-by: Jan Hohenheim <jan@hohenheim.ch> |
||
|
|
14756e100c |
Rename bevy_ui_picking_backend to ui_picking (#21435)
# Objective - Only prefix features bevy_ if they correspond to a crate - Another step towards #20867 ## Solution - rename it ## Testing - ci |
||
|
|
f73e3bc11e |
Add generator command to features md file (#21434)
# Objective - i always forget what it is ## Solution - put it at the top of the file (another md template does this - not new) ## Testing - umm |
||
|
|
9fe6234b8e |
rename bevy_sprite_picking_backend to sprite_picking (#21437)
# Objective - Only prefix features bevy_ if they correspond to a crate - Another step towards #20867 ## Solution - rename it ## Testing - ci |
||
|
|
40df90cf73 |
Make bevy_mikktspace optional (#21390)
# Objective - allow users to cut unneeded deps ## Solution - feature gate ## Testing - clearcoat example uses generated tangents, still works. |
||
|
|
b7a90ae653 |
make bevy_mesh optional for bevy_animate (#20742)
# Objective - make bevy_mesh optional for bevy_animate as mentioned in https://github.com/bevyengine/bevy/pull/20714#issuecomment-3218581329 ## Solution - copy paste the morph weights stuff out into a module, gate it, then add the optional dep |
||
|
|
ff7837ef38 |
Rename animation to gltf_animation (#21388)
# Objective - Step towards #20867 ## Solution - Do a rename ## Testing - Ran some examples |
||
|
|
c23377228c |
bevy_mesh optional morph (#21389)
# Objective - make morph support optional on bevy_mesh - unblock #20742 - another step towards #20867 ## Solution - feature ## Testing - morph targets example works |
||
|
|
d38a1ec982 |
Mark bevy_ui_widgets as experimental for now (#20972)
# Objective - These are still going to undergo *extensive* change: users should be aware of what they're getting into. - Fixes #20957. ## Solution - [x] rename the feature - [x] remove from our default features - [x] add warning to crate docs - [x] add warning to release notes - [x] add warnings to examples ## Testing I've run both the `standard_widgets` and `standard_widgets_observers` examples succesfully. |
||
|
|
f07c12570a |
Renamed bevy_core_widgets to bevy_ui_widgets. (#20944)
Renamed `CoreXXX` components to `XXXBehavior`. Fixes: #20664 @alice-i-cecile @cart |
||
|
|
f6b77e4e49 |
bevy_post_process (#20778)
# Objective Split out post process effects from bevy_core_pipeline because they are not core pipelines. ## Solution @IceSentry proposed something like this, not sure if the split is exactly as he envisioned but this seems reasonable to me. The goal is to move absolutely everything possible out of bevy_core_pipelines to unblock bevy_pbr/bevy_sprite_render compilation. Future PRs may attempt to move more little bits out. ## Testing |
||
|
|
ac380673b7 |
rename bevy_anti_aliasing to bevy_anti_alias (#20857)
# Objective - rename to have less suffixing - match future bevy_post_process crate ## Solution - remove ing ## Testing - run anti_aliasing example (not renamed, can rename this too if desired) |
||
|
|
cbf989c9da |
WebAssets without filtering (#20628)
# Objective - adopt #17889 - Fixes #5061 --------- Co-authored-by: Peter Hayman <peteyhayman@gmail.com> Co-authored-by: François Mockers <francois.mockers@vleue.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: jf908 <jf908@users.noreply.github.com> Co-authored-by: François Mockers <mockersf@gmail.com> Co-authored-by: jf908 <josh@thefindons.com> |
||
|
|
c24491e449 |
Clean up root toml features (#20752)
# Objective - We currently specify transitive feature dependencies in two places: bevy and bevy_internal Cargo.tomls - This means they get out of sync often, accumulate unnecessary duplication, and sometimes forget certain transitive deps. ## Solution - Standardize on bevy_internal. Why: this makes it impossible to use it incorrectly if you depend on bevy_internal directly for some reason. If we standardized on bevy Cargo.toml holding these, it would mean that they could be bypassed by depending on bevy_internal. Not sure why someone would do that, but this feels right. - Move the few transitive feature dependency specifications that are still in bevy to bevy_internal - clean up a lot of duplicates - add a few missing dependencies - add top level bevy_mesh, bevy_camera, bevy_light, and bevy_shader features. ## Testing - this stuff is hard to test automatically or comprehensively. #20741 might make it easy to have a no-render test suite we can maintain coverage for, but other than that its just manual verification. |
||
|
|
bf4f0e5e1d |
Rebrand glTF coordinate conversion to an alternative strategy that is biased towards glTF models (#20131)
# Objective - Fixes https://github.com/bevyengine/bevy/issues/20121 - Reverts https://github.com/bevyengine/bevy/pull/19816 Per long discussion with @superdump (see https://github.com/bevyengine/bevy/issues/19686#issuecomment-3069180465), the new coordinate loading system is still wrong, just now biased in favor of having correct forward semantics for models instead of cameras. Which is still what I need, but it should not be the new default, as we may well change `Transform::forward` instead. ## Solution Since changing forward semantics is a bigger change, let's rebrand the coordinate conversion code and keep it opt-in so that users that don't use glTF cameras get correct semantics in the meantime. ## Testing - Ran 3D examples and Blender test scenes. --------- Co-authored-by: Robert Swain <robert.swain@gmail.com> |
||
|
|
9ee0aaafc5 |
Split out sprite rendering (#20587)
# Objective - Split out `bevy_sprite_render` from `bevy_sprite` . ## Solution - Do the thing ## Testing - CI - `cargo run --example sprite` |
||
|
|
1bb17a94dd |
Initial DLSS implementation (#19864)
# Objective - Closes https://github.com/bevyengine/bevy/issues/8420 ## Solution - Initial implementation of DLSS upscaling, via https://github.com/bevyengine/dlss_wgpu. - Future PRs will work more on transparency, exposure, working with custom viewports, fixing inevitable resolution override bugs, etc. - DLSS framegen is not planned, but ray-reconstruction is for solari. - FSR3/4, XeSS2, and MetalFX temporal upscaling should be easy to add now if a future contributor wants to. In the future we could have an auto-temporal AA component that handles DLSS/FSR/XeSS/MetalFX/TAA fallbacks automatically. ## Testing - Did you test these changes? If so, how? - Run the anti_aliasing example - Are there any parts that need more testing? - Different types of scene content and rendering effects to make sure they work with DLSS/upscaling - Reviewing dlss_wgpu code --- ## Showcase  --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Carter Anderson <mcanders1@gmail.com> |
||
|
|
7a869253d1 |
Opt-in raw vulkan initialization with hooks (#20565)
# Objective Currently registering additional required Vulkan features requires either hard-coding them into `bevy_render` (see the current [DLSS proposal](https://github.com/bevyengine/bevy/pull/19864)), or forcing the plugin to take full manual control over wgpu initialization. Neither is an acceptable or scalable option for a modular engine like Bevy. ## Solution * Add a new `raw_vulkan_init` Cargo feature, that when enabled switches to wgpu's raw Vulkan init path, which accepts callbacks that allow checking and requiring additional Vulkan features. * Add a new `WgpuRawVulkanInitSettings` resource, which provides wgpu Vulkan Instance and Device init callbacks, which can be used to detect and register vulkan features. * These callbacks can register arbitrary features in the new `AdditionalVulkanFeatures` resource, which is inserted into the RenderApp at the same time that the RenderDevice is. This enables plugins to register initialization callbacks, which must happen _before_ RenderPlugin. They can then feed off of `AdditionalVulkanFeatures`, after the renderer is initialized, to detect if a given feature is supported. Due to the current lifecycles, this is best accomplished with either: * A separate "init plugin" that is registered before RenderPlugin, and a "logic plugin" that does everything else. This should be used if the plugin logic needs `Plugin::build()` access to render device state, which needs to be registered _after_ RenderPlugin to have access. The proposed DLSS feature needs this pattern. * A single "init plugin" that is registered before RenderPlugin and does everything. Use this pattern if you can as it is simpler. With deferred plugin init, we could remove the need for this split. --------- Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com> |