Skip to content

Scenes

A scene is a self-contained slice of your game — a title screen, a gameplay level, a pause menu. Scenes own entities and receive lifecycle callbacks as they are pushed onto or popped from the scene stack.

Extend the Scene base class:

import { Scene } from "@yagejs/core";
class GameplayScene extends Scene {
readonly name = "gameplay";
readonly pauseBelow = true; // pause scenes underneath
readonly transparentBelow = false; // hide scenes underneath
onEnter() {
const player = this.spawn("player");
player.add(new Transform(400, 300));
player.add(new PlayerController());
}
onExit() {
// cleanup when this scene is removed from the stack
}
onPause() {
// another scene was pushed on top
}
onResume() {
// the scene on top was popped, this scene is active again
}
}
PropertyDefaultPurpose
nameUnique identifier for the scene
pauseBelowfalseWhen true, scenes below this one stop updating
transparentBelowfalseWhen true, scenes below this one still render

A pause menu typically sets both pauseBelow: true and transparentBelow: true — the game world is visible but frozen underneath.

The engine exposes a stack-based scene manager:

// Push a new scene onto the stack
engine.scenes.push(new GameplayScene());
// Pop the top scene
engine.scenes.pop();
// Replace the top scene (pop + push in one call)
engine.scenes.replace(new GameOverScene());
// Get the currently active (top) scene
const current = engine.scenes.active;
push(A) → A.onEnter()
push(B) → A.onPause() → B.onEnter()
pop() → B.onExit() → A.onResume()
replace(C) → B.onExit() → C.onEnter()

Scenes provide helpers to find entities:

// Find an entity by name (returns first match or undefined)
const player = scene.findEntity("player");
// Find all entities with a given tag
const enemies = scene.findEntitiesByTag("enemy");
// Get all entities in the scene
const all = scene.getEntities();

Scenes are always classes. Override onEnter to spawn entities, resolve services, and wire up the scene:

import { Scene, Transform } from "@yagejs/core";
import { SpriteComponent, CameraKey } from "@yagejs/renderer";
import { InputManagerKey } from "@yagejs/input";
class TitleScene extends Scene {
readonly name = "title";
onEnter() {
const logo = this.spawn("logo");
logo.add(new Transform(640, 200));
logo.add(new SpriteComponent({ textureKey: "logo.png" }));
const input = this.context.resolve(InputManagerKey);
input.onPressed("start", () => {
this.context.resolve(SceneManagerKey).replace(new GameplayScene());
});
}
}
engine.scenes.push(new TitleScene());