Skip to content

Update deleted identity cache for physics events - #72

Open
ashtonmeuser wants to merge 1 commit into
PurrNet:devfrom
ashtonmeuser:cache-deleting-update
Open

ashtonmeuser wants to merge 1 commit into
PurrNet:devfrom
ashtonmeuser:cache-deleting-update

Conversation

@ashtonmeuser

@ashtonmeuser ashtonmeuser commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

See #56 and #57.

This is an updated and narrowed version of the above PRs. In short, this caches identities deleted from the hierarchy in order to use said identities in physics events.

A simple case where this is critical is when deleting an identity via PredictedHierarchy.Delete() e.g. a PredictedRigidbody2D, bodies touching this body should invoke PredictedRigidbody2D.onCollisionExit() containing the deleted identity.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0554cf0d57

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +569 to +570
var identity = GetIdentityIncludingDeleting(id);
return identity ? identity.gameObject : null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve non-pooled objects through exit dispatch

When a verified frame deletes a non-pooled predicted object in the same tick as a physics Exit event, InternalDelete unregisters it and immediately destroys its GameObject before PostSimulateAll dispatches the event. Unity's destroyed-object null semantics make this cached PredictedIdentity evaluate false here, so the helper still returns null and the new callers discard the Exit event. The deletion must be deferred until after dispatch, or the callback data must retain something that remains usable after DestroyImmediateDirectly.

Useful? React with 👍 / 👎.

Comment on lines +639 to +640
if (isSimulating)
_deletingInstanceMap[predictedIdentity.id] = predictedIdentity;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Cache deletions throughout the outer replay operation

When ProcessQueuedFrames handles multiple queued frames, the first SimulateFrame sets isSimulating back to false even though the outer replay loop is still active, so hierarchy removals performed while reading each later frame fail this new condition and are never cached. A crossed-gap rollback has the same problem even on its first frame because its gap SimulateFrame calls finish before RestoreVerifiedState removes leavers. Consequently, Exit events from those verified frames still cannot resolve pooled deleted objects at PostSimulate; the cache condition needs to account for the enclosing replay operation rather than this non-nested boolean.

Useful? React with 👍 / 👎.

@ashtonmeuser

Copy link
Copy Markdown
Contributor Author

The above comments highlight valid concerns. These issues seem to stem from the fact that there are valid cases where the game object that exited a collision has been deleted, therefore firing a onCollisionExit event contain other == null. A workaround would be changing the signature of exit events to be onCollisionExit(GameObject other, PredictedComponentID otherId, DisposableList<Physics2DContactPoint> evContacts). The consumer could then use the PredictedComponentID regardless of whether other == null.

@ashtonmeuser

Copy link
Copy Markdown
Contributor Author

See #73 for a solution that circumvents many of the replay and falsy other GameObject issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant