• interested in more? sign up to the newsletter

     

Automatic wall generation

Tweet about this on TwitterShare on RedditShare on Facebook

wallgenerationcode

Most of my games use some form of random level generation. I love the process of creating the code to make that work, and I love that it allows me to generate much more playable content by saving time on designing levels.  For Heroes of Loot and now my new game Space Grunts, I used some code that also generates the looks of a level, so besides the layout which is mostly saying “hey, this is a wall, and this is not”, the game also has to show correct graphics for each wall.

A couple of people drilled me about how that actually works, so now I can just point them to this article – hi!

First thing to do is create your level-generation code, there are many ways of doing that and this article is not going to tell you how, you can find a few of my posts on that here.

The code this blog is all about is assigned the right “texture” to each 1 and 0 in your tilemap. Obviously 0’s are empty spots so they are normally just ground textures and easy to do, the 1’s are walls and are a bit trickier.  To keep this a bit cleaner, in my code I use a tilemap for the 1’s and 0’s, and a rendermap for the texture indices.

Simple theory behind it: check every tile in your tilemap, see if it’s solid or empty. If it’s solid, let’s get to work and check it’s surrounding tiles.  This really comes down to a lot of “IF then, Else” checks.  So what we do for EACH tile in the tilemap:

1) are we a solid tile, or an empty tile?  if empty? place the floor texture, and continue with the next tile
2) we are solid! so make us a full wall texture (usually a full-square) and continue with step 3
3) check our surrounding neighbors in all 8 directions. If we have NO solid neighbors, we are a single solid tile in the middle of open floor.. so we can turn into a pillar, or a cube, or statue, etc.
4) this is where your logic brain has to start working, cause we need to do a lot of IF checks:
– IF the tile on the left+right of us are also solid, but the tiles top+bottom are not.. we are part of a horizontal wall
– IF the tile on the top+down of us are also solid, but the tiles left+right are not.. we are part of a vertical wall

That’s the basic test, and you’ll have to just do this test for all possible cases. These cases are pretty simple to figure out, cause your tile-set will actually show you which ones you have to think about. So for every wall tile in your tile-set, check what the IF statement should be, and add that code.

What you’ll end up is something in the direction of this:

wallgencodecode

The Checkcorners function simply checks in the 8 directions (top,right,down,left, and 4 diagonals) and based on that outcome we set the right tile to the rendermap.

Extra tip: start with the “easy” walls, so the simple horizontal+vertical ones I explained above, then the outer-corner tiles, then the inner corner tiles, and after that do the “weird” ones like T caps, etc.

If you got questions about this, drop me a comment below!

 

Bookmark the permalink.
  • Ronan Leroy

    I usually only check 4 directions (My games have always had simple top-down or side views, so I usually don’t have to care much about diagonals), and use a simple binary system to get right tile.

    My tilesets for walls are organised in 16 columns: each column contains the same type of tile. For example, the first column contains tiles where ther are no walls surrounding the current tile. The second column has only a wall on top, and the third has a wall on the right. The fourth has a wall on top and another on the right. The fifth column only has a wall on the bottom.

    Then as I check the 4 directions, I add a number if I find a wall: 1 if I there is a wall on top, 2 if there is one on the right, 4 if there is one on bottom and 8 if there is one on the left.

    The result is the index of the column I must chose a tile from: If there is a wall on top and another on the bottom, 1+4=5 so I draw a random tile from the sixth column (they are 0-indexed ;) )

    The same method can be used with diagonal checks but you’ll need a 256 columns tileset or check special cases if you want to reuse some tiles. And it doesn’t take into account cases that could never happen depending on your map generator (like a wall with empty tiles on all 4 sides but walls on all 4 diagonals).

    • The diagonals are required, in this case, for the outer and inner corners. And for T splits there’s some extra checking required also. But it’s why I use this method, it allows for a proper looking top-down dungeon/world without having 256 columns in your tileset ;)

      • mataronasd

        You could use a hashmap and associate the source rectangle with the weird tile ID

      • Matthew Arnold

        I am using this same technique but its only implementing 4 way lookups.

        And it resulting in odd looking corner connections between tiles, so ill have to go to 8 way as well.

        great write up though.

  • Kim Pedersen

    Have you considered a bit-wise approach to this?

    I use this myself and it works exceptionally well and is really easy to implement. I got inspired by the article here: http://www.saltgames.com/2010/a-bitwise-method-for-applying-tilemaps/ and it will make it really simple to do tile maps with several types of terrain without ending up in “else if” hell.

    Of cause, your way of doing it works. So, there is really no need to change it when you have a fairly simple map without different terrains.

    Just thought I would throw a bit of inspiration your way :)