Skip to content

Conversation

gwafotapa
Copy link
Contributor

@gwafotapa gwafotapa commented Aug 30, 2025

Objective

EntityWorldMut::replace_related triggers Insert and Replace lifecycle events of the target. Additionally, depending on the input, it will also trigger Add and Remove. This happens when there is no intersection between the old and new relations because we start by removing the old before adding the new.

Triggering Add and Remove is clearly wrong. For Insert and Replace there are two perspectives:

  • Either we think of replace_related as mutating the RelationshipTarget component in which case no lifecycle events should trigger;
  • Or we think of replace_related as replacing the RelationshipTarget component in which case Insert and Replace should fire.

This PR goes with the first approach because:

  • It feels more natural (kinda subjective);
  • It is more consistent with replace_related_with_difference which doesn't fire any lifecycle events.

Solution

Building on the existing trick, we populate the dummy with the entity id of the target, ensuring that the RelationshipTarget component never gets emptied during the breaking of existing relations. This prevents Remove.

Finally we restore the correctly initialized RelationshipTarget component by mutating it directly instead of using EntityWorldMut::insert to avoid triggering Insert and Replace.

Testing

Added a test to ensure this works correctly.
Added a similar test for replace_related_with_difference.

@alice-i-cecile
Copy link
Member

Really good explanation, comments and tests. Thank you.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events 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 labels Sep 1, 2025
@gwafotapa
Copy link
Contributor Author

Minor tweak. No need to call mem::replace at the end since we don't need the dummy anymore. We can just mutate the RelationshipTarget component directly.

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 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.

2 participants