Friday, February 3, 2012

Start of a gamedev blog: Autotiling

I think I've decided that I'm going to use this as a dev blog for my adventures in game design. Not quite specifically for one single game, but for all the interesting little tidbits that inspire me to type something.

 Today's topic is "Autotiling". Or at least, that's what the RPG Maker community calls it. Basically, what most newbies in gamedev do when it comes to tile-based level design is use the help of a level editor with a GUI to take a particular block from a tileset and assign it to a particular cell in the grid representing the level. Simple to do, though rather tedious, seeing that you have to account for every single block in every single level and manually judge what their texture should be in accordance with their surroundings. A good example of this is the "Lunar Magic" editor for Super Mario World. You have full control over what block goes where and a GUI to assist you, but you must place all of them in ways that they mesh well with their surroundings.

A slightly more advanced game programmer would probably opt for a level editor where he merely indicates certain properties of blocks and has the game assign a texture to them. Though this will increase loading time, it makes for ridiculously rapid level design and is absolutely indispensable when making randomly-generated levels. But while programming one, a problem arises: How many different tiles are there to account for? Squidi.net goes into detail on it, arriving at a rather large 47 different tiles to create in a graphic editor, then assign to blocks in the game. It seems rather difficult to make a function to handle this, seeing that 47 is a prime number and there are likely to be numerous convoluted if-statements, but whoever is in charge of graphics would probably notice a pattern of being able to copy/paste certain parts of tiles to make new ones. In fact, it seems like ALL the tiles you can make arise from a set of smaller subtiles, like molecules being made from atoms. So, after many hours of experimentation, fruitless googling, and eventually wrestling my computer, I arrived at a short 'n sweet algorithm described here (using Flashpunk) that helped me go from this behemoth:
...to this cute little thing:
The difference in area is mind-boggling, isn't it? Granted, I was using Squidi.net's "Blob" template for those tiles, but even with the most efficient use of area, you'd have 47 32x32 tiles, 48,128 pixels in one tileset. But for this tiny template, you have 20 16x16 tiles, 5,120 pixels total, nearly TEN TIMES SMALLER, reducing the amount of data for holding game textures significantly. However, it does look a bit disorganized, doesn't it? Don't fret, there's method to my madness. It's based on the indices given by the algorithm. Indices are assigned based on the nearest three blocks of a corner in a cell:
The arrows indicate what cells influences what corners. The upper-left corner of a cell is affected by the cell in the row above it, the row to the left of it, and the cell diagonally up-left from it. Index is determined through lots of boolean-to-int sheananigans that I don't feel like elaborating on (its in the code) and interpreting them as so:
0: Outward-pointing corner. There are free positions above the cell and to the side the corner points to.
1: Vertical: The only free position is on the horizontal side the subcell is located.
2: Horizontal: Similar to vertical, but the vertical sides (top and bottom) are used.
3: Inward-pointing corner. The cell is surrounded by adjacent cells on all sides, but there's a free spot diagonally outwards.
4: Decorative: You probably won't interact with this cell. It's completely surrounded by other solid cells that prevent you from getting to it.
 Then you add more based on the corner's position: Add 5 if its on the right side of the cell. Add 10 if it's on the bottom. Now to assign a tile in the tileset to the corner, simply associate the numbers 0-19 with every 16x16 block of pixels like so:
And assign accordingly:
From there, you do this to the rest of the corners in the cell, then do it on all the cells in your grid. You might be able to change a few things and make them even have different styles.
A quick demo of this can be seen here. Press r to get a new randomly-generated level, and left-click to toggle cells solid and non-solid, reworking the textures of surrounding cells. I'd embed the swf, but blogger doesn't seem to be enthusiastic about letting me do so.
For those of you familiar with flashpunk, the source is available here.

Saturday, November 7, 2009

I guess I made another blog.

I already have a wordpress one and should probably use that one instead, but Google tends to be full of fun new stuff each time I visit. So I'm giving this thing a try. I should've probably thought of something to put here beforehand.