excaliburjs / Excalibur

🎮 Your friendly TypeScript 2D game engine for the web 🗡️

Home Page:https://excaliburjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Moving / teleport entries between scenes results in duplicate presence

JumpLink opened this issue · comments

Steps to Reproduce

Create two scenes, add the entry to the first scene, then "teleport" the entry (e.g. triggered by an event of your choice) to another scene by remove the entry from the current scene and add them to the new scene like this:

currentScene.add(entry);
...
// teleport
currentScene.remove(entry);
newScene.add(entry);

Now the entry is drawn on both scenes and not removed from the current scene. You can switch between the scenes with the Excalibur Dev Tools to check this.

Expected Result

The entry should disappear from the current scene and not be drawn.

Actual Result

The entry also remains on the scene and is drawn.

Environment

  • browsers and versions: Firefox 114.0.2
  • operating system: Fedora Linux 38
  • Excalibur versions: Latest main branch
  • (anything else that may be relevant)

Current Workaround

If I use a timer the entry disappears as expected:

currentScene.add(entry);
...
// teleport
currentScene.remove(entry);
setTimeout(() => {
  newScene.add(entry);
}, 1000);

@JumpLink I agree, I think it is most expected that an actor can only exist in one scene at a time.

I think this might be a result of deferred removal causing things to not behave properly in the original scene. Timers do not have deferred removal at the end of the frame.

The add actor is immediate.

To work around this issue you could do non deferred removal from the underlying ecs world

// false means non-deferred removal
currentScene.world.remove(entity, false);

@JumpLink would it also make sense to implicitly remove an entity from it's previous scene if added to another?

currentScene.add(entry);
...
// teleport
newScene.add(entry); // implicitly removed from currentScene

@JumpLink would it also make sense to implicitly remove an entity from it's previous scene if added to another?

currentScene.add(entry);
...
// teleport
newScene.add(entry); // implicitly removed from currentScene

@eonarheim I am not sure, maybe there are situations where it is useful to have an entry in several scenes? If you ask because it would be easier to solve the problem this way, then you could introduce a new method transfer or teleport that does exactly that?

I think this might be a result of deferred removal causing things to not behave properly in the original scene. Timers do not have deferred removal at the end of the frame.

The add actor is immediate.

To work around this issue you could do non deferred removal from the underlying ecs world

// false means non-deferred removal
currentScene.world.remove(entity, false);

Thank you, this is working 👍