DEVOLOGIST</>

Scene Lifecycle in Phaser 4: A Detailed Guide

Phaser
23/08/202610 min read

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. constructor
2. 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

Best Practices

Quick Cheat Sheet

constructor() // class setup
init(data) // reset state, receive data
preload() // load assets
create() // build scene
update() // per-frame logic
pause() // stop update temporarily
resume() // continue after pause
sleep() // temporarily inactive
wake() // reactivate slept scene
shutdown() // cleanup before stop/restart
destroy() // 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.