We reach 24k stars on GitHub, Arcade Physics gets updated, read about the new overlapTiles feature and the virtual joystick plugin.
Welcome to Dev Log 143. My work has been split over so many different tasks recently that this Dev Log is going to feel like a shotgun blast of small bits of information. To be honest, this is likely to carry on for a few weeks yet, as lots of ends start being tied together.
My continued focus has been directed on the new docs site, as well as diving in to GitHub issues as well. When I split my time like this it means both tasks take longer to complete, but as I mentioned last week, I feel it's important. Plus, there's only so much php I can take in a day :) The docs
24k GitHub Stars!
During the week, the Phaser GitHub repo hit 24,000 stars. This is quite amazing. Thank you to everyone who has starred the project (if you haven't, please do so!). I know that these stars don't really mean much, but you have to understand that being an open source project means I have precious few metrics by which to track how things are going.
Unlike, say, Construct, or Unity, I have absolutely no idea how many developers are using Phaser. I can infer some guesses, based on what few metrics I do have, such as newsletter subscribers, web site traffic and GitHub stars, but I'll never truly know. Which is kind of sad in a way, yet inevitable. So even tiny things, like a little star counter against the project, can mean more to me than they perhaps should.
Arcade Physics Updates
I've recently fixed a number of lingering Arcade Physics issues and changed the way the game and physics step is handled slightly. In a previous update, I moved to a fixed timestep, allowing for deterministic results from Arcade Physics, something that didn't happen previously. I spent some time refining this flow further and ironing out some issues.
The physics body update has been broken down into 3 stages. First is
preUpdate. This syncs position data from the parent Game Object and also resets all the internal collision flags. This is run only once per game step. Next, there is the
update method. This now does nothing more than calculate the new velocity and handle bounds collisions. Depending on the physics step, this can be run multiple times per frame. Finally, there is
postUpdate which is responsible for syncing the changes in the body back through to the parent Game Object.
In the previous iteration, all of these tasks were being done at once in the same step. By splitting them up I've been able to tidy up a lot of internal code in the World class, refactor the Body postUpdate method and fix a number of bugs at the same time, including the ability to run your own collision calls during a Scene update.
If you use Arcade Physics in your game, please can you help test the new build and report if anything breaks.
As part of the work I was doing inside Arcade Physics, I took the time to implement a feature I had been wanting in there for months: the ability to check for overlaps with specific tiles from a Tilemap, regardless if they have been flagged for collision or not.
The new method, accessible via the Arcade Physics World instance, is called
overlapTiles and it takes a single physics-enabled Game Object, such as a Sprite, and then performs overlap detection against any tile you provide in the input array. The tiles don't have to have been set for collision, either in your map editor, or via code.They don't even have to be on the same Tilemap layer, the method doesn't care, it will run overlap tests against them all in turn, firing your provided callback when an overlap occurs.
I put together a demo to show how it works. You can see it in the screen shot above, click it to test it out. Use the cursors to move and jump. All you need to do is collect the yellow tiles.
The method works by taking an array of tiles. So you need to build this up first. The Tilemap API has a method called
filterTiles which can be used to do this. For example, in our test map, the yellow tiles have an index of 82. So we build an array of just those tiles:
We then pass this array to the
overlapTiles method, along with our player sprite and a callback to invoke, should an overlap occur:
The above code is run in our Scene
update method in this demo, but you could call it from anywhere. If the Game Object overlaps with a tile, both items are sent to your callback, where further action can be taken. In the example demo above the tile is removed from the map and the array is refreshed.
There are several benefits to using this method, combined with a couple of drawbacks. The most obvious benefit is that you can dynamically create the array of tiles to be tested against, as your game requires it. Each different array could redirect to a different callback too. What's more, because it's just a tile instance it doesn't care if the tile can collide or not, meaning you don't need any extra steps in your level set-up or code.
The downside is that it's an O(N) method. That means, for every single tile you pass to the method, each one of them will be checked against the Game Object. No filtering or spatial culling is performed. This makes it perfect for small quantities of tiles, but increasingly more expensive the larger the numbers go. As with most things like this, test it for yourself to see the impact on your game. If the array is small enough you may not even notice it.
This new method can be found in the master branch on GitHub, along with all other changes targetted for 3.16.3.
March Backers Examples Bundle with free Plugin!
Earlier this week I released the March Backers Examples Bundle to everyone who supports Phaser via Patreon or PayPal. I release a bundle of examples each month to backers and they're slowly building into quite a handy resource, especially as each bundle contains all previous months, too.
This month was a little different. As well as the examples I gave all backers a free copy of the brand new Phaser 3 Virtual Joystick Plugin. This plugin was originally released several years ago for Phaser 2 and has proved popular ever since. It allows you to easily add a virtual joystick and buttons to your game, perfect for mobile users.
I took some time to recode the plugin from scratch, adding features as I went. The new plugin was written fully in ES6 and packaged using Parcel and Babel. It was my first time using Parcel and I have to admit the experience was a bit mixed. The main benefit of Parcel is that it's "zero configuration". This is the polar opposite to Webpack, which has a configuration file complexity akin to learning a second language. This aspect of Parcel was fantastic. It really did bundle out of the box with nothing more than a single command-line call.
However, because I needed a slightly different output than its defaults are used to, it took several hours of frustrating trial and error before I finally stumbled upon a semi-related GitHub issue, in which the Parcel author had posted a link to a tiny, easy to miss repo, that finally demonstrated a specific way of running Parcel that provided the bundle output I required. With this new found knowledge in place I was able to get it to package the plugin and it worked within Phaser 3 perfectly.
There's definitely a potential tutorial-in-the-making from my experience with this! After solving that issue I was able to code merrily away in ES6 and test it instantly. The new joystick plugin uses fully native Phaser 3 features, as you'd expect, includes some updated PSDs, 3 different skins, 10 examples, a getting started guide and full documentation generated using ESDoc. This was another first. Previously I had used JSDoc for everything, but I figured as I was coding in ES6 anyway, why not use ESDoc instead? As it transpires, ESDoc is even more opinionated than JSDoc! Too much for me to ever consider using it for Phaser itself, but it just about managed the plugin with a few tweaks.
Anyway, overall I was very pleased with the end result, even if the new tooling experience required to get there was a painful learning curve with plenty of dead-ends at times. All Backers will now have a copy of the plugin. If you become a backer after reading this, you can find the post on my Patreon page and download it from there! For everyone else, I will be releasing the plugin onto the Phaser site for sale in the coming days.