Implement a way to bypass all default filters
- 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?
Default filters such as `Enabled` and `Internal` allow queries to skip entities with them. Beyond these, users can create their own default filters in addition.
Right now, every query must use `Allow` to allow a specific filter. This works for "regular" systems, but does not fit the bill for things that are used to uphold invariants. Consider:
- Lifecycle observers that ensure that ECS invariants are upheld usually need to work for *every* component they're triggered on, no matter if it's disabled or similar, or else the invariants are not upheld when the filter is removed from the Entity. See https://github.com/TheBevyFlock/bevy_cli/issues/524. This has lead to a multitude of bug reports from users of various libraries when they spawn entities already holding `Disabled`. Plugin authors can react to this by using `Allow`, but that does not factor in any user-defined default filters
- `DespawnOn` components are used to uphold invariants related to state. See https://github.com/bevyengine/bevy/issues/21579 for a real-world regression because we didn't remember to allow `Internal` once it was added. In this specific case, we didn't even allow `Disabled`. But after adding `Disabled` and `Internal`, the `DespawnOn` mechanism still won't work when we either implement a new Bevy default filter or again a user provides their own
## What solution would you like?
Something to bypass all default filters. E.g. a filter called `AllowAll`.
## What alternative(s) have you considered?
- Leave as-is
- Provide only a way to bypass all Bevy default filters
- Provide different types to bypass Bevy default filters and userland default filters
- Make default filters opt-in instead of opt-out
- Don't use default filters at all in lifecycle observers and refactor the despawn_on systems to be observers
- Remove default filters entirely
- Make it `AllowAllExcept` or similar so that you can write down any exceptions, i.e. stuff you still want to not allow
- Switch to a query language like flecs has where all of this can be better expressed
- Hope that BSN fixes this all somehow? There is an idea floating around that observers in BSN can directly query components of the observed entity as their params, bypassing default filters while doing so.
- Introduce default filter kinds. "This is a default filter that is active for systems and observers, this is a default filter that is active for only systems"
- Introduce a dedicated concept of systems / observers for upholding invariants
- Wait until we have https://github.com/bevyengine/bevy/issues/20817 and use it everywhere we care about invariants. Not sure how that would exactly solve the `DespawnOn` case though
I can do this all day lol. For now, I think `AllowAll` is a fine bandaid. It's still crappy because you have to remember to use it, but it's better than what we have now.
Contributor guide
Research direction
The payload names no files or tests. Start by tracing how default filters and Allow work through queries, lifecycle observers, and the DespawnOn use cases described here; done means one mechanism can bypass all default filters, including user-defined ones, with the behavior verified by tests.
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
- Mostly clear
- Newbie friendliness
- 30/100