From 3fcc5f232818a19a9638a901f4d71b53912b0634 Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Tue, 30 Jan 2024 11:33:09 +0100 Subject: [PATCH 1/4] 0:13: Add Dynamic queries section --- content/news/2024-02-03-bevy-0.13/index.md | 131 ++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/content/news/2024-02-03-bevy-0.13/index.md b/content/news/2024-02-03-bevy-0.13/index.md index 59d001bfcc..bd564c2b05 100644 --- a/content/news/2024-02-03-bevy-0.13/index.md +++ b/content/news/2024-02-03-bevy-0.13/index.md @@ -33,9 +33,136 @@ TODO. ## Dynamic queries -
authors: @TODO
+
authors: @james-j-obrien, @jakobhellermann, @Suficio
+ +In bevy ECS, queries use a type DSL. The full type of the query — meaning: +what component to access, which filter to use — must be specified at compile time. + +Sometimes, we don't know what the query accesses at compile time. +A UI with a dynamic list filtering by component, bindings for a scripting language, +*entity relationships* (more on this later), all of those, are impossible to accomplish without +creating queries at runtime. + +They are now possible thanks to dynamic queries. + +The standard way of defining a `Query` is by using them as system parameters: + +```rust +fn take_damange(mut player_health: Query<(Entity, &mut Health), With>) { + // ... +} +``` + +**This won't change**. And for most — if not all — gameplay use cases, you will +continue to happily use the [`Query`] API, which made bevy's reputation as a delightful game +engine. + +However, now, consider this: As a developer, or game modder, I want to list entities +with a specific component, through a text prompt. Similarly to how the Quake console works. +How does that look like? + +```rust +#[derive(Resource)] +struct UserQuery(String); + +// user_query is entered as a text prompt by the user when the game is running. +// Using a system, we quickly find out we can't use `Query`. +fn list_entites_system(user_query: Res, query: Query>) {} + +// using the more advanced `World` API, we are still stuck. +fn list_entities(user_query: String, world: &mut World) { + // What to put here? vvv + let query = world.query::(); +} +``` + +It's impossible to chose a type based on the value of `user_query`! +[`QueryBuilder`] solves this problem. + +```rust +fn list_entities( + user_query: String, + type_registry: &TypeRegistry, + world: &mut World, +) -> Option<()> { + let name = user_query.split(' ').next()?; + let type_id = type_registry.get_with_short_type_path(name)?.type_id(); + let component_id = world.components().get_id(type_id)?; + + let query = QueryBuilder::::new(&mut world) + .ref_id(component_id) + .build(); + + for entity_ref in query.iter(world) { + let ptr = entity_ref.get_by_id(component_id); + // Convert `ptr` into a `&dyn Reflect` and use it. + } + Some(()) +} +``` + +It is still an error-prone, complex, and unsafe API, but it makes something that was previously +impossible now possible. There are more ways of using `QueryBuilder`, check out +[The dynamic query pull request] for a detailed breakdown of the API. + +[`QueryBuilder`] is here for people who need queries with runtime access specification, +maybe you need to: + +- Add a runtime filter to [`bevy-inspector-egui`]'s entity inspector. +- Define queries in a scripting language such as Lua or JavaScript. +- Define new components from a scripting language and query them. +- Add a [Quake-style console] to modify or query components from a prompt at runtime. +- Create an [editor with remote capabilities]. +- And those are only what people came up with *before* the 0.13 release! + +We expect third party crates to provide convenient wrappers around the `QueryBuilder` API. + + +### Relations + +I mentioned *entity relationships* earlier. What are relations? They are a way to associate +entities to other entities. For example, the `Parent` and `Children` components +in `bevy_hierarchy` are relations. They describe a relation between several entities. + +`bevy_hierarchy` is fairly robust, but if you yourself want to create your own +relation (say, a group of units in an RTS game), the road ahead is a tar pit of footguns +and synchronization bugs. + +*Entity relationships* encode relations in the ECS. They are a staple of the [Flecs] C +ECS. This makes it *a pleasure* to describe relations, as opposed to the tar pit +of footguns that it is today in bevy. + +Sander Mertens, of Flecs fame, [describes in details] the prerequisites for an +entity relationship implementation. +One of those prerequisites is the ability to use entity ids as query parameters. +Dynamic queries allow just that. + + +### A long wait + +Given how useful dynamic queries are, you might be wondering why we added them this late. +But dynamic queries have a long history: they date back from **November 2022**, +when Suficio proposed [a simple change]. It was deemed too unsafe, [a counter-proposal] +was made by Jakob Hellermann. It was stalled due to complexity and the lack of qualified and +interested reviewers. They were finally merged in **January 2024** +thanks to [James O'Brien's stupendous effort][The dynamic query pull request]. + +For an in-depth technical and historical breakdown of dynamic queries, check +out [this GitHub discussion thread](https://github.com/bevyengine/bevy/discussions/9816). + +They have been *a long time* coming and they are finally here! + +[`bevy-inspector-egui`]: https://crates.io/crates/bevy-inspector-egui +[Quake-style console]: https://github.com/doonv/bevy_dev_console +[editor with remote capabilities]: https://makeshift-bevy-web-editor.vercel.app/ +[a simple change]: https://github.com/bevyengine/bevy/pull/6240 +[The dynamic query pull request]: https://github.com/bevyengine/bevy/pull/9774 +[a counter-proposal]: https://github.com/bevyengine/bevy/pull/6390 +[`QueryBuilder`]: https://dev-docs.bevyengine.org/bevy/ecs/prelude/struct.QueryBuilder.html +[`Query`]: https://dev-docs.bevyengine.org/bevy/ecs/prelude/struct.Query.html +[describes in details]: https://ajmmertens.medium.com/a-roadmap-to-entity-relationships-5b1d11ebb4eb +[Flecs]: https://www.flecs.dev/flecs/ -TODO. ## Entity optimizations From 0112dcc258018f79f083eb6477c97f4d6df08c14 Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Tue, 30 Jan 2024 12:04:55 +0100 Subject: [PATCH 2/4] Fix markdownlint --- content/news/2024-02-03-bevy-0.13/index.md | 25 ++++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/content/news/2024-02-03-bevy-0.13/index.md b/content/news/2024-02-03-bevy-0.13/index.md index bd564c2b05..3dfe69dd8d 100644 --- a/content/news/2024-02-03-bevy-0.13/index.md +++ b/content/news/2024-02-03-bevy-0.13/index.md @@ -40,7 +40,7 @@ what component to access, which filter to use — must be specified at compile t Sometimes, we don't know what the query accesses at compile time. A UI with a dynamic list filtering by component, bindings for a scripting language, -*entity relationships* (more on this later), all of those, are impossible to accomplish without +_entity relationships_ (more on this later), all of those, are impossible to accomplish without creating queries at runtime. They are now possible thanks to dynamic queries. @@ -108,19 +108,18 @@ impossible now possible. There are more ways of using `QueryBuilder`, check out [`QueryBuilder`] is here for people who need queries with runtime access specification, maybe you need to: -- Add a runtime filter to [`bevy-inspector-egui`]'s entity inspector. -- Define queries in a scripting language such as Lua or JavaScript. -- Define new components from a scripting language and query them. -- Add a [Quake-style console] to modify or query components from a prompt at runtime. -- Create an [editor with remote capabilities]. -- And those are only what people came up with *before* the 0.13 release! +* Add a runtime filter to [`bevy-inspector-egui`]'s entity inspector. +* Define queries in a scripting language such as Lua or JavaScript. +* Define new components from a scripting language and query them. +* Add a [Quake-style console] to modify or query components from a prompt at runtime. +* Create an [editor with remote capabilities]. +* And those are only what people came up with _before_ the 0.13 release! We expect third party crates to provide convenient wrappers around the `QueryBuilder` API. - ### Relations -I mentioned *entity relationships* earlier. What are relations? They are a way to associate +I mentioned _entity relationships_ earlier. What are relations? They are a way to associate entities to other entities. For example, the `Parent` and `Children` components in `bevy_hierarchy` are relations. They describe a relation between several entities. @@ -128,8 +127,8 @@ in `bevy_hierarchy` are relations. They describe a relation between several enti relation (say, a group of units in an RTS game), the road ahead is a tar pit of footguns and synchronization bugs. -*Entity relationships* encode relations in the ECS. They are a staple of the [Flecs] C -ECS. This makes it *a pleasure* to describe relations, as opposed to the tar pit +_Entity relationships_ encode relations in the ECS. They are a staple of the [Flecs] C +ECS. This makes it _a pleasure_ to describe relations, as opposed to the tar pit of footguns that it is today in bevy. Sander Mertens, of Flecs fame, [describes in details] the prerequisites for an @@ -137,7 +136,6 @@ entity relationship implementation. One of those prerequisites is the ability to use entity ids as query parameters. Dynamic queries allow just that. - ### A long wait Given how useful dynamic queries are, you might be wondering why we added them this late. @@ -150,7 +148,7 @@ thanks to [James O'Brien's stupendous effort][The dynamic query pull request]. For an in-depth technical and historical breakdown of dynamic queries, check out [this GitHub discussion thread](https://github.com/bevyengine/bevy/discussions/9816). -They have been *a long time* coming and they are finally here! +They have been _a long time_ coming and they are finally here! [`bevy-inspector-egui`]: https://crates.io/crates/bevy-inspector-egui [Quake-style console]: https://github.com/doonv/bevy_dev_console @@ -163,7 +161,6 @@ They have been *a long time* coming and they are finally here! [describes in details]: https://ajmmertens.medium.com/a-roadmap-to-entity-relationships-5b1d11ebb4eb [Flecs]: https://www.flecs.dev/flecs/ - ## Entity optimizations
authors: @TODO
From 29a7d7fcb6fce194f2dfea02af14e4615e99300d Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Thu, 1 Feb 2024 09:50:51 +0100 Subject: [PATCH 3/4] Fix typo discovered by ManevilleF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Lescaudey de Maneville --- content/news/2024-02-03-bevy-0.13/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/news/2024-02-03-bevy-0.13/index.md b/content/news/2024-02-03-bevy-0.13/index.md index 3dfe69dd8d..4515c91a66 100644 --- a/content/news/2024-02-03-bevy-0.13/index.md +++ b/content/news/2024-02-03-bevy-0.13/index.md @@ -48,7 +48,7 @@ They are now possible thanks to dynamic queries. The standard way of defining a `Query` is by using them as system parameters: ```rust -fn take_damange(mut player_health: Query<(Entity, &mut Health), With>) { +fn take_damage(mut player_health: Query<(Entity, &mut Health), With>) { // ... } ``` From 6ce2576973a2704b4aa6693f41d647839db86750 Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Mon, 12 Feb 2024 13:16:09 -0500 Subject: [PATCH 4/4] Add suggestions from reviewers Co-authored-by: TrialDragon <31419708+TrialDragon@users.noreply.github.com> --- content/news/2024-02-03-bevy-0.13/index.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/news/2024-02-03-bevy-0.13/index.md b/content/news/2024-02-03-bevy-0.13/index.md index 4515c91a66..3838772418 100644 --- a/content/news/2024-02-03-bevy-0.13/index.md +++ b/content/news/2024-02-03-bevy-0.13/index.md @@ -35,10 +35,10 @@ TODO.
authors: @james-j-obrien, @jakobhellermann, @Suficio
-In bevy ECS, queries use a type DSL. The full type of the query — meaning: +In Bevy's ECS, queries use a type-powered DSL. The full type of the query — meaning: what component to access, which filter to use — must be specified at compile time. -Sometimes, we don't know what the query accesses at compile time. +Sometimes, we can't easily know what data the query wants to access at compile time. A UI with a dynamic list filtering by component, bindings for a scripting language, _entity relationships_ (more on this later), all of those, are impossible to accomplish without creating queries at runtime. @@ -54,12 +54,12 @@ fn take_damage(mut player_health: Query<(Entity, &mut Health), With>) { ``` **This won't change**. And for most — if not all — gameplay use cases, you will -continue to happily use the [`Query`] API, which made bevy's reputation as a delightful game +continue to happily use the [`Query`] API, which made Bevy's reputation as a delightful game engine. -However, now, consider this: As a developer, or game modder, I want to list entities -with a specific component, through a text prompt. Similarly to how the Quake console works. -How does that look like? +However, consider this situation: As a game or mod developer I want to list entities +with a specific component through a text prompt. Similarly to how the Quake console works. +What would that look like? ```rust #[derive(Resource)] @@ -113,7 +113,7 @@ maybe you need to: * Define new components from a scripting language and query them. * Add a [Quake-style console] to modify or query components from a prompt at runtime. * Create an [editor with remote capabilities]. -* And those are only what people came up with _before_ the 0.13 release! +* And these are only the plans we've heard about so far! We expect third party crates to provide convenient wrappers around the `QueryBuilder` API.