Phaser 4 Debugger
Use this skill to diagnose and fix Phaser 4 issues from evidence rather than guessing.
Workflow
- Collect the exact symptom, error text, stack trace, browser/device context, and reproduction steps when available.
- Read the relevant code before editing. For black screens, inspect
src/main.ts, scene registration, scene transitions, preload paths, and browser console/network errors.
- Trace likely root causes using Phaser lifecycle order: config, preload, create, update, asset keys, physics body creation, collisions, input, scene start/stop state, and rendering depth.
- Make the smallest fix that addresses the root cause.
- Verify with
npx tsc --noEmit for TypeScript projects and, when practical, a local dev-server smoke test.
Debugging Checklist
- Asset 404s and mismatched texture keys
- Scene not registered or wrong scene key
this.physics, this.input, or this.anims used before scene initialization
- Arcade body missing because object was created without physics
- Collider/overlap registered with the wrong object or group
- Animation key/frame mismatch
- Depth/alpha/camera bounds hiding an object
- Phaser 3 API usage after upgrading to Phaser 4
- Per-frame allocations, unbounded groups, and missing object pooling
- Timer events not tracked —
time.addEvent() without a stored reference accumulates across scene restarts
- Physics groups not explicitly destroyed — evolved weapon groups and spawn-phase groups leak if not
clear(true,true) + destroy()'d
- Stat mutations without base+modifiers — two systems writing the same stat in the same frame produce race-condition values
- Notification dedup by string equality — drops legitimate rapid repeat events (e.g. two coin pickups in 200 ms); use a time-window dedup instead
- Overlay/panel backdrops sized from module-level constants — freeze at boot size; use
this.cameras.main.width/height + resize listener
Common Silent Failure Categories
When the game freezes or behaves incorrectly with no console error, use these fast diagnostic paths before reaching for the full guide in references/agent-guidance.md.
Silent freeze (no error):
// Add to main.ts BEFORE new Phaser.Game(config)
window.onerror = (msg, _src, _line, _col, err) => {
console.error('GLOBAL ERROR:', msg, err?.stack);
};
window.onunhandledrejection = (ev) => {
console.error('UNHANDLED REJECTION:', ev.reason);
};
Then hard-refresh. Any previously silent failure will now log. See references/agent-guidance.md → Silent Freeze for the full checklist.
Spawns stop mid-session (no error):
Pool slot leak — entities leaving the camera view without recycling their slot. Add console.log('pool free:', pool.getTotalFree()) in your spawn call. If it hits zero and stays there, a slot is being held. See references/agent-guidance.md → Pool Slot Leak.
Forced animation plays one frame then reverts:
Entity update() overwrites forced animation one tick later. Fix with cinematicMode flag. See skills/phaser-animation/references/state-machine-patterns.md.
Speed or stat jumps to wrong value intermittently:
Two systems mutate the same stat on the same frame. Use base+modifiers pattern. See references/agent-guidance.md → Race Between Two Systems.
Stuck entity detection fires incorrectly (false positives or negatives):
body.velocity returns 0 when pushing against a wall. Use position-delta sampling instead. See references/agent-guidance.md → Stuck Detection Fails.
Full Guidance
For the complete diagnostic playbook, read references/agent-guidance.md. It is copied from the Claude subagent definition but should be applied as a portable skill; ignore Claude-only fields such as model, color, and tools.
1---2name: phaser-debugger3description: This skill should be used when the user reports a Phaser 4 bug, black screen, missing sprite, failed collision, broken physics, animation issue, crash, console error, performance problem, slow game, save/load issue, mobile runtime issue, or unexpected gameplay behavior.4---56# Phaser 4 Debugger78Use this skill to diagnose and fix Phaser 4 issues from evidence rather than guessing.910## Workflow11121. Collect the exact symptom, error text, stack trace, browser/device context, and reproduction steps when available.132. Read the relevant code before editing. For black screens, inspect `src/main.ts`, scene registration, scene transitions, preload paths, and browser console/network errors.143. Trace likely root causes using Phaser lifecycle order: config, preload, create, update, asset keys, physics body creation, collisions, input, scene start/stop state, and rendering depth.154. Make the smallest fix that addresses the root cause.165. Verify with `npx tsc --noEmit` for TypeScript projects and, when practical, a local dev-server smoke test.1718## Debugging Checklist1920- Asset 404s and mismatched texture keys21- Scene not registered or wrong scene key22- `this.physics`, `this.input`, or `this.anims` used before scene initialization23- Arcade body missing because object was created without physics24- Collider/overlap registered with the wrong object or group25- Animation key/frame mismatch26- Depth/alpha/camera bounds hiding an object27- Phaser 3 API usage after upgrading to Phaser 428- Per-frame allocations, unbounded groups, and missing object pooling29- **Timer events not tracked** — `time.addEvent()` without a stored reference accumulates across scene restarts30- **Physics groups not explicitly destroyed** — evolved weapon groups and spawn-phase groups leak if not `clear(true,true)` + `destroy()`'d31- **Stat mutations without base+modifiers** — two systems writing the same stat in the same frame produce race-condition values32- **Notification dedup by string equality** — drops legitimate rapid repeat events (e.g. two coin pickups in 200 ms); use a time-window dedup instead33- **Overlay/panel backdrops sized from module-level constants** — freeze at boot size; use `this.cameras.main.width/height` + resize listener3435## Common Silent Failure Categories3637When the game freezes or behaves incorrectly with **no console error**, use these fast diagnostic paths before reaching for the full guide in `references/agent-guidance.md`.3839**Silent freeze (no error):**40```typescript41// Add to main.ts BEFORE new Phaser.Game(config)42window.onerror = (msg, _src, _line, _col, err) => {43 console.error('GLOBAL ERROR:', msg, err?.stack);44};45window.onunhandledrejection = (ev) => {46 console.error('UNHANDLED REJECTION:', ev.reason);47};48```49Then hard-refresh. Any previously silent failure will now log. See `references/agent-guidance.md → Silent Freeze` for the full checklist.5051**Spawns stop mid-session (no error):**52Pool slot leak — entities leaving the camera view without recycling their slot. Add `console.log('pool free:', pool.getTotalFree())` in your spawn call. If it hits zero and stays there, a slot is being held. See `references/agent-guidance.md → Pool Slot Leak`.5354**Forced animation plays one frame then reverts:**55Entity `update()` overwrites forced animation one tick later. Fix with `cinematicMode` flag. See `skills/phaser-animation/references/state-machine-patterns.md`.5657**Speed or stat jumps to wrong value intermittently:**58Two systems mutate the same stat on the same frame. Use base+modifiers pattern. See `references/agent-guidance.md → Race Between Two Systems`.5960**Stuck entity detection fires incorrectly (false positives or negatives):**61`body.velocity` returns 0 when pushing against a wall. Use position-delta sampling instead. See `references/agent-guidance.md → Stuck Detection Fails`.6263## Full Guidance6465For the complete diagnostic playbook, read `references/agent-guidance.md`. It is copied from the Claude subagent definition but should be applied as a portable skill; ignore Claude-only fields such as `model`, `color`, and `tools`.