Introduction

AutoTiles Helper is a small set of scripts and resources that will help you create and automate a seamless tiling system based on a total of 47 tiles that cover every sensible permutation of adjacent instances. You just have to provide the tileset, and the scritps will automatically figure out which tile is appropriate for a particular spot.

The scripts also provide a way to automatically generate a complete and ready to use tileset of 47 images from a compressed tileset:

Install

1. Open GameMaker: Studio, log in to the Marketplace and navigate to the Library tab. From there you can download and import the resources into your project.
2. Next, go into the extensions folder in the resource tree, double click the AutoTiles Helper extension and select the tab "Import resources".
3. The minimum resources you'll need are the contents of the "autotiles" folders in included files and in scripts. If you want to try the sample rooms just import all the contents into a blank project.

How to use

The first thing you need is a compressed (sample) or expanded (sample) tileset. You can use your own, but remember that the final uncompressed tileset has a specific tile order that has to be followed or it won't work as expected. See the section Anatomy of a tile for more information.

With a compressed tileset

If you have a compressed tileset, the first thing to do is generate an expanded version. In order to do that you'll need to load the expansion matrix first and then generate it passing the tileset as background to the autotile_expand script:

var matrix = autotile_load_expansion_matrix(working_directory+"autotiles/expansion_matrix.dsgrid");
expanded_tileset = autotile_expand(matrix,bk_tileset);
ds_grid_destroy(matrix);

The expansion matrix is a precomputed ds_grid that tells how the various pieces of the compressed tileset should be rearranged in order to compose a full tileset. Although this extension provides a default one in the included files (expansion_matrix.dsgrid), you are free peek at the code and generate your own.

The code above will result in the variable expanded_tileset ponting to a surface containing (surprisingly) the uncompressed tileset. From there you can save the surface to file (suggested) or use it on the fly to generate a sprite with 48 subimages, as in the provided demo project.

Note: the output of ds_grid_write on HTML5 is different than other platforms. If using HTML5, please use expansion_matrix.json

With an expanded tileset

Using the expanded tileset to generate a seamless autotiled room is easy, here's a way to do it:

first you need to load the tileset as a sprite with 48 subimages using "create from strip" in the tile editor, and assign the sprite to an object (let's call it obj_tile). Set image_speed = 0 in the create event of that object. Place your obj_tile instances in the room the way you prefer.

Then in a controller object execute the following in its create event:

var tile_map = autotile_load_tile_map(working_directory+"autotiles/tile_map.json"); //Load the tile_map from the included file
with(obj_tile) {image_index = autotile_get_index(tile_map,false);} //Assign the correct image_index to every obj_tile in the room
ds_map_destroy(tile_map); //Destroy the tile map after using it

Anatomy of a tileset

While there are no constraints on how big your tileset can be, expanded and compressed tilesets need to be structured in a very specific way in order to be used with the provided scripts and resources.

Compressed tilesets

Compressed tilesets contain all the required information that allow to generate a full expanded tileset. Starting from a structured like the one on the left, by dividing and recombining it into small sections of size 16x16 it's possible generate 47 tiles of size 32x32 (48 including the dummy 32x32 square in the top left corner).

For a more detailed guide, refer to this post that explains the same structure as used in rpg maker.

Expanded tilesets

An expanded tileset has all the 47 possible combinations in the correct order. The order is not set in stone, meaning that it's decided arbitrarily and subsequently taken into account when deciding which tile to display based on the adjacent tiles.

In this extension, the default order is shown above and is defined by the provided tile map included in the file tile_map.json. Note that tile0 is never used in the computed tile index, it's just a visual reference for the instances you place into the room. In the sample compressed tileset above, tile0 corresponds to the 32x32 square on the top left.

If you feel you understand enough if what's going on in the scripts, you are free to alter tile_map.json and provide a different tile order (and maybe post it on the forums for others to use).

Function reference

autotile_load_expansion_matrix(filename)

Helper function that returns a ds_grid, loaded from the provided file name, that tells to autotile_expand() how to rearrange a compressed tileset.

Example //loads the default expansion matrix provided with the extension
autotile_load_expansion_matrix(working_directory+"autotiles/expansion_matrix.dsgrid");
autotile_expand(expansion_matrix,background)

Expands a compressed tileset stored in the provided background. Returns a surface with the expanded tileset.

Example matrix = autotile_load_expansion_matrix(working_directory+"autotiles/expansion_matrix.dsgrid");
surf = autotile_expand(matrix,bk_autotile);
ds_grid_destroy(matrix);
autotile_load_tile_map(filename)

Helper function that returns a ds_map, loaded from the provided file name, that tells to the script autotile_get_index() how an expanded tileset is arranged.

Example //loads the default tile map provided with the extension
autotile_load_tile_map(working_directory+"autotiles/tile_map.json");
autotile_get_index(tile_map,open_borders)

Executed from an object with a tileset as sprite, returns the correct image_index to apply based on the adjacent tiles of the same type.
If open_borders is true, all tiles placed on the edge of the room will consider the outside of the room as composed by tiles of the same type. This makes the map look bigger than it actually is.

Example var tile_map = autotile_load_tile_map(working_directory+"autotiles/tile_map.json"); //Load the tile_map from the included file
with(obj_tile) {image_index = autotile_get_index(tile_map,false);} //Assign the correct image_index to every obj_tile in the room
ds_map_destroy(tile_map); //Destroy the tile map after using it

Credits

Contact me on the GMC forums or by email at simoneguerra<at>ekalia.com