Phaser Scene Management: How We Structure 9 Scenes

Phaser Scene Management: How We Structure 9 Scenes

Direct answer: Keep one scene per screen, load assets only in a dedicated BootScene, and share game state through the registry or a module — not through scene-to-scene property passing. A 9-scene game stays readable if each scene only knows its own UI and the transitions it owns.

Merge Fish 2048 is built with 9 scenes. Here is exactly how they are laid out and why.

1. Our scene map

SceneJobLoads assets?
BootScenePreloads all assets, shows progress barYes — everything
MenuSceneMain menu, mode pickNo
GameSceneGameplay: board, input, HUD, animationsNo
GameOverSceneGame over / victory overlayNo
LevelSelectSceneChapter & level grid, stars, progressNo
AquariumSceneFish collection / aquariumNo
RankSceneRank / achievement boardNo
HelpSceneHow-to-play overlayNo
SettingsSceneMusic / SFX togglesNo

The rule we follow: assets load exactly once, in BootScene. Every other scene is instant because textures, audio, and fonts are already in the cache. A scene that needs an image it didn’t load is a bug waiting to happen.

2. The boot → menu → game flow

// main.js — Phaser config
scenes: [BootScene, MenuScene, GameScene, GameOverScene,
         LevelSelectScene, AquariumScene, RankScene, HelpScene, SettingsScene]

One decision that saved us hours: each scene owns its transitions. GameScene knows it can go to GameOverScene or SettingsScene, but it does not know about AquariumScene. When we added the aquarium later, we only touched MenuScene and one button — no ripple through the rest.

3. Cross-scene state without spaghetti

Player data (best score, music on/off, per-mode stats) lives in a Storage module, not in scene properties:

// anywhere in any scene
Storage.get('best_score');   // -> number
Storage.set('music_on', false);

Scenes read and write through this single module. The Phaser registry works too, but a module has one advantage: it can persist to localStorage in the same call, so you never lose state when a scene restarts. For a merge game where the player’s best score must survive scene switches and page reloads, that is the difference between “it works” and “it works on Tuesday but not after refresh”.

4. Overlay scenes instead of stacking UI

Help and Settings are full scenes layered on top of the current screen, not modal containers inside GameScene. Each opens with this.scene.launch('Settings') and closes with this.scene.stop(). Launch/stop keeps the gameplay scene alive underneath — pause the game on launch, resume on stop, and you get a pause menu for free without a single line of modal code.

Common mistakes


Written by ruofan, independent HTML5 game developer. Structure and numbers come from Merge Fish 2048 (Phaser 3.90 + Vite), a game we’re building. API details: Phaser scene docs.