One of the best new features in GameMaker Studio 2 is the improved tile system.
I never used tiles much in GMS1, because they were such a pain to work with, and did so little. In GMS1, tiles were a type of background resource. In the GMS1 room editor, you had to select your tiles manually, then place them one click at a time, which was very tedious. GMS users developed complicated auto-tiling scripts that would select the correct tile and place it in the room at runtime. This solution worked well, but was complicated to understand, set up, or modify. GMS1 tiles did not support animation, so if you wanted animated backgrounds, you either had to use sprites, or else come up with some sophisticated tile-swapping script that would programmatically animate your background tiles.
If you wanted your tiles to represent some kind of interactive object in the game, you had to also place an invisible object behind the tile, and program it to do whatever behaviors you needed. To me, there wasn’t much point in using tiles when I could just assign a sprite to the object, and use the object directly. If you did work with tiles in GMS1, then you may have to unlearn or relearn a few things before you feel comfortable with the new system.
I’m happy to say that in GMS2 the situation is much better. GMS2 tiles support animation and auto tiling. You can draw tiles in the room by the mouse without having to click each and every time you want to place a tile. This makes working with them much easier than it used to be.
However, there is still a lot of learning to do in order to develop the understanding necessary to set up tilesets and get the full use of them in your projects.
It took me an evening to figure out, about 4-6 hours, which isn’t bad. But after I had figured it out to the point where I have auto tile working, I realized that I could save others a lot of frustration by going a bit further to explain it.
Getting into GMS2 Tiles
First, the help manual article on Tileset Editor is essential reading. There are several articles which you should read first. And maybe a few YouTube videos are also helpful, to see the process of setting up a tileset for use within your project.
It’s actually pretty easy to use once you’ve gone through the process once so you understand it, but until you’ve completed your first working tileset, you’ll probably have a lot of questions and uncertainty about how it all works and what you’re supposed to do.
This article will guide you through that first time, and explain things so that they are easier to understand, and you’ll have an easier time of it than I did.
Before getting into that, there are a few constraints that you need to be aware of when working with tiles.
- The tile grid size must be a power of 2. So, for the most part, 8×8, 16×16, 32×32, or 64×64 tiles will be the sizes to work with.
- Any tile-based animations must have a number of frames that is a power of 2: 2, 4, 8, 16, etc.
- Tile positions in a room are constrained to a grid in GMS2. You can no longer position them at an arbitrary position in the room; they must snap to a grid the size of the tile.
Now that we’ve covered that, let’s look at the Tileset setup and usage workflow.
GMS2 Tileset Workflow
First, let’s take a general overview of the entire workflow, before we dive deeper into each step:
Before you can use a tileset to decorate a room, you have to set up a Tileset resource. A Tileset resource is a resource that depends on a Sprite resource, and defines how the image in the Sprite is sliced up to create a set of tiles.
- Create a sprite that will hold the image data for your tileset.
- Create a tileset asset.
- Define the tileset.
- Add the sprite from Step 1 to the tileset.
- Set tile size to split up the image.
- (Optional): Create any brushes, animations, and auto tile sets that are needed.
- Create additional tilesets, as needed.
This is where you put your tiles to work in the game. It’s all about creating and managing Tile Layers in your rooms, using the Room Editor.
- Add a tile layer to a room
- Select a tileset to use in the layer
- Add tiles to the tile layer.
- Add additional tile layers to the room, as needed.
Now that we’ve covered the workflow of Tile setup and usage at a high level, let’s go back and look at each step in depth.
Create a sprite that will hold the image data for your tileset
The first thing you need to do is create a Sprite resource, and add an image to it containing your tiles.
If you’re drawing this yourself, you’ll need to learn how to lay out this image. The first thing you’ll need to understand is that your tiles need to conform to a grid. You should set up the grid in the Image Editor to the size you’ll need for your tiles. I found that using an Image Editor grid that is half of what I want my actual tile size to be works well, so for a tile image that I wanted to draw that would have 32x32px tiles in it, I set the grid size in the Image Editor to 16×16. Then I drew out my tiles, using chunks that were 2×2 grid cells.
An important thing to realize in drawing your tiles is that your tile images should include some solid pixels as well as negative space surrounding the solid part of the tile. This is difficult to understand, especially at first, and it takes some getting used to the idea. To explain this properly, I need to illustrate.
As you can see here, I have drawn a brown rectangle, representing a solid object in the game room, and overlaid a green grid on top of it, showing how the tile borders should look if they’re done properly. Noticed that each tile (except for the center ones, which are completely solid) shows a certain amount of solid space and some white space.
I think a lot of people probably mistakenly think that their grid of tiles should look like this:
I know I did, at first. It’s hard to understand why tiles don’t work the second way — it seems a lot more obvious to position them that way, doesn’t it?. If you’re just thinking about a simple rectangular platform or wall like this, it’s easy to think that it should simply be a 2×4 rectangle of solid brown tiles, all the same. The thing is, if you go back to the first illustration, you can see that in that illustration, we have many different types of tiles, representing edges, corners, and solid areas, working together to create the same rectangular platform, and since they’re not all the same tile, you can re-combine them in many different arrangements, to create other shapes.
Since the point of making the tile set is to enable you to create all the different types of edges and corners, you want to make sure that the sprite your tiles are drawn in is laid out in such a fashion.
We really need to create a ring so we can have inner and outer corners represented in our tile. We also need to have a tile representing a completely open space. By convention, GMS2 auto tile sets reserve the top left tile grid for this empty tile. Here’s a better image that shows all the different corner and edges that we’ll need for a complete tile set:
With this arrangement, we are able to create almost any arrangement of blocks, but we still have a few more tiles to create. We actually have a few duplicates in this tile set, which I’ll color code in the next illustration, as well as number the unique tiles.
As you can see, we have 14 unique tiles in this image, and a few duplicates. There are actually two more tiles that we’ll need to create a universal 16-tile auto tile set. They are:
We can consolidate space in our earlier image by eliminating some of the redundant tiles and replacing them with the ones we needed, like so:
Really, these tiles could be arranged in any ordering; this is just an example of one such arrangement.
There’s also a 47-tile auto tile but I think now that we’ve walked through the 16-tile auto tile set creation, you should be able to figure out the 47-tile version on your own. The ideas are the same, it’s just more work.
But just to make things convenient, here are two templates that I’ve created for 16×16 and 47×47 auto tiles, matching the order that the GMS2 Tile Set editor uses for its template:
You can right-click, save, and use these for laying out your own tiles. If you need 32×32 sized tiles, or larger, just scale the image up to whatever you need. Then import the image into the GMS2 Sprite Editor, set the grid to the size you need, and draw over the template in a new layer until you’ve built up your tiles!
I will point out here, that this sheet that we’ve created above just gives us a starting point to create a single auto-tile set. Most games will likely need several tilesets, for different areas of the game. Auto-tiling is best for your basic terrain, such as walls, floors, and platforms.
We could also choose to include numerous additional tiles in one sprite image if we desire, for decorative things that do not make sense to do auto-tiling with, or create additional tiles to represent terrain features in the game such tables and chairs, or other furniture, or trees, bushes, you name it. Or we could store each type of terrain, decorative elements, etc. in its own tileset resource.
We could also duplicate this 16-tile layout multiple times, and include in a variety of different terrain types, or different colors, all in a single large tilesheet. Or we could have multiple tile sheets. But be cautious about making the sheet too large. You’ll want to read the Texture Groups section of the manual to understand the limits of how large your sheets can be.
One last thing: If you wanted to create an animated auto-tiling tileset, you would need to create additional copies of our 16-tile auto tile layout, and draw each one as a different frame of animation. We’ll explain how to do this in the section on creating tile animations.
Create a tileset asset
Now that we have a sprite holding the image for our tile set, it’s time to create the tile set asset. To do this, right-click on the Tile Sets section of the resource tree, and select Create. You can name the new Tileset something meaningful, such as grassland, or ocean, or city, or indoors, or whatever suits your game.
Define the tileset
The Tileset editor looks like this:
The first thing to do is to add the sprite from Step 1 to the tileset. Click on Select Sprite, and select the sprite. Next, set tile size to split up the image, by entering the information in the Tile Properties fields at the right, as appropriate. The sprite image will appear sliced up by a grid as you change these values. Once the grid looks how you want it, we’re ready to create any Brushes, Animations, and/or Auto Tiling sets that are needed.
(Optional): Create any brushes, animations, and auto tile sets that are needed
At this point, we could use our Tileset right away, by going to the Room editor, adding a Tile Layer, and drawing in some Tiles from our newly created Tileset. But there’s a few very useful, and powerful, things we can still do to complete the setup, and that’s define Brushes, Animations, and Auto Tile sets. Not every Tileset needs Brushes, Animations, or Auto Tiling to be defined for it, but when you do use these, especially Auto Tiling, it will make creating your rooms much easier and faster.
This is where it really starts to get good.
A brush is a selection of tiles, grouped together and added to your tile layer as one. Let’s say you have something in your tile that takes up more than one tile. This could be a large terrain feature, such as a building, or a mountain, or a tree. Without using brushes, every time you wanted to plant one of these multi-tile features in your room, you’d need to select each tile one at a time, place it in your Tile Layer, in the correct order… this is tedious work and easy to screw up. So Tile Brushes make this easier by collecting the related tiles together, so that they can be added to the Tile Layer with just a single click to place the entire Brush.
You can use Brushes not just to place multi-tile graphics, but to place arrangements of platforms. Say you have a particular jumping puzzle that you want to repeat several times in a level; you can create a Brush with the tiles spaced out in just the way you want them, then place them quickly and easily into your Tile Layer.
Setting up Animation Tiles is pretty easy. Simply add a new Animation, specify the number of frames (which must be a power of 2), and then add the tiles that make up the animation one at a time until you’ve filled out the animation.
It’s worth noting that you don’t have to use Tilesets to do animation. You can place any sprite resource into a room directly, without the need to place an instance of some object to draw the sprite for you. These can be added to asset layers or background layers. Background layers can tile or stretch or both, and can move. So consider whether you need to do your animations in tiles or if you can do them more easily another way.
Setting up an auto tile set is pretty easy too, although at first it seems complicated. Taking the sprite that we created, above, we have all the tiles we need to create a 16-tile auto tile set. GMS2 also supports a 47-tile system, but it is much the same to set up.
Create a new Auto Tile set. The auto tile set will present a template which you have to fill in with tiles from your tileset sprite. Simply go through the template by clicking on each tile in the template, then click on a tile from your tileset sprite to connect it to the template. The currently selected tile in the template is red, and as you go through your tileset adding tiles to the auto tile template, it will fill in the tile you selected, then advance to the next tile in the template automatically.
The key to understanding the auto tile template is that the light grey parts of the template are meant to represent the solid parts of your tile, and the dark grey parts are meant to represent the empty space. If you didn’t know this up front, it’s very difficult to read the template correctly, and this was one of the most confusing parts of figuring out the auto tile editor.
Each of auto tiles (remember, there can be more than one in a tileset resource) is called an auto tile library. The image above shows two auto tile libraries about to be created; a 16-tile library, and a 47-tile library, just to show what they both look like.
It’s also important to understand the buttons to the right of the auto tile templates, which look a bit like a yinyang. These control how the tileset treats the borders of the room. Outside the edges of the room, the tileset must make an assumption: either the tiles outside the room count as empty, or as filled. This influences the auto tile system to select the appropriate tile at the room edge, and will result in an edge border around the room if the outside is treated as empty.
Once you’re done setting up the Tile Set resource, when you go to the Room Editor, in the Tile Layer editor, you’ll see a section in your tile palette called Libraries. Here, you can select Brushes, Animations, and Auto Tile sets to draw, rather than selecting individual Tiles from your Tile Set.
Pro Tip: An auto tile library will not work until and unless every tile in the template has been assigned. If you try laying out auto tiles in a tile layer and they just won’t draw, no matter what you do, go back and look at the template. Somewhere in there, some part of the template has not been assigned to a valid tile in your tileset.
The auto-tiling section in the manual illustrates this pretty well, with some nice animations showing how it works.
Animated Auto Tile sets
To create an animated Auto Tile set, simply make sure that each tile in your Auto Tile set is the first tile in an Animation set. In the room editor, the tiles will not animate, but as long as you place animated tiles in the editor using the first image in the animation, they will animate at runtime.
Re-Auto Tiling (Auto Tiling at runtime)
Dynamically re-auto-tiling at runtime is not supported by GMS2 at present, but it is a planned feature according to YYG lead programmer Mike Dailly, albeit with no release date announced yet.
This means that, at least for now, your auto-tiled setup will not automatically update the tiles if something changes during the game, for example if a new platform is created, or an existing one is destroyed, the tiles in the adjacent region will not update. This can cause things to look weird.
Presently the only way to handle this would be through a custom coded solution to evaluate the neighbors and determine an updated arrangement of tiles. This is pretty much the old system from GMS1, when auto-tiling was done at runtime.
There are scripts published on the GMC Forums and available for purchase in the Marketplace that will do auto-tiling for you, and YouTube videos describing how they work. These will need to be updated in order to be compatible with GMS2. At this time I haven’t evaluated these solutions, so I won’t be making a recommendation for any here. Hopefully YYG will provide a built-in solution in the form of GML functions, and there won’t be a need to invest time into developing custom solutions.
Create additional tilesets, as needed.
Your project can have as many tilesets as needed. Create as many as you like, to allow you to create as many different environments as you need for your game. It’s probably best to start simple and just create one at first, and then once you’re happy with it and satisfied that you know how to use the tile system, create additional Tilesets.
You can use multiple Tilesets in the same room, and in different layers, overlapping them. This is how you can develop very nice looking rooms.
Can a tile layer move/scroll?
Short answer: Yes. The functions
tilemap_y() allow you to move a tile layer around the room. For complete details of all the things you can do with tilemaps, consult the manual.
The individual tiles in the tile layer have to align to their grid. So you can’t offset individual tiles, and make them move. But you can move the entire tilemap. If need be, you could put a few tiles in a layer that moves, and use this to create moving terrain features. For things like crumbling tiles, or tiles that break loose and drop one at a time when the player stands on them, it’s better to handle these with objects rather than tiles; of course, you can just use a sprite that looks the same as the tileset that you’re using, so everything blends together.
GMS2 can handle collisions between instances and tiles directly, without the need to use instances of hidden collision object behind the tiles. This is very handy, since you no longer need to lay out a bunch of instances in a room, then tile over them, and as well it offers greater performance, because there’s much less overhead involved with tiles than there is with instances.
Tile Collisions are meant for solid, stationary objects, such as platforms in a side-scrolling game, or walls in a top-down game, not for handling all possible collisions in your game. You will still want to use normal collision events for handling collisions between different objects in the game.
I mention them here so you’re aware of it, but rather than make this article even longer, I recommend you watch the tutorial video by GMWolf, which explains one approach for how to make a tilemap collision system in GMS2. His approach is to create a separate, invisible tile layer for the collision tilemap, which separates collisions from the decorative tile layer, which allows you to have decorative tiles which have rough texture, for surfaces like tall grass or uneven rock. The collision checking is performed by the objects in your game, which check to see if their sprite’s collision mask overlaps the tiles in the collision map.
It’s a very good approach, but it is just one way to do it. In GMWolf’s demo, a player object is prevented from entering into the region covered by the collision map. But there may be other types of collision checking, for example to determine if the player has entered a region that does damage, or is overlapping a ladder tile. Each of these situations can be handled by some variation of this basic approach, using additional collision tilemaps for different types of collisions. For example, you could have a collision tilemap for solid platforms, another tilemap for ladders, one for water, one for slippery platforms, one for danger zones, etc., as many as needed. You can even use a collision tilemap to trigger events, such as to spawn or activate enemies when the player reaches a certain region of the game. There are many possibilities, so use your imagination.
Isometric and Hexagon tiling?
Because of GMS2’s requirement that tiles align to grid, you can’t lay out isometric or hexagonal tiles in a single tile layer. You’ll need to use a two layer approach, with the second layer offset horizontally and vertically, so that the two layers blend together.
This approach has its downsides. Having to switch back and forth between the two layers when laying them out in the room editor is a pain. And checking both layers for collisions doubles the amount of work the game needs to do at runtime for handling tile-based collisions.
I hope that something is done about these problems, I would like to see an “isometric grid” checkbox in the layer editor that allows aligning to a half-sized grid, or perhaps a new tile layer type for isometric tiles. But for now a two layer solution seems to be the best approach.
Update: YYG lead developer Mike Dailly recommends that we refer to the Isometric demo in GMS1.x for the recommended how to do Isometric games. (Hopefully a 2.x Isometric demo will be happening eventually).
GML move functions and Tiles
If you use the GML functions
these work with the collision mask of objects, not tiles. So they will not be helpful to you if you’re implementing a tile-based collision system.
However, you can write your own version of these functions to work with tiles; to do so you just need to understand how the built-in functions work, and how to detect collisions with tiles.
move_bounce simply reverses the
vspeed of the bouncing object:
So, first determine whether the tile collision is horizontal or vertical, then use:
hspeed *= -1;
vspeed *= -1;
to reverse the appropriate speed variable.
bbox_right is in collision, set
hspeed *= -1. If the
bbox_bottom is in collision, set
vspeed *= -1.
move_bounce functions also take a boolean argument to turn on “advanced” collisions, which use the collision mask to do precise checking. These are slower to calculate, and the manual recommends not to use advanced unless it’s necessary, but they otherwise work the same. If you wanted to, you could come up with a tile collision check that uses the sprite’s collision mask to check for collisions with tiles, and use that.
move_outside functions work by using a
while loop to check for collisions with the calling object, moving it one pixel at a time until the while condition is satisfied. This is easy enough to implement in a tile-based system as well.