Add collision warnings to the MoveFrame plugin - #891
Add collision warnings to the MoveFrame plugin#891Micheal Parks (micheal-parks) wants to merge 7 commits into
MoveFrame plugin#891Conversation
🦋 Changeset detectedLatest commit: 8d47cf2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
|
Claude (@claude) review |
|
Claude finished Micheal Parks (@micheal-parks)'s task in 4m 47s —— View job Code Review
This is a well-structured PR. The collision detection pipeline is cleanly separated into focused modules with excellent inline documentation — especially the comments explaining why No correctness bugs found. Issues below are ordered by severity. Moderate
The cache is recreated on every Minor
Module-level scratch variables in Nit / Accessibility
Each <li class="flex flex-wrap items-center gap-1.5">(Could not post this as an inline comment — the file was committed as a binary in the diff.) Missing test coverage
The four existing test files cover the physics plumbing ( |
| ): CollisionMember[] => { | ||
| const members: CollisionMember[] = [] | ||
| const seen = new Set<Entity>() | ||
| const bitCache = new Map<Entity, number>() |
There was a problem hiding this comment.
The bitCache is created fresh on every collectMembers call and can never produce a cache hit within a single call. The seen set guarantees each entity is visited exactly once, so bitFor(entity) is called exactly once per entity per call — the cached !== undefined branch is dead code every time.
If the intent was to avoid re-walking the parent hierarchy for multiple colliders owned by the same arm (e.g. two Box entities both parented to arm), the cache would need to be keyed by the subject (after resolving through GhostOf), not by entity. Even then, each entity in the loop is unique, so the hit rate would only ever be >0 for two ghosts sharing a source — which can't happen because GhostOf is exclusive: true.
Consider removing the cache entirely since it adds complexity with no benefit:
| const bitCache = new Map<Entity, number>() | |
| const bitFor = (entity: Entity): number => { | |
| // One hop only — a ghost's source is never itself a ghost, and resolving | |
| // through a chain would need a cycle guard for no gain. | |
| const source = entity.targetFor(GhostOf) | |
| const subject = source?.isAlive() ? source : entity | |
| return armBitFor(subject, armBits) | |
| } |
Overview
Adds collision warnings to the move frame plugin. This is done by instantiating rapier whenever the plugin is active, adding all entities to the rapier world, and collision testing all of the arm descendent entities against all other world entities.