Scene Lifecycle in Phaser 4: A Detailed Guide
The scene lifecycle is the sequence of steps Phaser follows to create, start, run, pause, stop, shut down, and destroy a scene.
If you understand the lifecycle well, you can load assets at the right time, initialize variables correctly, avoid duplicate objects, manage scene restarts safely, and clean up events and memory properly.
In Phaser 4, a scene typically moves through these stages:
constructor -> init -> preload -> create -> update -> pause/resume -> sleep/wake -> shutdown -> destroy
For scene switching and restart behavior, you may also want to read our related guides on Restarting a Scene in Phaser 4 and Mastering Scene Switching in Phaser 4.
1. Scene Constructor
The constructor runs when the scene class is created in JavaScript, before Phaser actually starts the scene.
export default class GameScene extends Phaser.Scene {constructor() {super({ key: 'GameScene' });this.score = 0;}}
Use it for setting the scene key, defining class-level defaults, and creating static references. Avoid loading assets or creating game objects here because the scene is not fully running yet.
2. init(data)
The init() method runs right before preload() and create(). It is used to prepare the scene for a new run.
init(data) {this.level = data.level ?? 1;this.score = data.score ?? 0;this.lives = data.lives ?? 3;}
Use init() to receive data from another scene, reset scene state, prepare variables, and set flags and counters.
3. preload()
The preload() method is used for loading assets before the scene is created.
preload() {this.load.image('player', 'assets/player.png');this.load.image('enemy', 'assets/enemy.png');this.load.audio('jump', 'assets/jump.mp3');}
Use it for images, spritesheets, audio, tilemaps, JSON, fonts, and other external resources. Do not create gameplay objects here.
4. create()
The create() method runs after assets are loaded. This is where you build the scene.
create() {this.player = this.add.image(400, 300, 'player');this.enemy = this.add.image(600, 300, 'enemy');this.scoreText = this.add.text(20, 20, `Score: ${this.score}`, {fontSize: '24px',color: '#ffffff'});}
Use create() for creating sprites, text, UI, physics, input, timers, groups, containers, and scene events. This is where most level setup happens.
5. update(time, delta)
The update() method runs every frame. It is the game loop.
update(time, delta) {this.player.x += 2;}
Use it for movement, animation logic, input checking, AI behavior, and frame-by-frame state updates. Avoid loading assets or creating objects here.
Lifecycle Flow in Practice
1. constructor2. init(data)3. preload()4. create()5. update()6. update()7. update()...
6. Pause and Resume
A scene can be paused without being destroyed. When paused, update stops running, but objects remain in memory.
this.scene.pause();
And you can resume it later:
this.scene.resume();
7. Sleep and Wake
Sleeping is similar to pausing, but is often used when a scene should stop updating temporarily and be brought back later.
this.scene.sleep();this.scene.wake();
This is useful when showing a menu on top of the game or switching between UI layers.
8. Shutdown
shutdown happens when the scene is stopped or restarted. This is a very important cleanup stage.
create() {this.handleKey = () => {console.log('R pressed');};this.input.keyboard.on('keydown-R', this.handleKey);this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {this.input.keyboard.off('keydown-R', this.handleKey);});}
Without cleanup, restarting a scene can create duplicate listeners and bugs.
9. Destroy
destroy() is the final removal of the scene. This happens when the scene is no longer needed at all.
The key difference is: shutdown means the scene may be used again, while destroy means it is gone permanently.
Example: Complete Scene Lifecycle
import Phaser from 'phaser';export default class GameScene extends Phaser.Scene {constructor() {super({ key: 'GameScene' });this.score = 0;}init(data) {this.level = data.level ?? 1;this.score = data.score ?? 0;console.log('init', data);}preload() {this.load.image('player', 'assets/player.png');this.load.image('enemy', 'assets/enemy.png');}create() {this.player = this.add.image(400, 300, 'player');this.enemy = this.add.image(600, 300, 'enemy');this.scoreText = this.add.text(20, 20, `Score: ${this.score}`, {fontSize: '24px',color: '#ffffff'});this.handleRestart = () => {this.scene.restart();};this.input.keyboard.on('keydown-R', this.handleRestart);this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {this.input.keyboard.off('keydown-R', this.handleRestart);});}update(time, delta) {this.player.x += 1;}}
What Runs Again on Restart?
When you call this.scene.restart(), Phaser typically runs the scene lifecycle again from the beginning, which is whyinit() is ideal for resetting variables.
Common Mistakes
- Creating objects in the constructor instead of
create(). - Forgetting cleanup on
shutdown. - Putting asset loading in
preload()instead ofcreate(). - Using
update()for one-time setup.
Best Practices
- Use the constructor only for scene setup, not gameplay objects.
- Use
init()to reset state and receive incoming data. - Use
preload()for assets. - Use
create()for building the scene. - Use
update()for continuous gameplay logic. - Use
shutdownto clean up listeners and temporary resources. - Use
destroy()only for permanent removal.
Quick Cheat Sheet
constructor() // class setupinit(data) // reset state, receive datapreload() // load assetscreate() // build sceneupdate() // per-frame logicpause() // stop update temporarilyresume() // continue after pausesleep() // temporarily inactivewake() // reactivate slept sceneshutdown() // cleanup before stop/restartdestroy() // remove permanently
FAQ
What is the Phaser scene lifecycle?
The scene lifecycle is the sequence Phaser follows to create, start, run, pause, stop, shut down, and destroy a scene. The main stages are constructor, init, preload, create, update, shutdown, and destroy.
What is the difference between init() and create() in Phaser 4?
init() runs before preload and create, and is used to prepare state and receive data. create() runs after assets are loaded and is used to build the scene, add objects, register input, and create UI.
When should I use shutdown?
Use shutdown to clean up scene-owned resources such as timers, event listeners, keyboard callbacks, and custom subscriptions before a scene stops or restarts.
What is the difference between shutdown and destroy?
shutdown means the scene is being stopped or restarted but may be used again later, while destroy means the scene is permanently removed and will not be reused.
Conclusion
If you understand the Phaser 4 scene lifecycle, you can structure your game cleanly, avoid duplicate objects, manage restarts safely, and keep your scenes maintainable as your project grows.