Skip to content

Commit 8387729

Browse files
nicopapManevilleFalice-i-cecileTrialDragon
authored
0.13: Add Dynamic Queries section (#895)
Co-authored-by: Félix Lescaudey de Maneville <felix.maneville@gmail.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: TrialDragon <31419708+TrialDragon@users.noreply.github.com>
1 parent 979f613 commit 8387729

File tree

1 file changed

+126
-2
lines changed
  • content/news/2024-02-03-bevy-0.13

1 file changed

+126
-2
lines changed

content/news/2024-02-03-bevy-0.13/index.md

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,133 @@ As usual, there's been some changes that may cause issues for custom shaders. We
541541

542542
## Texture Atlas Rework
543543

544-
<div class="release-feature-authors">authors: @TODO</div>
544+
<div class="release-feature-authors">authors: @james-j-obrien, @jakobhellermann, @Suficio</div>
545545

546-
TODO.
546+
In Bevy's ECS, queries use a type-powered DSL. The full type of the query — meaning:
547+
what component to access, which filter to use — must be specified at compile time.
548+
549+
Sometimes, we can't easily know what data the query wants to access at compile time.
550+
A UI with a dynamic list filtering by component, bindings for a scripting language,
551+
_entity relationships_ (more on this later), all of those, are impossible to accomplish without
552+
creating queries at runtime.
553+
554+
They are now possible thanks to dynamic queries.
555+
556+
The standard way of defining a `Query` is by using them as system parameters:
557+
558+
```rust
559+
fn take_damage(mut player_health: Query<(Entity, &mut Health), With<Player>>) {
560+
// ...
561+
}
562+
```
563+
564+
**This won't change**. And for most — if not all — gameplay use cases, you will
565+
continue to happily use the [`Query`] API, which made Bevy's reputation as a delightful game
566+
engine.
567+
568+
However, consider this situation: As a game or mod developer I want to list entities
569+
with a specific component through a text prompt. Similarly to how the Quake console works.
570+
What would that look like?
571+
572+
```rust
573+
#[derive(Resource)]
574+
struct UserQuery(String);
575+
576+
// user_query is entered as a text prompt by the user when the game is running.
577+
// Using a system, we quickly find out we can't use `Query`.
578+
fn list_entites_system(user_query: Res<UserQuery>, query: Query<TODO, With<TODO>>) {}
579+
580+
// using the more advanced `World` API, we are still stuck.
581+
fn list_entities(user_query: String, world: &mut World) {
582+
// What to put here? vvv
583+
let query = world.query::<TODO>();
584+
}
585+
```
586+
587+
It's impossible to chose a type based on the value of `user_query`!
588+
[`QueryBuilder`] solves this problem.
589+
590+
```rust
591+
fn list_entities(
592+
user_query: String,
593+
type_registry: &TypeRegistry,
594+
world: &mut World,
595+
) -> Option<()> {
596+
let name = user_query.split(' ').next()?;
597+
let type_id = type_registry.get_with_short_type_path(name)?.type_id();
598+
let component_id = world.components().get_id(type_id)?;
599+
600+
let query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
601+
.ref_id(component_id)
602+
.build();
603+
604+
for entity_ref in query.iter(world) {
605+
let ptr = entity_ref.get_by_id(component_id);
606+
// Convert `ptr` into a `&dyn Reflect` and use it.
607+
}
608+
Some(())
609+
}
610+
```
611+
612+
It is still an error-prone, complex, and unsafe API, but it makes something that was previously
613+
impossible now possible. There are more ways of using `QueryBuilder`, check out
614+
[The dynamic query pull request] for a detailed breakdown of the API.
615+
616+
[`QueryBuilder`] is here for people who need queries with runtime access specification,
617+
maybe you need to:
618+
619+
* Add a runtime filter to [`bevy-inspector-egui`]'s entity inspector.
620+
* Define queries in a scripting language such as Lua or JavaScript.
621+
* Define new components from a scripting language and query them.
622+
* Add a [Quake-style console] to modify or query components from a prompt at runtime.
623+
* Create an [editor with remote capabilities].
624+
* And these are only the plans we've heard about so far!
625+
626+
We expect third party crates to provide convenient wrappers around the `QueryBuilder` API.
627+
628+
### Relations
629+
630+
I mentioned _entity relationships_ earlier. What are relations? They are a way to associate
631+
entities to other entities. For example, the `Parent` and `Children` components
632+
in `bevy_hierarchy` are relations. They describe a relation between several entities.
633+
634+
`bevy_hierarchy` is fairly robust, but if you yourself want to create your own
635+
relation (say, a group of units in an RTS game), the road ahead is a tar pit of footguns
636+
and synchronization bugs.
637+
638+
_Entity relationships_ encode relations in the ECS. They are a staple of the [Flecs] C
639+
ECS. This makes it _a pleasure_ to describe relations, as opposed to the tar pit
640+
of footguns that it is today in bevy.
641+
642+
Sander Mertens, of Flecs fame, [describes in details] the prerequisites for an
643+
entity relationship implementation.
644+
One of those prerequisites is the ability to use entity ids as query parameters.
645+
Dynamic queries allow just that.
646+
647+
### A long wait
648+
649+
Given how useful dynamic queries are, you might be wondering why we added them this late.
650+
But dynamic queries have a long history: they date back from **November 2022**,
651+
when Suficio proposed [a simple change]. It was deemed too unsafe, [a counter-proposal]
652+
was made by Jakob Hellermann. It was stalled due to complexity and the lack of qualified and
653+
interested reviewers. They were finally merged in **January 2024**
654+
thanks to [James O'Brien's stupendous effort][The dynamic query pull request].
655+
656+
For an in-depth technical and historical breakdown of dynamic queries, check
657+
out [this GitHub discussion thread](https://github.com/bevyengine/bevy/discussions/9816).
658+
659+
They have been _a long time_ coming and they are finally here!
660+
661+
[`bevy-inspector-egui`]: https://crates.io/crates/bevy-inspector-egui
662+
[Quake-style console]: https://github.com/doonv/bevy_dev_console
663+
[editor with remote capabilities]: https://makeshift-bevy-web-editor.vercel.app/
664+
[a simple change]: https://github.com/bevyengine/bevy/pull/6240
665+
[The dynamic query pull request]: https://github.com/bevyengine/bevy/pull/9774
666+
[a counter-proposal]: https://github.com/bevyengine/bevy/pull/6390
667+
[`QueryBuilder`]: https://dev-docs.bevyengine.org/bevy/ecs/prelude/struct.QueryBuilder.html
668+
[`Query`]: https://dev-docs.bevyengine.org/bevy/ecs/prelude/struct.Query.html
669+
[describes in details]: https://ajmmertens.medium.com/a-roadmap-to-entity-relationships-5b1d11ebb4eb
670+
[Flecs]: https://www.flecs.dev/flecs/
547671

548672
## Sprite Slicing and Tiling
549673

0 commit comments

Comments
 (0)