npm phaser 3.50.0-beta.4
Phaser v3.50.0 Beta 4

latest releases: 3.80.1, 3.80.0, 3.80.0-beta.2...
3 years ago

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been
moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Display List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.95, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance over using regular Containers.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it'.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scene's to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.

Animation API New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes between two animations. Mixing allows you to specify a unique delay between a pairing of animations. When playing Animation A on a Game Object, if you then play Animation B, and a mix exists, it will wait for the specified delay to be over before playing Animation B. This allows you to customise smoothing between different types of animation, such as blending between an idle and a walk state, or a running and a firing state.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • The TextureTintStripPipeline now extends TextureTintPipeline and just changes the topolgy, vastly reducing the filesize.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • global.Phaser = Phaser has been removed, as it's no longer required by the UMD loader, which should make importing in Angular 10 easier. Fix #5212 (thanks @blackyale)
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. Fix #4824 (thanks @rexrainbow)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards

Don't miss a new phaser release

NewReleases is sending notifications on new releases.