| name | phaser-migrate |
| description | This skill should be used when the user asks to "migrate from Phaser 3", "upgrade to Phaser 4", "convert my v3 game", "Phaser 3 to 4 migration", "update Phaser version", "my Phaser 3 game broke after upgrading", "behavior changed after RC upgrade", "RC6 to RC7 migration", or has code that uses deprecated or removed Phaser 3 APIs or behavior that silently drifted between Phaser 4 RC releases. |
| version | 0.5.0 |
Phaser 3 → Phaser 4 Migration
Migrating from Phaser 3 to Phaser 4 is mostly straightforward. The core public API is preserved. This skill covers every breaking change and how to fix it — AND also covers RC-to-RC behavioral drift within Phaser 4 (e.g., RC6 → RC7) where APIs silently changed semantics between RC releases.
Step 1 — Update the Package
npm uninstall phaser
npm install phaser@beta
Verify installed version:
node -e "const p = require('phaser'); console.log(p.VERSION)"
Should print 4.0.0-rc.7 (or later RC).
Step 2 — Scan for Breaking Changes
Run these grep searches to find every issue in your src/ directory:
grep -rn "Geom\.Point\|new Phaser\.Geom\.Point\|Geom\.Point\." src/
grep -rn "Math\.PI2\b" src/
grep -rn "Phaser\.Structs\." src/
grep -rn "DynamicTexture\|RenderTexture\|addDynamicTexture\|addRenderTexture" src/
grep -rn "Camera3D\|Layer3D\|FacebookInstant\|SpinePlugin\|SpineFile" src/
grep -rn "tileSprite.*setCrop\|setCrop.*tileSprite" src/
grep -rn "Create\.GenerateTexture\|Phaser\.Create\." src/
grep -rn "spine\|Spine" src/ -i
grep -rn "phaser-ie9" .
grep -rn "createGeometryMask\|setBitmapMask\|setMask\b\|clearMask" src/
Step 3 — Apply Fixes
Fix 1: Geom.Point → Vector2
Phaser.Geom.Point is completely removed. Use Phaser.Math.Vector2.
const point = new Phaser.Geom.Point(x, y);
point.x = 100;
const distance = Phaser.Geom.Point.GetMagnitude(point);
const clone = Phaser.Geom.Point.Clone(point);
Phaser.Geom.Point.SetMagnitude(point, 50);
const point = new Phaser.Math.Vector2(x, y);
point.x = 100;
const distance = point.length();
const clone = point.clone();
point.setLength(50);
Full Point → Vector2 method mapping:
| Phaser 3 (static) | Phaser 4 (instance) |
|---|
Point.GetMagnitude(pt) | pt.length() |
Point.Clone(pt) | pt.clone() |
Point.SetMagnitude(pt, n) | pt.setLength(n) |
Point.Ceil(pt) | pt.ceil() |
Point.Floor(pt) | pt.floor() |
Point.Invert(pt) | pt.invert() |
Point.Negative(pt) | pt.negate() |
Point.Project(pt, target, out) | pt.project(target) |
Point.GetCentroid(points) | Phaser.Math.GetCentroid(points) |
Point.GetRectangleFromPoints(pts) | Phaser.Math.GetVec2Bounds(pts) |
All Geometry classes (Circle, Ellipse, Line, Rectangle, Triangle, Polygon) now return Vector2 instead of Point for point-related results.
Fix 2: Math.PI2 → Math.TAU
const fullRotation = Math.PI2;
const fullRotation = Math.TAU;
const halfRotation = Math.PI_OVER_2;
Fix 3: Phaser.Structs → Native JS
const myMap = new Phaser.Structs.Map([]);
myMap.set('key', value);
myMap.get('key');
myMap.delete('key');
myMap.getArray();
const mySet = new Phaser.Structs.Set();
mySet.set(value);
mySet.delete(value);
mySet.contains(value);
const myMap = new Map<string, any>();
myMap.set('key', value);
myMap.get('key');
myMap.delete('key');
[...myMap.values()];
const mySet = new Set<any>();
mySet.add(value);
mySet.delete(value);
mySet.has(value);
Fix 4: DynamicTexture / RenderTexture — Add render()
const dynTex = this.textures.addDynamicTexture('key', 200, 200);
dynTex.draw('sprite', 0, 0);
const dynTex = this.textures.addDynamicTexture('key', 200, 200);
dynTex.draw('sprite', 0, 0);
dynTex.render();
Fix 5: Removed Plugins
Camera3D — no replacement. Phaser 4 is 2D only. If 3D is needed, use Three.js alongside Phaser.
Layer3D — no replacement. Removed with Camera3D.
Facebook Instant Games — removed. Facebook no longer supports this platform.
Spine Plugin (official v3/v4 Spine support) — use the official Esoteric Software Phaser plugin instead. The Phaser bundled Spine plugin is no longer maintained.
Fix 6: TileSprite Cropping
TileSprite no longer supports texture cropping in Phaser 4.
const ts = this.add.tileSprite(x, y, w, h, 'texture');
ts.setCrop(0, 0, 100, 100);
const rt = this.add.renderTexture(x, y, 100, 100);
rt.draw('texture', 0, 0);
rt.render();
Fix 7: Create.GenerateTexture Removed
Phaser.Create.GenerateTexture and all Create Palettes are removed.
const texture = Phaser.Create.GenerateTexture({ data: palettes, pixelWidth: 2 });
const gfx = this.add.graphics();
gfx.fillStyle(0xff0000);
gfx.fillRect(0, 0, 16, 16);
gfx.generateTexture('red-square', 16, 16);
gfx.destroy();
Fix 8: Removed IE9 Entry Point
import Phaser from 'phaser/src/phaser-ie9.js';
import Phaser from 'phaser';
Fix 9: WebGL Geometry Masks → Scissor / Viewport Clipping
Phaser 4 changed how WebGL masks work. Stencil-buffer geometry masks from v3 either silently no-op or produce incorrect results in v4's Beam renderer. Camera viewport clipping is the correct replacement for rectangular clip regions.
const shape = this.add.graphics().fillRect(x, y, w, h);
const mask = shape.createGeometryMask();
targetSprite.setMask(mask);
this.cameras.main.setViewport(x, y, w, h);
const { width, height } = this.scale;
this.cameras.main.setViewport(0, 0, width, height);
If you need a mask on a non-camera object (e.g. a sprite with a custom clip region), use a bitmap mask with a Graphics texture rather than a geometry mask.
Step 4 — Update TypeScript Config
If using TypeScript, ensure tsconfig.json is correct for v4:
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"typeRoots": ["./node_modules/phaser/types"],
"types": ["Phaser"]
}
}
Step 5 — Verify and Test
npx tsc --noEmit
npm run dev
Check in browser:
- No console errors on startup
- All scenes load correctly
- Physics behaves the same as v3
- Animations play correctly
Quick Migration Checklist
Additional Resources
Reference Files
references/v3-to-v4-changes.md — Complete changelog of all Phaser v3→v4 breaking changes, including renderer internals, deprecated APIs, and behavior differences
references/rc6-to-rc7-changes.md — Behavioral drift between Phaser 4 RC releases (masks, animations, camera, tilemap, groups, scene events, scale manager). Read when upgrading RC versions OR when code that worked in an earlier RC silently misbehaves.