Dynamic Tilemaps are added along with ScrollFactor.

Published on 26th June 2017

Welcome to another Dev Log. A few issues ago we took a look at the new Static Tilemap renderer that had been added to Phaser 3. We also mentioned that we would add in a Dynamic Tilemap and this issue we can show it in action.

Static vs. Dynamic

The main difference between to two types of Tilemap renderer can be found in how the tile data is prepared for the GPU. In a Static tilemap, we store the data directly as a mesh, instead of rebuilding and culling each tile individually like we do with the dynamic tilemap.

During its creation, the dynamic tilemap generates an array of meta data tiles that describe the tile that will be rendered. The tile description contains properties like alpha, tint and visibility. This tile is also used to cull based on the current camera so we don't render unnecessary tiles. Finally, the tiles are rendered by adding them to the sprite batch which generates the vertices at runtime and uploads them to the GPU.

In contrast, the static tilemap can be very fast to render since the vertices are already stored in VRAM and we don't need to update that data every frame. This is especially good since updating resources from the CPU is very slow because it requires synchronising the GPU with the CPU. At the end, the whole map is rendered in a single draw call without stalling.

To summarise: A Static Tilemap stores the map data in VRAM, avoiding the need to push the data to the GPU every frame. Whereas the Dynamic Tilemap is built especially to work with the Sprite Batch renderer, so it has to push the data up every frame. If your data is constantly or even slightly changing, you need this approach.

You'd use a Dynamic Tilemap if you require any of the following features:

Animated Tiles

Tiles can be animated by way of modifying their tile ID. The ID is purely a reference to a frame within the tileset. By changing the ID over a period of time it has the same effect as animating the tiles. You can do this either to a single tile, or you could code it to update all tiles in the map that are animated. We have not added any helper functions for this yet, instead concentrating on providing you with the technical ability to do it first, so you can roll your own. In the future, though we can build upon this feature and make it more 'friendly'.

Per-Tile Tint support

This is a nice feature! WebGL only of course but you are able to modify the tint value of any single tile in the map. You can adjust a specific tile, for example, if you want to tint the tile at position 30x20 in your map, you can do that. Or you could loop through the tile data and tint any tile that matches your own criteria.

This could be used for some neat lighting and environmental effects with a little careful planning.

Per-Tile Alpha and Visibility support

As you can imagine you can also change the alpha and visible state of any single tile. Again, this impacts just one tile, or you can loop through the tile data applying your own matching constraints. The Alpha property could be tweened, leading to nice visual effects, or just toggled based on actions in your game. It's up to you how you use it!

Modify Map Data in real time

The tilemap data array is just a plain flat array of Tile objects. And you're free to change them at any point. You can add new tiles in, remove old ones, or just modify a single tile instead. This is extremely useful for things like streaming game worlds, where tiles at the edge of the map can be modified to provide for the new incoming data.

It also allows you to draw maps in real time, and to demonstrate this we've created a couple of examples for you to play with. The first example shows you how to draw a map using the mouse and literally paint down tiles.

image

Use the mouse to paint tiles. Press Z to bring up the Tile Palette to pick a new tile from. Press 1 to 3 to change layers (X to view them all) and finally use the cursor keys to move around.

This showcases both drawing tiles dynamically, across multiple layers, the new ScrollFactor property, and tile culling.

The map renderer will cull tiles automatically, avoiding rendering tiles that are not visible to the camera. This has been implemented in both the Dynamic and Static Tilemaps, as although the Static map is already nice and fast, it still doesn't need to waste time drawing tiles that cannot be seen.

Impact.js Support

I'm very pleased to announce that thanks to his kind support, Dominic Szablewski has allowed for Phaser 3 to able to load and run Impact.js tilemaps. If you've ever used Impact before you'll know it comes with a neat map editor called Weltmeister.

image

This can be used to create map and collision layers, as well as allow for Entity placement. Phaser 3 will natively be able to load Weltmeister map data. So if you've already got an Impact license this will let you use the map editor to build your own levels. We have also accurately re-created the physics values used in Impact, allowing you to take previous games you may have made, and port them to Phaser 3 while using the same Body properties and values you have been used to previously.

As with everything in V3 we have made this a complete stand-alone module, so if you don't need it you can exclude it easily enough. However, for those (like me) who enjoyed using Impact, it's a great way to breathe new life into it.

Run and Jump

I wanted to take the previous 'Drawing' example, combine it with a bit of the work done with Impact support so far, and evolve it into a proper showcase piece where you can run and jump around a level, drawing and removing parts of it in real time as you go. Meet Platform Maker:

image

You start off in an empty world that is 3 screens by 2 in size. You can run around but that's all. So grab your mouse and start drawing some tiles to jump on. You can draw while running or falling, which is quite fun :) And if you press the shift key while drawing it will erase the tiles.

It's a simple enough example but is showcasing several important new additions, one of which is Scroll Factor.

Scroll Factor Property

Felipe implemented the Scroll Factor property on all Game Objects. It influences what happens to the position of a Game Object when a camera moves. You can see it in action in the Drawing Example in this Dev Log where each layer has a different Scroll Factor. You can also see it in the Platform Maker example above, where a Scroll Factor of zero is used to prevent the text hint from scrolling off the screen.

It can be given to any Game Object which allows for some really nice parallax effects as cameras move, and it's a great addition to have in the core.

So there we go, wrapping up another Dev Log. Loads of new features and more to come next issue. Thank you to all of our Patreons who make our current rapid rate of development possible, it's only because you're awesome that we're able to keep firing out such improvements at this rate.

Phaser 3 Labs

Visit the Phaser 3 Labs to view the new API structure in depth, read the FAQ, previous Developer Logs and contribution guides. You can also join the Phaser 3 Google Group. The group is for anyone who wishes to discuss what the Phaser 3 API will contain.

Welcome to another Dev Log. A few issues ago we took a look at the new Static Tilemap renderer that had been added to Phaser 3. We also mentioned that we would add in a Dynamic Tilemap and this issue we can show it in action.

Static vs. Dynamic

The main difference between to two types of Tilemap renderer can be found in how the tile data is prepared for the GPU. In a Static tilemap, we store the data directly as a mesh, instead of rebuilding and culling each tile individually like we do with the dynamic tilemap.

During its creation, the dynamic tilemap generates an array of meta data tiles that describe the tile that will be rendered. The tile description contains properties like alpha, tint and visibility. This tile is also used to cull based on the current camera so we don't render unnecessary tiles. Finally, the tiles are rendered by adding them to the sprite batch which generates the vertices at runtime and uploads them to the GPU.

In contrast, the static tilemap can be very fast to render since the vertices are already stored in VRAM and we don't need to update that data every frame. This is especially good since updating resources from the CPU is very slow because it requires synchronising the GPU with the CPU. At the end, the whole map is rendered in a single draw call without stalling.

To summarise: A Static Tilemap stores the map data in VRAM, avoiding the need to push the data to the GPU every frame. Whereas the Dynamic Tilemap is built especially to work with the Sprite Batch renderer, so it has to push the data up every frame. If your data is constantly or even slightly changing, you need this approach.

You'd use a Dynamic Tilemap if you require any of the following features:

Animated Tiles

Tiles can be animated by way of modifying their tile ID. The ID is purely a reference to a frame within the tileset. By changing the ID over a period of time it has the same effect as animating the tiles. You can do this either to a single tile, or you could code it to update all tiles in the map that are animated. We have not added any helper functions for this yet, instead concentrating on providing you with the technical ability to do it first, so you can roll your own. In the future, though we can build upon this feature and make it more 'friendly'.

Per-Tile Tint support

This is a nice feature! WebGL only of course but you are able to modify the tint value of any single tile in the map. You can adjust a specific tile, for example, if you want to tint the tile at position 30x20 in your map, you can do that. Or you could loop through the tile data and tint any tile that matches your own criteria.

This could be used for some neat lighting and environmental effects with a little careful planning.

Per-Tile Alpha and Visibility support

As you can imagine you can also change the alpha and visible state of any single tile. Again, this impacts just one tile, or you can loop through the tile data applying your own matching constraints. The Alpha property could be tweened, leading to nice visual effects, or just toggled based on actions in your game. It's up to you how you use it!

Modify Map Data in real time

The tilemap data array is just a plain flat array of Tile objects. And you're free to change them at any point. You can add new tiles in, remove old ones, or just modify a single tile instead. This is extremely useful for things like streaming game worlds, where tiles at the edge of the map can be modified to provide for the new incoming data.

It also allows you to draw maps in real time, and to demonstrate this we've created a couple of examples for you to play with. The first example shows you how to draw a map using the mouse and literally paint down tiles.

image

Use the mouse to paint tiles. Press Z to bring up the Tile Palette to pick a new tile from. Press 1 to 3 to change layers (X to view them all) and finally use the cursor keys to move around.

This showcases both drawing tiles dynamically, across multiple layers, the new ScrollFactor property, and tile culling.

The map renderer will cull tiles automatically, avoiding rendering tiles that are not visible to the camera. This has been implemented in both the Dynamic and Static Tilemaps, as although the Static map is already nice and fast, it still doesn't need to waste time drawing tiles that cannot be seen.

Impact.js Support

I'm very pleased to announce that thanks to his kind support, Dominic Szablewski has allowed for Phaser 3 to able to load and run Impact.js tilemaps. If you've ever used Impact before you'll know it comes with a neat map editor called Weltmeister.

image

This can be used to create map and collision layers, as well as allow for Entity placement. Phaser 3 will natively be able to load Weltmeister map data. So if you've already got an Impact license this will let you use the map editor to build your own levels. We have also accurately re-created the physics values used in Impact, allowing you to take previous games you may have made, and port them to Phaser 3 while using the same Body properties and values you have been used to previously.

As with everything in V3 we have made this a complete stand-alone module, so if you don't need it you can exclude it easily enough. However, for those (like me) who enjoyed using Impact, it's a great way to breathe new life into it.

Run and Jump

I wanted to take the previous 'Drawing' example, combine it with a bit of the work done with Impact support so far, and evolve it into a proper showcase piece where you can run and jump around a level, drawing and removing parts of it in real time as you go. Meet Platform Maker:

image

You start off in an empty world that is 3 screens by 2 in size. You can run around but that's all. So grab your mouse and start drawing some tiles to jump on. You can draw while running or falling, which is quite fun :) And if you press the shift key while drawing it will erase the tiles.

It's a simple enough example but is showcasing several important new additions, one of which is Scroll Factor.

Scroll Factor Property

Felipe implemented the Scroll Factor property on all Game Objects. It influences what happens to the position of a Game Object when a camera moves. You can see it in action in the Drawing Example in this Dev Log where each layer has a different Scroll Factor. You can also see it in the Platform Maker example above, where a Scroll Factor of zero is used to prevent the text hint from scrolling off the screen.

It can be given to any Game Object which allows for some really nice parallax effects as cameras move, and it's a great addition to have in the core.

So there we go, wrapping up another Dev Log. Loads of new features and more to come next issue. Thank you to all of our Patreons who make our current rapid rate of development possible, it's only because you're awesome that we're able to keep firing out such improvements at this rate.

Phaser 3 Labs

Visit the Phaser 3 Labs to view the new API structure in depth, read the FAQ, previous Developer Logs and contribution guides. You can also join the Phaser 3 Google Group. The group is for anyone who wishes to discuss what the Phaser 3 API will contain.