v3-to-v4-migration
Use this skill when migrating a Phaser 3 project to Phaser 4, or when a user asks about breaking changes, API differences, or how to update their v3 code. Covers renderer changes (pipelines to render nodes), FX/masks to filters, tint system, camera matrix, texture coordinates, DynamicTexture, shader
By phaserjs · 458 installs
npx skills add phaserjs/phaser --skill v3-to-v4-migration
Source repository · Upstream listing
Phaser v3 to v4 Migration Guide
This guide covers everything you need to change when upgrading a Phaser v3 project to Phaser v4. It is organized from highest impact changes to smaller details, so you can work through it top to bottom.
Related skills: ../v4 new features/SKILL.md, ../game setup and config/SKILL.md, ../filters and postfx/SKILL.md
Table of Contents
1. [Renderer: Pipelines to Render Nodes]( 1 renderer pipelines to render nodes)
2. [Canvas Renderer Deprecated]( 2 canvas renderer deprecated)
3. [FX and Masks are now Filters]( 3 fx and masks are now filters)
4. [Tint System]( 4 tint system)
5. [Camera System]( 5 camera system)
6. [Texture Coordinates and GL Orientation]( 6 texture coordinates and gl orientation)
7. [DynamicTexture and RenderTexture]( 7 dynamictexture and rendertexture)
8. [Shader API]( 8 shader api)
9. [GLSL Loading]( 9 glsl loading)
10. [Lighting]( 10 lighting)
11. [TileSprite]( 11 tilesprite)
12. [Graphics and Shape]( 12 graphics and shape)
13. [Geometry: Point Replaced by Vector2]( 13 geometry point replaced by vector2)
14. [Math Constants]( 14 math constants)
15. [Data Structures]( 15 data structures)
16. [Round Pixels]( 16 round pixels)
17. [Removed Game Objects]( 17 removed game objects)
18. [Removed Plugins and Entry Points]( 18 removed plugins and entry points)
19. [Removed Utilities and Polyfills]( 19 removed utilities and polyfills)
20. [Spine Plugins]( 20 spine plugins)
21. [Miscellaneous Breaking Changes]( 21 miscellaneous breaking changes)
22. [Migration Checklist]( migration checklist)
1. Renderer: Pipelines to Render Nodes
Phaser v4 contains a brand new WebGL renderer. The entire rendering pipeline from v3 has been replaced. This is the single biggest change in v4.
What was removed:
The v3 Pipeline system has been removed entirely. Pipelines frequently held multiple responsibilities (e.g. the Utility pipeline handled various different rendering tasks) and each had to manage WebGL state independently, leading to conflicts where one pipeline could break another's assumptions.
What replaced it:
The new RenderNode architecture. Each render node handles a single rendering task, making the system more maintainable. All render nodes have a run method, and some have a batch method to assemble state from several sources before invoking run .
What this means for you:
If your game only uses the standard Phaser API (Sprites, Text, Tilemaps, etc.), the new renderer should work transparently.
If you wrote custom WebGL pipelines in v3, they will need to be rewritten as render nodes. Use RenderConfig renderNodes to register custom render nodes at boot.
If you accessed WebGLRenderer internals directly, be aware that many internal properties have been removed or restructured:
WebGLRenderer.textureIndexes is removed. Use glTextureUnits.unitIndices instead.
WebGLRenderer genericVertexBuffer and genericVertexData are removed (freeing ~16MB RAM/VRAM). BatchHandler render nodes now create their own WebGL data buffers.
WebGLAttribLocationWrapper is removed.
Do not make direct WebGL gl calls in a Phaser v4 game. This can change the WebGL state without updating the internal WebGLGlobalWrapper , causing unpredictable behavior. If you need direct WebGL access, use an Extern game object, which resets state after it finishes.
2. Canvas Renderer Deprecated
The Canvas renderer is still available but should be considered deprecated. Canvas rendering does not support any of the WebGL techniques used in v4's advanced rendering features. As WebGL support is effectively baseline today, we recommend WebGL for all new projects.
Canvas retains one advantage: 27 blend modes vs WebGL's 4 native modes (NORMAL, ADD, MULTIPLY, SCREEN). In v4, the new Blend filter can recreate all Canvas blend modes in WebGL, though it requires indirection through a CaptureFrame , DynamicTexture , or similar.
3. FX and Masks are now Filters
This is one of the most impactful changes for v3 users who relied on the FX or Mask systems.
What changed:
FX (pre and post) and Masks have been unified into a single Filter system. A Filter takes an input image and produces an output image, usually via a single shader. All filters are mutually compatible.
Key differences from v3:
No more preFX/postFX distinction. Filters are divided into internal (affects just the object) and external (affects the object in its rendering context, usually the full screen) lists.
No more object restrictions. In v3, only certain objects supported FX. In v4, filters can be applied to any game object or scene camera , including Extern objects.
BitmapMask removed. Use the new Mask filter instead. GeometryMask remains available in Canvas only.
Removed derived FX and their replacements:
v3 FX v4 Replacement
Bloom Phaser.Actions.AddEffectBloom()
Shine Phaser.Actions.AddEffectShine()
Circle Phaser.Actions.AddMaskShape()
Gradient Gradient game object
ColorMatrix change:
The ColorMatrix filter shifted its color management methods onto a colorMatrix property:
Mask migration:
4. Tint System
The tint system has been overhauled with a new API and additional blend modes.
Removed:
tintFill property
setTintFill() method
Replacement:
Use the new tintMode property or setTintMode() method to control tint blending.
Phaser.TintModes enumerates the available modes: MULTIPLY , FILL , ADD , SCREEN , OVERLAY , HARD LIGHT .
How to convert your code:
Other tint changes:
tint and setTint() now purely affect color settings. In v3, calling these would silently deactivate fill mode.
FILL mode now treats partial alpha correctly.
BitmapText tinting now works correctly.
5. Camera System
The camera matrix system has been rewritten. If you only use standard camera properties ( scrollX , scrollY , zoom , rotation ), your code should work without changes. However, if you access camera matrices directly, you must update your code.
What changed:
v3 v4
Camera matrix = position + rotation + zoom Camera matrix = rotation + zoom + scroll (no position)
Scroll appended separately Scroll is part of Camera matrix
No equivalent Camera matrixExternal = position only
No equivalent Camera matrixCombined = matrix matrixExternal
If you manipulated scroll factors manually:
Other camera changes:
GetCalcMatrix() now takes an additional ignoreCameraPosition parameter.
GetCalcMatrixResults now includes a matrixExternal property.
6. Texture Coordinates and GL Orientation
Phaser v3 used top left orientation for textures, which caused mismatches internally (framebuffers drawn upside down, then flipped). Phaser v4 uses GL orientation throughout, where Y=0 is at the bottom.
Action required:
If you use compressed textures , they must be re compressed with the Y axis starting at the bottom and increasing upwards. This is usually available as a "flip Y" option in your texture compression software.
Standard image textures (PNG, JPG, etc.) are handled automatically no action needed.
If you write custom shaders , note that texture coordinates now use GL conventions where Y=0 is at the bottom of the image.
7. DynamicTexture and RenderTexture
In v3, DynamicTexture allowed you to define batches and perform intricate drawing operations directly. In v4, many of these complex methods have been removed in favor of using the standard rendering system, which handles batching automatically.
Breaking change: DynamicTexture and RenderTexture must now call render() to execute all buffered drawing commands. Previously, draw commands were executed immediately.
New capabilities:
DynamicTexture preserve() keeps the command buffer for reuse after rendering, allowing you to re render commands that draw changing game objects.
DynamicTexture callback() inserts a callback to run during command buffer execution.
DynamicTexture capture renders game objects more accurately than draw , capturing the current camera view.
RenderTexture.renderMode property: "render" (draw like an Image), "redraw" (update texture during render loop without drawing), or "all" (both). The "redraw" mode enables updating textures mid render loop for same frame shader outputs.
TextureManager addDynamicTexture now has a forceEven parameter.
8. Shader API
The Shader game object has been significantly rewritten. Existing v3 shaders will need to be updated.
What changed:
The construction signature now takes a config object ( ShaderQuadConfig ) instead of individual parameters.
Shadertoy style uniforms (resolution, time, etc.) are no longer set automatically. Encode them into your configuration if needed.
Texture coordinates now use GL conventions (Y=0 at bottom).
New Shader setUniform(name, value) method for setting program uniforms individually.
New Shader renderImmediate method for rendering outside the regular render loop.
9. GLSL Loading
The way Phaser loads GLSL code has changed:
GLSL code is no longer classified as "fragment" or "vertex" when loaded. Under the new system it could be either, or both. You load shaders separately and combine them when creating a Shader.
Custom templates have been replaced with pragma preprocessor directives, which are valid GLSL and compatible with automated syntax checkers. The pragmas are removed before compilation.
10. Lighting
Lighting has been simplified and enhanced.
How to convert your code:
Other lighting changes:
Lighting is available on many game objects: BitmapText, Blitter, Graphics, Shape, Image, Sprite, Particles, SpriteGPULayer, Stamp, Text, TileSprite, Video, TilemapLayer, and TilemapGPULayer.
Objects can now cast self shadows using a shader that simulates shadows from surface features based on texture brightness. Configurable game wide or per object.
Lights now have a z value to set height explicitly, replacing the implicit height based on game resolution from v3.
Note: lighting changes the shader, which breaks render batches.
You can also use the ImageLight filter for image based lighting, but it is separate from the core lighting system.
11. TileSprite
TileSprite has been internally rewritten to use a new shader that manually controls texture coordinate wrapping instead of relying on WebGL texture wrapping parameters.
What changed:
TileSprite no longer supports texture cropping.
TileSprite now assigns default dimensions to each dimension separately.
New capabilities:
TileSprite now supports texture frames within atlases and spritesheets (v3 could only repeat the entire texture file).
New tileRotation property allows rotating the repeating texture.
Works correctly with compressed textures, non power of two textures, and DynamicTextures (all had issues in v3).
12. Graphics and Shape
Graphics has a new pathDetailThreshold property (also available as a game config option) that skips vertices within a certain distance of one another, improving performance on complex curves in small areas.
Grid shape has renamed properties: it now uses stroke instead of outline , matching the conventions of other Shape objects. Grid also has new controls for rendering gutters between cells and whether to draw outlines on the outside of the grid or just between cells.
Rectangle now supports rounded corners.
13. Geometry: Point Replaced by Vector2
The Geom.Point class and all related functions have been removed. Use Vector2 instead.
Quick reference for method replacements:
v3 ( Point ) v4 ( Vector2 / Math )
Point.Ceil Vector2.ceil
Point.Floor Vector2.floor
Point.Clone Vector2.clone
Point.CopyFrom(src, dest) dest.copy(src)