一键导入
phaser4-gamedev
// Build 2D browser games with Phaser 4: WebGL-first rendering, scenes, filters, lighting, shaders, DynamicTexture and RenderTexture, tilemaps, SpriteGPULayer, TilemapGPULayer, and Phaser 3 to 4 migration work.
// Build 2D browser games with Phaser 4: WebGL-first rendering, scenes, filters, lighting, shaders, DynamicTexture and RenderTexture, tilemaps, SpriteGPULayer, TilemapGPULayer, and Phaser 3 to 4 migration work.
Build 2D browser games with Phaser 3: scene lifecycle, sprites/animations, input, Arcade/Matter physics, tilemaps, performance, and game architecture.
Build 2D games with Phaser 3 framework. Covers scene lifecycle, sprites, physics (Arcade/Matter), tilemaps, animations, input handling, and game architecture. Trigger: "create phaser game", "add phaser scene", "phaser sprite", "phaser physics", "game development with phaser".
| name | phaser4-gamedev |
| description | Build 2D browser games with Phaser 4: WebGL-first rendering, scenes, filters, lighting, shaders, DynamicTexture and RenderTexture, tilemaps, SpriteGPULayer, TilemapGPULayer, and Phaser 3 to 4 migration work. |
| metadata | {"short-description":"Phaser 4 game dev and migration."} |
Build 2D browser games using Phaser 4's WebGL-first renderer, scene model, and updated rendering APIs.
Phaser 4 is not Phaser 3 with a few renamed methods. The renderer, filter model, shader assumptions, texture orientation, and batching behavior changed. Good Phaser 4 work starts by choosing the right rendering path and measuring assets before code is written.
Before coding, ask:
SpriteGPULayer, TilemapGPULayer, RenderTexture, or a plain Sprite solve this more cleanly?Core principles:
Read references/spritesheets-and-textures.md first.
Spritesheet loading is still fragile. A few pixels off in frame size, spacing, or margin can create silent corruption that looks like animation or rendering bugs later.
NEVER guess frame dimensions. DO NOT assume texture orientation details are irrelevant if compressed textures or custom shaders are involved.
Read references/migration-hotspots.md first.
Search for the Phaser 3 APIs that changed meaning or disappeared. These are where most migration time goes:
setTintFillBitmapMaskpreFX / postFXPhaser.Geom.PointMath.TAU / Math.PI2setPipeline('Light2D')DynamicTexture / RenderTextureTileSprite croppingRead these before working on the relevant feature:
| When working on... | Read first |
|---|---|
| Migrating Phaser 3 code | references/migration-hotspots.md |
| Loading spritesheets, atlases, compressed textures, or TileSprite | references/spritesheets-and-textures.md |
| Performance issues, GPU layers, filters, lighting, or batching | references/rendering-and-performance.md |
| Path | Use when |
|---|---|
| Standard game objects | Most gameplay, UI, and ordinary animation |
SpriteGPULayer | Very large numbers of mostly simple quads or particle-like members |
TilemapGPULayer | Very large orthographic tile layers using one tileset |
RenderTexture / DynamicTexture | You need capture, compositing, stamping, or texture reuse |
| Filters / Shader | The effect is genuinely image-space or shader-driven |
| System | Use when |
|---|---|
| Arcade | Platformers, shooters, most 2D action games |
| Matter | Physics puzzles, compound bodies, more realistic collisions |
| None | Menu scenes, card games, visual novels, strategy UIs |
scenes/
├── BootScene.ts # Asset loading, progress bar, shader/texture setup
├── MenuScene.ts # Title screen and options
├── GameScene.ts # Main gameplay
├── UIScene.ts # HUD overlay (launched in parallel)
└── GameOverScene.ts # End screen and restart flow
this.scene.start('GameScene', { level: 1 }); // Stop current, start new
this.scene.launch('UIScene'); // Run in parallel
this.scene.pause('GameScene'); // Pause
this.scene.stop('UIScene'); // Stop
Prefer explicit WebGL unless there is a concrete reason not to.
const config: Phaser.Types.Core.GameConfig = {
type: Phaser.WEBGL,
width: 800,
height: 600,
roundPixels: false,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
},
physics: {
default: 'arcade',
arcade: { gravity: { y: 300 }, debug: false }
},
scene: [BootScene, MenuScene, GameScene]
};
class GameScene extends Phaser.Scene {
init(data: unknown) {} // Receive data from previous scene
preload() {} // Load assets before create
create() {} // Set up game objects, physics, input
update(time: number, delta: number) {} // Use delta for frame-rate independence
}
// Correct: scales with frame rate
this.player.x += this.speed * (delta / 1000);
// Wrong: varies with frame rate
this.player.x += this.speed;
// Phaser 3
sprite.setTintFill(0xff0000);
// Phaser 4
sprite.setTint(0xff0000).setTintMode(Phaser.TintModes.FILL);
// Phaser 3
sprite.setPipeline('Light2D');
// Phaser 4
sprite.setLighting(true);
// Phaser 3
const mask = new Phaser.Display.Masks.BitmapMask(scene, maskObject);
sprite.setMask(mask);
// Phaser 4
sprite.filters.internal.addMask(maskObject);
Phaser 4 buffers drawing commands. If you queue drawing work into a DynamicTexture or RenderTexture, execute it deliberately.
const rt = this.add.renderTexture(0, 0, 256, 256);
rt.draw(sprite, 0, 0);
rt.render();
Use preserve() or render modes only when they solve a concrete problem. Extra indirection complicates debugging quickly.
Do not assume old roundPixels behavior. Phaser 4 defaults it to false, and per-object control is more explicit.
sprite.vertexRoundMode = 'safe';
Use rounding intentionally for pixel art. Leave it off for rotated, scaled, or camera-heavy scenes unless you want the visual tradeoff.
| Anti-pattern | Why it hurts | Better |
|---|---|---|
| Treating Phaser 4 as a drop-in Phaser 3 upgrade | You miss renderer, filter, shader, and texture changes | Audit migration hotspots first, then port intentionally |
| Starting new work on Canvas-first assumptions | Many Phaser 4 features are WebGL-centric or unavailable in Canvas | Design for WebGL and treat Canvas as fallback only if required |
| Guessing spritesheet or atlas metadata | Visual corruption appears far away from the actual mistake | Measure frames, spacing, margin, and bounds before loading |
| Using filters or shaders for every visual effect | More complexity, more batch breaks, harder debugging | Use plain sprites, textures, and tint where possible |
| Applying lighting or filters everywhere | Shader changes break batches and can tank performance | Reserve them for objects that benefit visually |
Forgetting render() on DynamicTexture or RenderTexture | Queued work never lands on the texture | Make render execution explicit in the workflow |
Using SpriteGPULayer for frequently mutated gameplay entities | Its strength is scale, not arbitrary object behavior | Keep complex interactive entities on normal game objects |
Assuming TilemapGPULayer is a universal tilemap replacement | It is orthographic-only and more constrained | Use it when the layer size and rendering profile justify it |
Making raw gl calls outside supported integration points | You can desync Phaser's renderer state | Use Extern or higher-level Phaser APIs |
Common pitfall: "the port compiles, so the migration is done." Rendering, shader, and texture bugs often survive the first compile.
Avoid converging on a single Phaser 4 setup. Choose based on context:
roundPixels off, safe per-object rounding, or deliberate full roundingUIScene vs in-scene HUDWhat should vary is the architecture, not the rigor. Measure assets, check batching costs, and adapt the solution to the game's real constraints.
Phaser 4 gives you a more capable renderer and more explicit rendering tools, but it expects better architectural choices in return.
Before coding: what rendering path are you choosing, what assets define the truth, and what batch-breaking features are actually worth their cost?
Codex can do strong Phaser 4 work when the problem is framed precisely: scene boundaries, asset dimensions, rendering constraints, performance targets, and migration scope. These guidelines illuminate the path; they do not replace engineering judgment.