How to correctly switch back and forth between scenes?

Hi Everyone!

I would love some high level advice on the best way to switch game scenes. I have a level switcher in my game, which allows players to arbitrarily switch back and forth between scenes. (The level switcher is its own Scene, by the way.) Can anyone point me to any existing examples of this? (I haven’t found any in the Phaser 3 examples, and I think I’ve gone through all of them.)

I’ve tried to roll my own version of a scene switcher like this, but switching back to a previously loaded scene (using start) throws all kinds of errors for undefined properties. Probably there are some fundamentals that I don’t fully understand. Any advice much appreciated! :smile:

… after a bit more reading and experimentation:

It seems as if the context from which start is called is crucially important. If I’m correct in understanding this, calling start from a scene shuts down that scene and starts the new one. (https://rexrainbow.github.io/phaser3-rex-notes/docs/site/scenemanager/) So, if that’s correct, a switchLevel function like this should work:

const switchLevel = (oldScene, newSceneString) => {
  console.log(`From ${oldScene.scene.key} to ${newSceneString}`);
  oldScene.scene.start(newSceneString);
};

Which I should be able to call, for example, from a currently active scene like this:

switchLevel(this, "sceneC")

This is working in my little test case, but would love know from anyone out there if I’m off track here or there are any gotchas I need to know about… ?

Am I correct in assuming that this:

  • Keeps the preloaded assets in the oldScene in Phaser’s cache
  • Complete destroys the oldScene to free up the memory it occupied
  • starts the newScene , and, if the newScene had already been started at some previous time in the game, re-initialises it from scratch?

this.scene.start(…) will always stop the calling scene, yes.

If you’re controlling two scenes from a third scene, you could use instead of start():

// From 'c'
this.scene.stop('a').launch('b');

Likewise you could use instead of switch():

// From 'c'
this.scene.sleep('a').run('b');

All caches are global and independent of scene operations.

Stopped scenes aren’t removed, and restarted scenes are just restarted. It’s still the same scene, just in a new phase. Only scene add and remove alter that.

Thanks so much @samme, that explains a great deal! I haven’t found this documented clearly anywhere else so this is extremely helpful!!

You mentioned that stopped scenes aren’t removed. How does this affect memory? On the game I’m working on there are going to be dozens and dozens of scenes, most of them quite big, so I’d ideally like to completely remove them from memory before switching to a new scene. Should I rather be using add and remove?

You certainly could use add and remove instead of start and stop.

I would guess a stopped scene uses less memory than a running scene, because all of the scene contents are cleared. But more memory than zero.

Thanks @samme, I will try that :slight_smile: