Skip to content

Conversation

@Trashtalk217
Copy link
Contributor

Objective

As we move more stuff to entities, it's a good idea to keep these entities quasi-private. We do not want to confuse users by having to explain everything as being an entity.

This came out of #19711.

Solution

This PR introduces the concept of internal entities, entities marked by the Internal component, that are filtered out by queries through DefaultQureyFilters and also don't show up for World::entity_count().

Testing

Added a test.

@alice-i-cecile alice-i-cecile added this to the 0.17 milestone Jul 19, 2025
@alice-i-cecile alice-i-cecile added C-Usability A targeted quality-of-life change that makes Bevy easier to use A-Dev-Tools Tools used to debug Bevy applications. A-Cross-Cutting Impacts the entire engine S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jul 19, 2025
@Trashtalk217
Copy link
Contributor Author

There are two options for the tests, and I would like some comments as to what would be better:

  1. Replace every assert_eq!(world.entities().len(), 1) with assert_eq!(world.count_entities(), 1) which ignores internal entities.
  2. Replace every assert_eq!(world.entities().len(), 1) with assert!(world.check_entities(1, |world| { // some block })) which just registers the change.

@Trashtalk217 Trashtalk217 requested review from ItsDoot and chescock July 19, 2025 21:13
@chescock
Copy link
Contributor

There are two options for the tests, and I would like some comments as to what would be better:

  1. Replace every assert_eq!(world.entities().len(), 1) with assert_eq!(world.count_entities(), 1) which ignores internal entities.
  2. Replace every assert_eq!(world.entities().len(), 1) with assert!(world.check_entities(1, |world| { // some block })) which just registers the change.

If we can, I think it would be better to rewrite those tests to stop using entities.len() and instead query the entities they care about. Like, the ones that spawn an entity with TableStored can do world.query::<&TableStored>().iter(&world).len(). The ones that do spawn_empty() will need some new marker component for the test.

(Copied from my reply on Discord.)

@alice-i-cecile alice-i-cecile added the M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide label Jul 21, 2025
@github-actions
Copy link
Contributor

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Please review the instructions for writing migration guides, then expand or revise the content in the migration guides directory to reflect your changes.

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally on board but:

  1. I have some simple doc suggestions.
  2. I feel strongly about using queries in our tests rather than counting the total number of entities anywhere. I'll help yell at people too!

@alice-i-cecile alice-i-cecile added S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide labels Jul 21, 2025
@alice-i-cecile
Copy link
Member

Apparently this PR does not need a migration guide, but changes to make observers etc use this will.

@Trashtalk217
Copy link
Contributor Author

I've thought about it some more, and I came to agree.

world.query<Component>().len()

would be wonderful to have, but since I'm not going to re-architect queries right now, I'll take the alternative.
I'll remove the entity count stuff from this PR and go through the tests - replacing every entity_count with a query - in a separate PR.

@chescock
Copy link
Contributor

Hmm, I think there are some tricks that could make a query.count() method more efficient than query.iter().count(). That seems worth doing regardless of the outcome here, so let me push that up... #20230.

@alice-i-cecile alice-i-cecile self-requested a review July 21, 2025 20:38
@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Jul 21, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jul 21, 2025
Merged via the queue into bevyengine:main with commit 4c04775 Jul 21, 2025
34 checks passed
github-merge-queue bot pushed a commit that referenced this pull request Jul 21, 2025
# Objective

- `Allows` was added as a handy tool to work with default query filters.
- It wasn't in the docs though, and I had to hunt it down while
reviewing #20204.

## Solution

-  Add some breadcrumbs to the docs in the expected places.
github-merge-queue bot pushed a commit that referenced this pull request Jul 23, 2025
# Objective

Many tests currently check against `entity_count()` in order to see if
the absolute number of entities are where they expect it to be. This is
not a very robust of doing it, as we're adding more internal entities
(#20204).

## Solution

Replace `entity_count()` by a relevant query. We also change
`iter_entities` to filter out Internal entities by default. I don't know
if this is the right approach, because unlike default query filters,
there are very few escape hatches for users who do want to iterate
through all entities, including the internal ones.

I guess you could just make a query.

Actually, why isn't `iter_entities` just a query?

## Testing

I added a `world.spawn(Internal)` during world bootstrap and most tests
succeeded still.
github-merge-queue bot pushed a commit that referenced this pull request Oct 22, 2025
# Objective

Despite initially advocating for its inclusion in #20204, I've been
increasingly unconvinced by the edge cases and user-facing complexity
and surprise that `Internal` brings.

Accidental queries are quite hard to write, and the entitiy-inspector
concerns are really a UX problem for each tool to solve that `Internal`
doesn't help with.

@cart feels similarly: as a result I'm marking this PR as X-Blessed.

Closes #21363.

## Solution

- Remove `Internal` as a type.
- Follow the compiler errors to remove all references.
- Write a migration guide.
mate-h pushed a commit to mate-h/bevy that referenced this pull request Oct 22, 2025
# Objective

Despite initially advocating for its inclusion in bevyengine#20204, I've been
increasingly unconvinced by the edge cases and user-facing complexity
and surprise that `Internal` brings.

Accidental queries are quite hard to write, and the entitiy-inspector
concerns are really a UX problem for each tool to solve that `Internal`
doesn't help with.

@cart feels similarly: as a result I'm marking this PR as X-Blessed.

Closes bevyengine#21363.

## Solution

- Remove `Internal` as a type.
- Follow the compiler errors to remove all references.
- Write a migration guide.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Cross-Cutting Impacts the entire engine A-Dev-Tools Tools used to debug Bevy applications. C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants