Skip to content

Conversation

urben1680
Copy link
Contributor

@urben1680 urben1680 commented Jun 28, 2025

Objective

Fixes #18212

Solution

This solution updates bundles containing the component that gets additionally required components registered via World::register_required_components & friends.

I also added a method to Bundles to iterate BundleInfo that contain a certain ComponentId. Needed for the implementation, might be useful for users.

Testing

Added a new test. Also ran insert_simple benchmark to bench bundle registering:

image

base spawns 10k entities at once, so the bundle registration has more impact than unbatched where the registration happens once for 10k spawns.

Maybe this is too hot and needs more optimization?

It could be improved by simply have no additional field in Bundles. I guess that would bring bundle registration performance to main. But that also means a much more expensive search to update bundles as I would need to iterate every BundleInfo and do a linear search on its contributed components.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Jun 29, 2025
@urben1680 urben1680 marked this pull request as ready for review July 1, 2025 21:14
@ItsDoot ItsDoot self-requested a review July 2, 2025 06:58
@ItsDoot ItsDoot added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Jul 2, 2025
@urben1680 urben1680 marked this pull request as draft July 2, 2025 08:16
@urben1680

This comment was marked as outdated.

@ItsDoot ItsDoot 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 labels Jul 2, 2025
@urben1680 urben1680 marked this pull request as ready for review July 2, 2025 21:04
@ItsDoot ItsDoot removed the S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged label Jul 2, 2025
@ItsDoot ItsDoot added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Jul 2, 2025
Copy link
Contributor

@SkiFire13 SkiFire13 left a comment

Choose a reason for hiding this comment

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

I have not reviewed this deep in detail, however I don't see any update to archetype moves, and this most likely makes this incomplete at best and unsound at worst.

Imagine for example a situation with bundle with just component A, and an archetype edge from {} to {A} with just that bundle. At this point make A require B: this would update the bundle to also include B, however the edge would still point to {A}. Then the next time that edge is followed you would try to insert a B in an archetype that doesn't contain it, which looks pretty nonsensical.

@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 labels Jul 7, 2025
@urben1680
Copy link
Contributor Author

urben1680 commented Jul 7, 2025

@SkiFire13 The scope of this PR is to make the runtime-added required components that do not error today already to also update the bundles that are affected by that. This still is not updating archetype edges and needs a follow-up to support that.

The World::try_register_required_components + friends return an error (or panic for the non-try variants) if any archetype contains the component that is attempted to add a new requirement to it. This stays like that here, I even added another error case where it can fail.

Effectively, this only regards bundles that are merely registered, not used yet.

So this should all be sound from my point of view, but of course pointing out issues with the implementation is more than welcome.

@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Jul 7, 2025
@urben1680 urben1680 requested a review from SkiFire13 July 14, 2025 20:06
@alice-i-cecile
Copy link
Member

I don't understand this area of the ECS well enough to be able to review this in a timely fashion, sorry :(

Comment on lines +2579 to +2580
#[test]
fn update_required_components_in_bundle() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit for the test: I would also try to test the case where a C->D required component was added later, to ensure that the tracking metadata is properly updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That exposed a bug! 😀

Copy link
Contributor Author

@urben1680 urben1680 Jul 15, 2025

Choose a reason for hiding this comment

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

@SkiFire13 The updated test does fail, but not because of the bundle side of things that I worked on here.

When I change the last bit of the test with this:

// check if another registration can be associated to the bundle using the previously registered component
world.register_required_components::<D, E>(); // note that D is part of the bundle
//let bundle = world.bundles().get(bundle_id).unwrap();
//let contributed: HashSet<_> = bundle.contributed_components().iter().copied().collect();
let contributed: HashSet<_> = world.components().get_info(a_id).unwrap().required_components().iter_ids().collect();

//assert!(contributed.contains(&a_id));
assert!(contributed.contains(&b_id));
assert!(contributed.contains(&c_id));
assert!(contributed.contains(&d_id));
assert!(contributed.contains(&e_id));

Then the last assertion fails.

Copy link
Contributor Author

@urben1680 urben1680 Jul 15, 2025

Choose a reason for hiding this comment

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

I can confirm your PR #20110 fixes this.

@urben1680
Copy link
Contributor Author

Blocked by #20110 which fixes another bug exposed by a new test in this PR.

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-Bug An unexpected or incorrect behavior D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
None yet
Development

Successfully merging this pull request may close these issues.

World::register_required_components can make bundles outdated
4 participants