Component Groups
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## What problem does this solve or what need does it fill?
`bevy-trait-query` is a *really* important feature to support and improve, and hopefully eventually do in-house. For that, we need to have the concept of component groups (a set of components that share some functionality). The most common of these would be `dyn MyTrait` groups where all components that register as implementing `MyTrait` get added to the group. Speculatively, other groups may be possible. For example `HasU32AtOffset8` (or something) or a group of `BothTraits(&dyn MyTrait1, &dyn MyTrait2)`. Currently, these groups are not supported in the ECS, and `bevy-trait-query` layers them on top via resources. That has the unfortunate side effect that components need to be registered by hand prior to a query being made.
## What solution would you like?
Lets make a `ComponentGroup(Vec)` and include it in `Components`, allowing it to be registered. When a component is registered, it also adds itself to the groups it's in, and when a group is registered, it also registers any foreign components that are in the group.
Then, we add to `Access` and `FilteredAccess` a `groups` field, which tracks what groups each access needs. The groups don't need to be checked for conflicts; rather, the group's components are flattened into the `Access` like normal. When a component is registered to an existing group, all the access sets with that group need to re-check for conflicts and flatten the new component into it's list.
That means access lists can change at runtime! And simply registering a component can make two previously non-conflicting access sets conflict. It can even make an existing access set conflict with itself! This is conceptually unavoidable (I think), but it has some annoying consequences. For example, we can't statically compute access sets (or at least, we need to have a path to re-compute them).
## What alternative(s) have you considered?
We could just require all components to be registered before the first system is created, but that conflicts with a lot of design goals, ex: #17564. This is what `bevy-trait-query` does now, and it doesn't exactly scream, "ERGONOMICS!"
We could not flatten the structure in `Access`, but that would mean requiring `&Components` to check for conflicts. And conflicts could still arise from new registrations.
## Additional context
This has had a little discussion on [discord](https://discord.com/channels/691052431525675048/749335865876021248/1352472993753858091). But I think this is an important enough issue to be, well, an issue. We definitely need to work out a design for this.
Contributor guide
Research direction
Start by reviewing the proposed ComponentGroup and the existing Components, Access, and FilteredAccess concepts described in the issue. Work out how registration and changing access sets should behave, including conflict re-checks. Done means the design is resolved and the ECS supports component groups without requiring manual pre-registration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100