plugins/lisa-phaser-agy/skills/phaser-scenes/SKILL.md
This skill should be used when creating or editing Phaser 4 scenes — the init/preload/create/update lifecycle, starting/stopping/sleeping scenes, running scenes in parallel (HUD/pause overlays), passing data between scenes, the registry, and event-based communication. Use it when adding a scene, wiring scene transitions, or debugging lifecycle/ordering issues. Pairs with phaser-project-structure, phaser-assets, and phaser-gameobjects.
npx skillsauth add codyswanngt/lisa phaser-scenesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Scenes are Phaser's unit of game-flow composition. The lifecycle is unchanged
from Phaser 3 — init(data) → preload() → create(data) → update(time, delta)
— and each scene owns its display list, input, camera, time events, and (if
enabled) physics world.
One scene class per file under src/scenes/, exported as a class whose key
matches the file name:
export class Game extends Phaser.Scene {
constructor() {
super("Game"); // the scene key — also a constant in src/assets.ts
}
init(data: GameStartData) { /* receive data, reset state */ }
preload() { /* per-scene late loads only — bulk loading is the Preloader's job */ }
create() { /* build GameObjects, wire input + events */ }
update(_time: number, delta: number) { /* per-frame; delta in ms */ }
}
init receives the data passed by scene.start(key, data) — type that payload
(an interface per scene) instead of any.preload in gameplay scenes should be rare; the Preloader scene loads the game
pack up front ([[phaser-assets]]). Use per-scene preload only for genuinely
scene-local or late-bound assets.create is where GameObjects are built. Everything constructed here must be
cleaned up on shutdown if it lives outside the scene's display list (timers on
other scenes, global event listeners, DOM elements).update(time, delta) runs per render frame. Frame-rate-independent movement
multiplies by delta; physics movement belongs in Arcade bodies, not manual
position math ([[phaser-physics]]).Via this.scene (the ScenePlugin):
start(key, data) — stop the current scene, start another.launch(key, data) — start another scene in parallel (HUD, pause overlay).pause / resume, sleep / wake — suspend update/render without rebuild.stop(key) — shuts a scene down (fires Phaser.Scenes.Events.SHUTDOWN).bringToTop / sendToBack — z-order between parallel scenes.Overlay pattern: Game launches HUD; HUD renders score/health and listens to
events from Game. Pause: launch Pause, this.scene.pause("Game").
In preference order:
gameScene.events.emit("score-changed", score). Always remove listeners on
SHUTDOWN: this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => …).scene.start/launch data — for handoff at transition time.this.registry) — game-wide key/value store with change
events; for cross-cutting state like settings or the run seed.Never reach into another scene's GameObjects directly
(this.scene.get("Game").player.x = …) — that couples scenes to each other's
display-list internals and breaks when the other scene rebuilds.
src/assets.ts (e.g. SceneKeys.Game) — super(SceneKeys.Game).src/logic/** and are called from the scene.init, not in field initializers — scene classes
are instantiated once but started many times; stale fields from a previous run
are a classic restart bug.A scene change is verified by booting the game (bun run dev) and exercising the
actual transition: start → play → (pause/resume or restart) → confirm no
duplicated listeners (events firing twice after a restart is the canonical
symptom of a missed SHUTDOWN cleanup).
development
Prepare a machine — a fresh laptop or a throwaway container — to run coding agents, before any repository exists. Detects which of Lisa's supported agents (Claude Code, Codex, Cursor, OpenCode, Antigravity, Copilot) are already installed, asks which credential manager the machine uses (Bitwarden, 1Password, Doppler, Vault, AWS, or none), and installs only what is missing, each by its vendor's own preferred method. Idempotent, headless by default, and emits a Dockerfile for a spin-up/spin-down environment. Run it on a new machine, in a container, or before cloning anything.
tools
Provision and verify a remote execution environment for a host project — Codex Cloud today, other remote surfaces as they are added. Generates a repository-owned setup script that installs the declared toolchain, materializes secrets through lisa-secrets-access, and runs the project's own hook. Provisions by API where one exists, by driving the vendor console where one does not, and by emitting exact config otherwise — then proves the result with the same read-back regardless of which tier did the work. Use before dispatching any work with executionEnv.
tools
Bring a developer's machine in line with the toolchain the project declares. Reports every tool in remoteEnv.tools that is missing, outdated, or unpinned for this platform, and installs the missing ones into ~/.local/bin from the same pinned, checksummed entries the remote surfaces use — but only when asked. Same manifest, same pins, same installers as lisa-setup-remote-env; what differs is consent and that the pin is a floor rather than an equality. Run it on a fresh checkout, after a manifest change, or when a tool fails at the moment of use.
tools
Route one unit of work to a remote execution surface. Reads the executionEnv parameter (local by default, codex-cloud or claude-web today), verifies the environment is provisioned and bound to this repository, submits a thin skill invocation, records the task identifier to .lisa/remote-dispatch.json, and exits without polling. Routing only — the remote runs the identical skill from the identical repository. Composable and inline: other skills invoke it via the Skill tool rather than users calling it directly.