Phaser World Issue 217

After a long hiatus from the newsletter due to some technical issues with our old provider, we’re back with another round of news from the Phaser community. Once again, Gamedev.js Jam is back in 2025. We’ve also got 2 tutorials, 2 games, and a massive devlog from Ben with Phaser 4 updates for your reading pleasure.

This week:

📆 Events

» Gamedev.js Jam 2025

Phaser Studio returns as a Gold sponsor for Gamedev.js 2025.

The rules are simple: make a game using any version of Phaser. Four winners will each get $250 cash. Ten more winners will get Vampire Survivors game bundles with all DLCs.

Focused on games made for the web, you have 13 days from April 13th and 26th 2025 to build and submit your Phaser game.

The best part about Gamedev.js Jam, submit one game into as many challenges as you like!

🎦 Phaser Showcase

» Raccoon on the Run

A charming arcade adventure reminiscent of the classic 8-bit game Frogger. Dash through busy streets, leap over rivers and dodge wild obstacles—all while racing the clock and hoarding delicious treats. Play solo and race up the global leaderboard, or go head-to-head with friends in chaotic multiplayer fun—right on Discord.

» Mahjong Tour

Mahjong Tour, a vibrant Mahjong tile-matching puzzle adventure, whisks you away on a cultural journey through ancient secrets and breathtaking landscapes. Follow the glowing markers that guide you upward through increasingly challenging levels.

🚀Studio Releases

» Phaser Editor 4.11.0 Released

We're excited to announce Phaser Editor v4.11.0! This new version includes a new color theme, start page improvements, and the first steps in adopting Phaser 4.

Phaser 4 is in active development and is due for release in the coming weeks and we're working to make it compatible with Phaser Editor. In this release, we're providing a new Phaser 4 project template so you can start playing with it.

Most of the Phaser API is common to versions 3 and 4, but when using a Phaser 4 project, we disabled the Spine and FX extensions in the editor, as these aren't available in Phaser 4.

» Phaser v4 Beta 7 (and 8!) Released

We’ve released version 4.0.0 Beta 7 and Beta 8 in the past couple of weeks. Introducing a fundamental rewrite of its camera system alongside several improvements to GPU-based sprite handling and rendering. You can grab the latest version from GitHub and npm.

Here’s a summary of what’s new:

  • Improved Camera Behavior – The way the camera handles movement, zoom, and rotation has been refined for smoother and more accurate control.

  • Faster Sprite Updates – Changes to how images and objects are handled behind the scenes make updates quicker and more efficient.

  • Better Tilemap Support – Games using tile-based levels will now see more reliable rendering, especially when scaling or rotating scenes.

  • Sharper Shape Rendering – Visual elements like lines and borders now display more cleanly, without getting clipped at the edges.

  • General Fixes and Tweaks – Several bugs have been fixed, and some default settings were adjusted to reduce unwanted visual glitches.

» Phaser Launcher v1.0.9

We've released a brand new version of Phaser Launcher that packs 6 mighty game-making punches. This release includes the first of our new game templates. If you're looking for a little help getting started, use one of the provided templates to quick-start your game dev:

  • Color Sort: How quickly can you sort out the colors in this Color Sort game template.

  • 2048: Smash numbers together in this 2048 puzzle game template.

  • Breakout: Bounce it old-school with this Breakout game template.

  • Snake: Watch out for your tail! in this Snake game starter template.

  • Football Kick: In this beginner's keepy-uppy game template, see how long you can kick the football.

  • Pachinko: Drop balls for points in this Pachinko game template.

👨‍🏫 Tutorials

» Publishing Web Games on Steam with Electron

Want to take your HTML5 game to the next level? In this step-by-step tutorial, you'll learn how to convert your web game into a desktop app (.app, .exe) using Electron, package it with BunJS/NPM, and publish it to reach Steam's massive audience! This guide is perfect for indie game developers looking to bring their browser-based games to PC, Mac, and Linux.

» Make A Zelda-Like Game With Phaser

Scott Westover presents The "How To Make A Zelda-Like Game With Phaser 3" series and shows you how to create a top-down adventure game reminiscent of The Legend of Zelda, using TypeScript and Phaser 3.

🪵Phaser Studio Developer Logs

This is what the Phaser Studio team was up to last week…

» Tales from the Pixel Mines by Ben Richards

24 March 2025

Are we back? Taps mic. Well, we must be, or you wouldn't be reading this. Lots has happened since the last developer log went out! I'll give you a summary, rather than delve into typical obsessive detail.

New Releases

We released Phaser 4 beta 7 and beta 8. See https://github.com/phaserjs/phaser/releases/tag/v4.0.0-beta.8 for the files.

Camera Changes

We changed the way camera matrices work. Don't panic; cameras still do the same things. They're just more logical behind the scenes.

The issue was, a camera describes two things: where the camera is looking (the "view"), and where the camera is drawing on screen (the "position"). But the original implementation combined these together into a single camera matrix, so we had to untangle them every time we needed to do something important. For example, we don't care about the position when rendering into a framebuffer; and we don't care about the view when drawing that framebuffer to the camera position.

So I changed the camera to have two matrices. The existing matrix now describes the view, including camera scroll (which it did not previously). The new matrixExternal describes the position (and it could describe other kinds of transform, but position is the only one that plays nicely with GL scissor as a way to restrict which part of the screen it draws to).

Camera transforms now work the same way across all game objects, which allowed us to solve some internal rendering problems.

This is most likely to affect developers who use GetCalcMatrix to handle matrices directly. Its return type now has the extra external matrix, and includes camera scroll. There is a common pattern for using these matrices, and applying scroll factor:

// `calcMatrix` is a TransformMatrix reused for calculations.
// Copy from the camera, so we only mutate this reused matrix.
calcMatrix.copyWithScrollFactorFrom(
    camera.matrix,
    camera.scrollX, camera.scrollY,
    gameObject.scrollFactorX, gameObject.scrollFactorY
);

// `parentMatrix` is an optional value, usually passed by Containers.
if (parentMatrix)
{
    calcMatrix.multiply(parentMatrix);
}

// `spriteMatrix` is a TransformMatrix reused for calculations.
spriteMatrix.applyITRS(
    gameObject.x, gameObject.y,
    gameObject.rotation,
    gameObject.scaleX * flipX, gameObject.scaleY * flipY
);

// The transformation product is stored in `calcMatrix`.
calcMatrix.multiply(spriteMatrix);

SpriteGPULayer Enhancements

We added several features to SpriteGPULayer.

Animation templates can now set loop: false to set an animation to open-ended. The default repeating animation is intended for permanent background fixtures. Open-ended animations are intended for one-off effects, such as complex special effects and explosions, or dynamic particle sources.

New methods insertMembers and insertMembersData provide support for adding members within the existing depth order, although this is expensive if you're handlings hundreds of thousands of objects.

It is now possible to use editMember and loop: false to loop over the entire GPULayer population, replacing old members with new ones. This is useful for effects such as smoke trails, dynamic particle sources, etc, where old members fade out and can be safely replaced.

Capturing Game Imagery

CaptureFrame Object

The new CaptureFrame game object doesn't render anything. Instead, it copies out the current framebuffer to a texture, before anything further is drawn.

This allows you to perform post-processing before the post-render step. Simply use the copied texture on an Image, and apply filters to it.

In the example above, the scene consists of a background, animated bubbles, and a logo. We place a CaptureFrame and associated filtered image just before the logo, so it only copies the background and bubbles, then applies a water distortion to them.

This kind of effect could be also be accomplished with DynamicTextures and Layers or Containers. CaptureFrame is easier to move around within a scene, and has very low overhead because it's just copying what's already on the screen.

DynamicTexture Capture Command

We have added a new DynamicTexture#capture(gameObject, config) method (also available on RenderTexture). This method gives you greater control than the draw command, via an extensive config object. It is intended for capturing objects using world transforms, instead of direct x, y positions.

This method is used by the Mask filter. Mask now uses the current camera and world transforms of an object. For example, if a Mask uses an object inside a Container, the mask appears exactly where the object would appear when drawn normally.

Display List Introspection

In Phaser 3, there exists a WebGLRenderer#nextTypeMatch flag. This tells you whether the next object that will be rendered has the same type as the current one. This had applications in custom renderers and Externs, where it could be used to support batch processing and other optimizations.

This was removed in Phaser 4, but it remains useful to know about what's happening next. In fact, why not open it up to all kinds of introspection?

So I added extra parameters to the RenderStep process, providing the current object list and index of what's rendering. Most game objects don't even know it exists, as RenderStep wraps transparently around their WebGLRenderer functions. But in a couple of places it can be more useful than ever.

Bug Fixes

Lots and lots of bugs have been squished. Check the changelogs to see the full list. We're almost completely out of bugs, to the point where I've just been going through GitHub closing issues that have been open for years. (I check them all, which involves rewriting them to Phaser 4 functions.) This is what the new renderer was always meant to do: fix longstanding issues and make Phaser super robust and reliable.

Phaser 3 Merge

My esteemed colleague Zeke has been fixing issues and making enhancements to Phaser 3 while I prepare the new renderer in this past year. Now that we're close to release, I've gone through all those fixes and ported them to Phaser 4. We're hoping to keep reversions to a minimum. I double-checked the process myself (and it's a good thing I did, because I missed a lot the first time).

Coming Up

We're hoping to have Phaser 4 release candidate 1 ready this week! Can you believe it? We're actually nearly done!

This is just the foundation, of course. There's a lot that we want to put on top of this work. Creation is never done - it merely hits exciting new milestones.

Share your content with 18,000+ readers

Have you created a game, tutorial, code snippet, video, or anything you feel our readers would like?

Please send it to us!

Until the next issue, happy coding!