Skip to content
Back to skills

Dev Phaser Fundamentals

ASecurity

Phaser game configuration, scenes, and lifecycle management

  • 666 stars
  • 0 votes
  • 4 copies
  • 12 views
  • Added February 8, 2026
documentationtypescriptgitapidocumentation

Works with

  • cursor
  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill dev-phaser-fundamentals --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dev Phaser Fundamentals?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dev Phaser Fundamentals
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-dev-phaser-fundamentals/badge)](https://www.skillsdirectory.com/skills/majiayu000-dev-phaser-fundamentals)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dev-phaser-fundamentals
description: Phaser game configuration, scenes, and lifecycle management
---

# Phaser Fundamentals

> "2D web games made simple – scenes, sprites, and physics."

## When to Use This Skill

Use when:

- Setting up a new Phaser game
- Creating game scenes
- Implementing the scene lifecycle (preload/create/update)
- Configuring game settings (scale, physics, renderer)
- Setting up the game container and canvas

## Quick Start

```typescript
import Phaser from "phaser";
import { MainScene } from "./scenes/MainScene";

const config: Phaser.Types.Core.GameConfig = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  parent: "game-container",
  backgroundColor: "#000000",
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
  },
  physics: {
    default: "arcade",
    arcade: {
      gravity: { y: 300 },
      debug: false,
    },
  },
  scene: [MainScene],
};

new Phaser.Game(config);
```

## Before/After: Manual DOM vs Phaser Pattern

### ❌ Before: Manual DOM Manipulation

```typescript
// Manual game loop without Phaser
const canvas = document.getElementById("game") as HTMLCanvasElement;
const ctx = canvas.getContext("2d")!;

let playerX = 400;
let playerY = 300;

// Manual asset loading
const playerImg = new Image();
playerImg.src = "assets/player.png";
playerImg.onload = () => {
  gameLoop();
};

// Manual game loop
function gameLoop() {
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw player
  ctx.drawImage(playerImg, playerX, playerY);

  // Handle input manually
  document.addEventListener("keydown", (e) => {
    if (e.key === "ArrowLeft") playerX -= 5;
    // ... more manual input handling
  });

  requestAnimationFrame(gameLoop);
}
```

**Problems:**
- Manual asset loading (no preload queue)
- No sprite management
- Manual collision detection
- No physics engine
- Scene management is manual

### ✅ After: Phaser Pattern

```typescript
// Phaser handles everything
export class GameScene extends Phaser.Scene {
  private player!: Phaser.Physics.Arcade.Sprite;

  preload() {
    // Built-in asset loading with progress tracking
    this.load.image("player", "assets/player.png");
  }

  create() {
    // Physics-enabled sprite
    this.player = this.physics.add.sprite(400, 300, "player");

    // Built-in input handling
    this.cursors = this.input.keyboard!.createCursorKeys();
  }

  update() {
    // Frame-independent movement
    if (this.cursors.left!.isDown) {
      this.player.setVelocityX(-160);
    }
    // Built-in physics handles position updates
  }
}

const config = {
  // Phaser manages the game loop, canvas, rendering
  scene: [GameScene],
  physics: { default: "arcade" },
};

new Phaser.Game(config);
```

**Benefits:**
- Asset preloading with progress events
- Built-in physics engine
- Scene lifecycle management
- Input handling abstraction
- Optimized rendering pipeline

## Decision Framework

| Need               | Use                                   |
| ------------------ | ------------------------------------- |
| Basic 2D game      | `Phaser.AUTO` renderer type           |
| Physics platformer | Arcade physics with gravity           |
| Physics puzzle     | Matter physics for realism            |
| Responsive layout  | `Phaser.Scale.FIT` with `CENTER_BOTH` |
| Multiple scenes    | Array of scene classes in config      |

## Progressive Guide

### Level 1: Basic Scene Setup

```typescript
export class MainScene extends Phaser.Scene {
  constructor() {
    super({ key: "MainScene" });
  }

  preload() {
    // Load assets before create()
    this.load.image("player", "assets/player.png");
    this.load.image("background", "assets/bg.png");
  }

  create() {
    // Create game objects
    this.add.image(400, 300, "background");
    this.player = this.physics.add.sprite(400, 300, "player");
  }

  update(time: number, delta: number) {
    // Game loop (60fps)
    // delta = time since last frame in ms
  }
}
```

### Level 2: Scene Configuration with Data

```typescript
export class GameScene extends Phaser.Scene {
  constructor() {
    super({ key: "GameScene", active: false });
  }

  init(data: { level: number; score: number }) {
    // Receive data from previous scene
    this.level = data.level || 1;
    this.score = data.score || 0;
  }

  preload() {
    // Load level-specific assets
    this.load.image(`level${this.level}`, `assets/level${this.level}.png`);
  }

  create() {
    // Setup game objects
    this.createPlayer();
    this.createEnemies();
  }

  update(time: number, delta: number) {
    this.updatePlayer();
    this.updateEnemies();
  }
}
```

### Level 3: Game Config with Multiple Scenes

```typescript
const config: Phaser.Types.Core.GameConfig = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  parent: "game-container",
  backgroundColor: "#2d2d2d",
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    width: 800,
    height: 600,
  },
  physics: {
    default: "arcade",
    arcade: {
      gravity: { x: 0, y: 1000 },
      debug: false,
    },
  },
  scene: [BootScene, PreloadScene, TitleScene, GameScene, UIScene],
  pipeline: { CustomPipeline: CustomPipeline },
};
```

### Level 4: Custom Game Config Extension

```typescript
interface ExtendedGameConfig extends Phaser.Types.Core.GameConfig {
  customSettings: {
    maxPlayers: number;
    gameMode: "deathmatch" | "capture";
  };
}

class CustomGame extends Phaser.Game {
  constructor(config: ExtendedGameConfig) {
    super(config);
    this.customSettings = config.customSettings;
  }
}
```

### Level 5: Scene Manager Control

```typescript
export class MainScene extends Phaser.Scene {
  create() {
    // Scene transitions
    this.scene.start("GameScene", { level: 1 });

    // Launch parallel scene (UI overlay)
    this.scene.launch("UIScene");

    // Pause current scene
    this.scene.pause();

    // Sleep scene (stops update but keeps rendering)
    this.scene.sleep("BackgroundScene");

    // Stop and remove scene
    this.scene.stop("OldScene");
  }
}
```

## Anti-Patterns

❌ **DON'T:**

- Load assets in `create()` - use `preload()`
- Create new objects in `update()` - causes GC pressure
- Use `this.scene.restart()` frequently - expensive operation
- Forget to call `super()` in scene constructor
- Use hardcoded screen dimensions - use scale manager
- Mix physics and non-physics objects without planning

✅ **DO:**

- Preload all assets in `preload()` before use
- Reuse objects with object pooling in `update()`
- Use scene data for passing values between scenes
- Clean up event listeners in `shutdown()` method
- Use `scale.manager` for responsive sizing
- Group related game objects with `this.add.group()`

## Code Patterns

### Scene Lifecycle Management

```typescript
export class GameScene extends Phaser.Scene {
  private player!: Phaser.Physics.Arcade.Sprite;
  private enemies!: Phaser.GameObjects.Group;
  private cursors!: Phaser.Types.Input.Keyboard.CursorKeys;

  constructor() {
    super({ key: "GameScene" });
  }

  create() {
    // Always setup shutdown for cleanup
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, this.shutdown, this);
  }

  shutdown() {
    // Clean up listeners
    this.input.keyboard!.off("keydown-ESC");
  }

  update(time: number, delta: number) {
    // Use delta for frame-independent movement
    const dt = delta / 1000; // Convert to seconds
  }
}
```

### Scale Manager Pattern

```typescript
const config: Phaser.Types.Core.GameConfig = {
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    width: 800,
    height: 600,
  },
};

// In scene, get scale info
this.scale.width; // Actual canvas width
this.scale.height; // Actual canvas height
```

## Checklist

Before completing Phaser setup:

- [ ] Game config has proper scale settings
- [ ] Physics configured correctly (arcade or matter)
- [ ] Scene keys are unique
- [ ] Assets preloaded before use in create()
- [ ] Update loop is performant (no object creation)
- [ ] Shutdown handlers for cleanup
- [ ] Responsive scaling configured
- [ ] Scene transitions use proper data passing

## Common Issues

| Issue               | Solution                                 |
| ------------------- | ---------------------------------------- |
| Assets not loading  | Check `preload()` runs before `create()` |
| Physics not working | Verify physics config and body type      |
| Scene not updating  | Check scene is `active: true`            |
| Canvas size wrong   | Configure scale manager                  |
| Memory leaks        | Clean up in `shutdown()`                 |

## Reference

- [Phaser 3 Documentation](https://photonstorm.github.io/phaser3-docs/) — Official API docs
- [Phaser Examples](https://phaser.io/examples) — Code examples
- [Phaser TypeScript Types](https://github.com/photonstorm/phaser/tree/master/types) — Type definitions

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.