Phaser Dev Log: Phaser 3.20 Released

Published on 12th October 2019

I'm pleased to announce that Phaser 3.20 is officially released. It has been published to GitHub and npm, so you can grab it from whichever source you prefer. There's a whole stack of goodness in this version and I've spent the past several weeks going through GitHub issues, fixing what I can, merging in PRs and tidying things up. Today I finished the process by updating the docs and Phaser web site and putting 3.20 onto the examples site as well. It's also now the default version used in the Labs editor.

You can read the full Change Log here, but I'll highlight a few key parts below.

If you've read either of my previous weekly posts, you'll know that I've been working on a new Video object, allowing you to playback videos, either local or streamed, in your games. This was something that a few of you had requested since the release of Phaser 3, but I had never got around to implementing it, and no-one had submitted a contribution towards it, so the feature-request just sat there idle.

Initially, I thought I could take the approach that was used in Phaser 2 and adapt that for Phaser 3. Which is how I started the process off. Yet, as no-one will be surprised to hear, browsers have moved on a lot since the Phaser 2 days, making the transition more time-consuming than I expected. You used to just be able to play videos, no questions asked and they'd happily stream into your game. However, this isn't the case any longer. Browser vendors have been working hard to avoid any kind of 'auto-playing' content on the web, which, like audio, prevents videos from playing unless the user has interacted with your game already, or the browsers Media Engagement Index is high enough. A far cry from what it used to be.

There are exceptions, of course. If a video doesn't have an audio track and is large enough in resolution, then you're able to start playback right away. Equally, servers can now be configured to send special headers that some browsers will respect and factor into the auto-play equation. This meant that I needed to change the way videos were loaded. You can now specify, as part of the loader call, if the video has audio or not. This lets Phaser set the video muted state immediately, allowing playback to commence right away.

Media playback also now emits a Promise. You can listen for resolution of this Promise to know when playback can begin, or the failure of it to know when playback is blocked. Of course, not all browsers do this, so Phaser still has to fall back to the event-based days of old to capture that flow as well.

I was hoping that I could re-create a small section of the game Dragon's Lair as a fun video example. For those unfamiliar with the game, it was a 1980s laserdisc game, where you simply moved the joystick in a direction to play the next part of the sequence. Much like a 'Choose your own adventure' book, but in an animated form. However, I was dismayed to find that for all the advancements that browsers have made in video handling, they still cannot accurately seek to a given point in a video. Which is essential for a game like Dragon's Lair, as you need to be able to jump to precise points for the next part of the game to play out. Seeking, it appears, is still too inaccurate to be reliable, with a significant margin of error required on either side of the desired seek point, as you're unlikely to actually end up on that actual time point. This was a real shame. Of course, I've still built seeking support into Phaser 3.20. You can tell the browser to jump to a timestamp, or you can give it a percentage and it'll jump based on the total video duration. You can even tell it to jump relatively, i.e. "+2.5" to jump 2.5 seconds ahead of where the marker currently is. So, it's all in there, but browsers just aren't as accurate as I was hoping, so my dreams of a web-based Dragon's Lair aren't happening just yet.

One thing I did find was that connecting to video streams is now a lot better! Although it's quite unusual for you to use a video stream in a game, it's now technically possible. I found a stream that played Amiga demos 24x7, which I used for testing, and it worked great :) Patreon Backers will find this example in the October bundle shortly.

All in all, it was really interesting working on the Video class. It's a powerful and flexible new addition to the Game Objects roster, especially when used in a browser that supports transparent WebM videos such as Chrome, and I'm looking forward to showing off what it can do in the October Backers Code Bundle :)

3.20 brings lots of other updates to the table, too. I worked hard fixing some key issues in the Spine Plugin and took the opportunity to update to their absolute latest 3.8 Runtimes. Previously, Spine was failing when used across multiple Scenes or Containers, but you can now mix and match and swap Scenes to your heart's content. If you use the Spine Plugin, then upgrade to 3.20. You'll need to re-export your animations using Spine 3.8, but it's worth the hassle of doing this.

When I originally added the pixelArt Game Configuration option the plan was that it would set the canvas to use nearest-neighbor scaling and then all textures would use a NEAREST filter mode, so they retained their 'pixel' crispness when scaled. Those two aspects did work, however, there were lots of other Game Objects that ignored it, such as Text (which used its own internal canvas), Bitmap Text, the Particle Emitter, the Tilemap renderer, Render Textures and more. In short, unless your game was using just Sprites, then not everything would respect the setting.

Needless to say, this negated the usefulness of the setting. So I spent a good while, going through everything I could find, making sure that all those objects which previously ignored it, now respected it. If you use the setting in your game then you may notice some visual changes in 3.20, so please adapt for those. If you've always wanted to use it, but couldn't because it didn't work fully, now please do :)

There's a lot of other fixes and enhancements in Phaser 3.20, so please do take the time to explore the Change Log and try it out in your game. It felt really good to give it a major update like this. I guess the last one wasn't that long ago, only being back in August, but with all the focus on Phaser 4, in my brain at least, it was nice to give v3 some love and attention.

Next week I'm going to spend a few days finishing off the October Backers Pack, closing down some more issues on GitHub and generally seeing how the community responds to 3.20. I'll also get back into Phaser 4, so expect updates across both versions in next week's Dev Log.

In the meantime, I hope to see you all on Discord soon, and please enjoy the 3.20 release - if you do find any issues, report them on GitHub, and if you release anything made with it, don't forget to tell me! Until then, have a good week everyone.

I'm pleased to announce that Phaser 3.20 is officially released. It has been published to GitHub and npm, so you can grab it from whichever source you prefer. There's a whole stack of goodness in this version and I've spent the past several weeks going through GitHub issues, fixing what I can, merging in PRs and tidying things up. Today I finished the process by updating the docs and Phaser web site and putting 3.20 onto the examples site as well. It's also now the default version used in the Labs editor.

You can read the full Change Log here, but I'll highlight a few key parts below.

If you've read either of my previous weekly posts, you'll know that I've been working on a new Video object, allowing you to playback videos, either local or streamed, in your games. This was something that a few of you had requested since the release of Phaser 3, but I had never got around to implementing it, and no-one had submitted a contribution towards it, so the feature-request just sat there idle.

Initially, I thought I could take the approach that was used in Phaser 2 and adapt that for Phaser 3. Which is how I started the process off. Yet, as no-one will be surprised to hear, browsers have moved on a lot since the Phaser 2 days, making the transition more time-consuming than I expected. You used to just be able to play videos, no questions asked and they'd happily stream into your game. However, this isn't the case any longer. Browser vendors have been working hard to avoid any kind of 'auto-playing' content on the web, which, like audio, prevents videos from playing unless the user has interacted with your game already, or the browsers Media Engagement Index is high enough. A far cry from what it used to be.

There are exceptions, of course. If a video doesn't have an audio track and is large enough in resolution, then you're able to start playback right away. Equally, servers can now be configured to send special headers that some browsers will respect and factor into the auto-play equation. This meant that I needed to change the way videos were loaded. You can now specify, as part of the loader call, if the video has audio or not. This lets Phaser set the video muted state immediately, allowing playback to commence right away.

Media playback also now emits a Promise. You can listen for resolution of this Promise to know when playback can begin, or the failure of it to know when playback is blocked. Of course, not all browsers do this, so Phaser still has to fall back to the event-based days of old to capture that flow as well.

I was hoping that I could re-create a small section of the game Dragon's Lair as a fun video example. For those unfamiliar with the game, it was a 1980s laserdisc game, where you simply moved the joystick in a direction to play the next part of the sequence. Much like a 'Choose your own adventure' book, but in an animated form. However, I was dismayed to find that for all the advancements that browsers have made in video handling, they still cannot accurately seek to a given point in a video. Which is essential for a game like Dragon's Lair, as you need to be able to jump to precise points for the next part of the game to play out. Seeking, it appears, is still too inaccurate to be reliable, with a significant margin of error required on either side of the desired seek point, as you're unlikely to actually end up on that actual time point. This was a real shame. Of course, I've still built seeking support into Phaser 3.20. You can tell the browser to jump to a timestamp, or you can give it a percentage and it'll jump based on the total video duration. You can even tell it to jump relatively, i.e. "+2.5" to jump 2.5 seconds ahead of where the marker currently is. So, it's all in there, but browsers just aren't as accurate as I was hoping, so my dreams of a web-based Dragon's Lair aren't happening just yet.

One thing I did find was that connecting to video streams is now a lot better! Although it's quite unusual for you to use a video stream in a game, it's now technically possible. I found a stream that played Amiga demos 24x7, which I used for testing, and it worked great :) Patreon Backers will find this example in the October bundle shortly.

All in all, it was really interesting working on the Video class. It's a powerful and flexible new addition to the Game Objects roster, especially when used in a browser that supports transparent WebM videos such as Chrome, and I'm looking forward to showing off what it can do in the October Backers Code Bundle :)

3.20 brings lots of other updates to the table, too. I worked hard fixing some key issues in the Spine Plugin and took the opportunity to update to their absolute latest 3.8 Runtimes. Previously, Spine was failing when used across multiple Scenes or Containers, but you can now mix and match and swap Scenes to your heart's content. If you use the Spine Plugin, then upgrade to 3.20. You'll need to re-export your animations using Spine 3.8, but it's worth the hassle of doing this.

When I originally added the pixelArt Game Configuration option the plan was that it would set the canvas to use nearest-neighbor scaling and then all textures would use a NEAREST filter mode, so they retained their 'pixel' crispness when scaled. Those two aspects did work, however, there were lots of other Game Objects that ignored it, such as Text (which used its own internal canvas), Bitmap Text, the Particle Emitter, the Tilemap renderer, Render Textures and more. In short, unless your game was using just Sprites, then not everything would respect the setting.

Needless to say, this negated the usefulness of the setting. So I spent a good while, going through everything I could find, making sure that all those objects which previously ignored it, now respected it. If you use the setting in your game then you may notice some visual changes in 3.20, so please adapt for those. If you've always wanted to use it, but couldn't because it didn't work fully, now please do :)

There's a lot of other fixes and enhancements in Phaser 3.20, so please do take the time to explore the Change Log and try it out in your game. It felt really good to give it a major update like this. I guess the last one wasn't that long ago, only being back in August, but with all the focus on Phaser 4, in my brain at least, it was nice to give v3 some love and attention.

Next week I'm going to spend a few days finishing off the October Backers Pack, closing down some more issues on GitHub and generally seeing how the community responds to 3.20. I'll also get back into Phaser 4, so expect updates across both versions in next week's Dev Log.

In the meantime, I hope to see you all on Discord soon, and please enjoy the 3.20 release - if you do find any issues, report them on GitHub, and if you release anything made with it, don't forget to tell me! Until then, have a good week everyone.