Skip to content

Mutually Exclusive Components #17707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ickk opened this issue Feb 6, 2025 · 3 comments
Closed

Mutually Exclusive Components #17707

ickk opened this issue Feb 6, 2025 · 3 comments
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible S-Needs-Design This issue requires design work to think about how it would best be accomplished

Comments

@ickk
Copy link
Contributor

ickk commented Feb 6, 2025

What problem does this solve or what need does it fill?

Provide a way to declare two or more components as "mutually exclusive". That is if ComponentA and ComponentB are mutually exclusive, only one of ComponentA or ComponentB may exist on an Entity at a given time.

What solution would you like?

  1. An annotation or derive macro that marks two or more components as xor, or another way to register the relationship with the application.

  2. When a ComponentA is added to an Entity that already has a ComponentB, then ComponentB will be automatically & atomically removed, thus upholding the invariant.

  3. Queries could be made aware of mutually exclusive components, and add implicit Without filters as appropriate. That is Query<.., With<ComponentA>> is equivalent to Query<.., (With<ComponentA>, Without<ComponentB>)>.

    This works to allow a system to have both Query<&mut T, With<ComponentA>> and Query<&mut T, With<ComponentB>>, without the user needing to explicitly write the Without filters.

  4. It should be possible for the user to add a ComponentC to an existing set of mutually exclusive components defined by a 3rd party.

What alternative(s) have you considered?

Enum Components provide similar xor behaviour, however the entire enum must be queried and then branched on inside systems. Additionally, it is not possible to add variants to an existing enum (point 4 of the previous section).

Additional context

This is kinda sorta the inverse of "Required Components", but it provides a stronger invariant (xor-ness should always be maintained) and can integrate more meaningfully into queries & systems, rather than acting only at bundle insertion time.

I'm sure I've seen this idea floating around before, so this is an attempt to formalise the feature request. (Maybe it should be an rfc?)

@ickk ickk added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Needs-Design This issue requires design work to think about how it would best be accomplished labels Feb 6, 2025
@tbillington
Copy link
Contributor

tbillington commented Feb 6, 2025

Thanks for raising this, something like it would be a nice ergonomic win.

I'm not sold on automatically resolving conflicts though. Would it also remove components that were added by required components? To me it feels much more like a logic error, eg I've accidentally added Player to an entity with NPC and I'd rather it fail, not make any changes, and log an error.

@HackerFoo
Copy link
Contributor

HackerFoo commented Feb 6, 2025

This would be useful to me. I'm using typed transforms in my app, so this could help make queries more succinct.

I think I'd prefer to manually remove conflicting components, though, so maybe inserting them should be an error. Maintaining mutual exclusivity could allow the ECS to store sets of mutually exclusive components as an enum, or make other optimizations.

Maybe a minimal implementation could just handle mutually exclusive markers (ZSTs), which would be very useful.

@alice-i-cecile alice-i-cecile removed S-Needs-Triage This issue needs to be labelled C-Usability A targeted quality-of-life change that makes Bevy easier to use labels Feb 6, 2025
@alice-i-cecile
Copy link
Member

This is a duplicate / subset of #1481. Please collect discussion there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible S-Needs-Design This issue requires design work to think about how it would best be accomplished
Projects
None yet
Development

No branches or pull requests

4 participants