Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/melonjs/src/physics/world.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,24 @@ export default class World extends Container {
// call the parent method
super.reset();

// save persistent child bodies
const persistentBodies = [];
this.bodies.forEach((value) => {
if (value.ancestor && value.ancestor.isPersistent) {
Comment on lines +128 to +131
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The persistence filter only keeps bodies whose owning renderable is marked isPersistent. Bodies belonging to non-persistent renderables inside a persistent container will still remain in the scene after super.reset(), but will be dropped from this.bodies by the subsequent clear() and never re-added, causing those objects to stop being stepped/collided. Consider retaining any body whose body.ancestor is still attached to this world after super.reset() (e.g., via the renderable’s container chain/root ancestor), or rebuilding this.bodies from the post-reset scene graph instead of checking only isPersistent on the body ancestor.

Suggested change
// save persistent child bodies
const persistentBodies = [];
this.bodies.forEach((value) => {
if (value.ancestor && value.ancestor.isPersistent) {
// save bodies whose owning renderable is still attached to this world
const persistentBodies = [];
this.bodies.forEach((value) => {
const owner = value.ancestor;
if (!owner) {
return;
}
// Walk up the container chain to check if the owner is still under this world
let current = owner;
while (current && current !== this && current.ancestor) {
current = current.ancestor;
}
if (current === this) {

Copilot uses AI. Check for mistakes.
persistentBodies.push(value);
}
});

// empty the list of active physic bodies
// Note: this should be empty already when calling the parent method
this.bodies.clear();

// insert persistent child bodies into the new state
if (persistentBodies.length > 0) {
persistentBodies.forEach((body) => {
this.bodies.add(body);
});
}
Comment on lines +128 to +145
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This introduces/changes behavior around which bodies survive World.reset(), but there doesn’t appear to be coverage for world reset + persistence in the current test suite. Adding a unit test that exercises a persistent container (with non-persistent children that have bodies) and/or a persistent renderable with a body would help prevent regressions.

Copilot uses AI. Check for mistakes.
}

/**
Expand Down
Loading