bevyengine / bevyengine/bevy

Allow filters to take a `Bundle` instead of a singular `Component`, and make the conjunction behavior configurable

Open
#15,327 6 comments 0 reactions 0 assignees View on GitHub
A-ECS C-Usability D-Modest X-Needs-SME
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

- This issue exists as an evolution of the context surrounding #9215

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

With the merging of #14791, bevy itself is moving away from the usage of `Bundle` structs as a means of adding many components to an entity at once, and recommends (but doesn't require that) ecosystem crates follow suit. Therefore, `Bundle`s are more free to be used in other cases with less of a worry about introducing footguns, since they are being phased out from common usage (but not completely removed).

The most immediate helpful place `Bundle`s would find usage in is filters:
```rust
// Why should we have to write all of this:
Query, With, With)>
// When we should be able to write this:
Query>

// And if we need to `OR` them:
Query, With, With)>>
// We should be able to do:
Query>
```

## What solution would you like?

These filters:
```rust
struct With;
struct Without;
struct Changed;
struct Added;
```

Become:
```rust
struct With;
struct Without;
struct Changed;
struct Added;
```

The additional `Join` generic parameter specifies how the tuple conjunction is performed:
- `All`: `With<(A, B, C), All>` means `With AND With AND With`
- `Any`: `With<(A, B, C), Any>` means `With
OR With OR With`

**We should determine if the default conjunction for `Without` should be `Any` instead of `All`.**

Note: `std::any::Any` already exists. We should try to find an alternative naming scheme that doesn't clash with std types or pre-existing bevy types, but we may have to resort to doing so anyways if no better alternative is found.

## What alternative(s) have you considered?

### Bundle tuples only

To reduce controversy, #9255 proposed implementing `With` and other filters only for `Bundle`s made of tuples. I believe this to no longer be necessary as `Bundle`s are being phased out in favor of required components, so it's believed that developers will have less of a draw towards thinking in terms of `Bundle`s (which would have been a poor-man's way of doing OOP).

### Conjunction-first

Previously suggested is a flipping of the filter type and conjunction type:
```rust
Any<(A, B, C), With>
Any<(A, B, C), Without>
All<(A, B, C), With>
// ...
```

However that ran into issues with HKTs (higher kinded types), and is verbose in the single-component case.

## Additional context

- Issue where it was originally removed: #2620
- Related issue regarding bundles in queries: #2252
- Previous issue: #9215
- PR originating from previous issue: #9255
- [Recent discussion on discord](https://discord.com/channels/691052431525675048/749335865876021248/1286506525040312380)

Contributor guide

Open the contributing guide

Research direction

Start by reading the referenced issues #9215, #9255, #2620, and #2252, then examine the existing With, Without, Changed, and Added filter APIs. Resolve the Bundle and conjunction design, including the naming conflict and Without's default behavior; completion requires an agreed API and its implementation.

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
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.