Skip to content

Component Groups #18540

Open
Open
@ElliottjPierce

Description

@ElliottjPierce

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<ComponentId>) 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. But I think this is an important enough issue to be, well, an issue. We definitely need to work out a design for this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleS-Needs-Design-DocThis issue or PR is particularly complex, and needs an approved design doc before it can be mergedX-ControversialThere is active debate or serious implications around merging this PR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions