My first posts on this blog so far were all about some kind of game development meta-topics: app store visibility, my unsuccessful wallpaper, social media shenanigans. Therefore it is time to prove that I’m actually doing some game development before you fall asleep. 😉 Today I want to show you something I have been working on over the last days for my upcoming android game: I drew and programmed a “fog of war” tileset.
For the case you are not THAT into game development, I might need to explain the terms “tileset” and “fog of war” first. If you already know what these terms mean because you are a wizard, you may safely skip this paragraph. For everybody else: A “tileset” basically is a set of multiple graphics that are arranged repeatedly to display larger areas in your game. The “area” in question could be an overhead map of your game or the side view of a level in the game. This image of a tile-based scenery explains it almost without words: In the upper part of the image you can see the so called “tiles” with their black background which are assembled to a nice scenery below.
“Fog of war” in computer games refers to a gameplay mechanic that is often found in the strategy genre. In most cases, these games are designed in such way that the player can only see as far as his own units / buildings on the battlefield can. Everything else is hidden in the so called “fog of war”, which is often represented by a gray or black fog that occludes the view of the player. (See some examples here.) When a game uses “fog of war”, players need to take care of reconnaissance if they want to know what their enemies are up to, which adds an additional exciting element to the gameplay.
In my game there will be a strategy part in which the player needs to explore a randomly generated map. The exploration is turn-based and somewhat tactical, as the player might get attacked early if he or she makes a wrong move. The map is drawn using a tileset and it is covered by fog of war at the beginning. The player is allowed to uncover a certain part of the map for each turn. In the beginning, I started out with a very simple tileset that only consisted out of squares in different colors to represent the different areas:
The black “A1” square represents an area covered with fog of war, B1 (transparent) is the uncovered area, C1 (brownish) are the border areas and so on. The “circles” are test graphics for the various things the player might or might not find behind the fog of war when the map is uncovered. Of course a map using these tiles alone would look very ugly, and this was only used for the first design tests. When I wanted to add better graphics to the prototype, I realized quickly that it would not be sufficient to only exchange the squares with some nice textures: I wanted the borders to be somewhat round and soft and not all blocky. so I thought: Hey, all I need is round borders, right? So I will only need 9 tiles for the fog of war:
Soon after creating this, I noticed that this approach would create a different problem: Now I also needed a minimum of 3 x 3 fields to be covered by fog of war. Smaller portions could not be displayed using this tileset because the above tileset already represents the smallest possible “fog cloud” that can be drawn while keeping the borders intact. But the current gameplay was originally designed on “single-field” basis, meaning the player could uncover single fields of the fog in certain cases. Also I noticed, that apparently I was missing some tiles to display the borders in certain corners:
After adding these tiles, I discovered quickly that I would need tiles with two corners as well:
And when I started to make it possible to support single 1 x 1 fields being covered by fog of war, all hell broke loose. In the end, I had to create all these following tiles to support any possible combination that could occur in the game:
After I had done this, I had to modify the code for the “uncovering” mechanism: Before the new tileset, I would only exchange a covered tile with an uncovered one. Now I had to deal with displaying the correct tile according to its neighbors. The brute force solution to this would be to look at the surrounding tiles and do a check like “If the ID of the tile of the top left is A and the ID on the right is B, well then the tile I need to display must be C.” The problem was that I would need to write 255 of these checks, as this is the number of all possible combinations of covered / uncovered tiles that can occur.
The solution to this problem lies within the term “combinations of covered and uncovered tiles”. To determine the tile that needs to be drawn, one must analyze all surrounding tiles. If you look at the second screenshot from above, there are 3 tiles on each side of the center tile. There can be various combinations of tiles in this 3×3 frame that can influence the center tile:
Each of the surrounding tiles around the center tile (c) can be expressed as either covered (1) or uncovered (0) which leads to the following situation for the examples:
But what is this good for? Well, If you go from the top left to the bottom right, and “collect” all the numbers to a combined binary number, you get an unique code for this tile constellation. In the example in the middle, this code is: 01011010. And here comes the good part: Every time the same constellation of uncovered and covered tiles occurs in our 3×3 frame, the center tile will always be the same. Really? Let’s check this again by modifying the center example:
Although the surrounding tiles have changed, the “code” for the surrounding tiles is still the same, so the same center tile can be used.
So all I had to do is to write down all possible combinations of 0s and 1s for the 8 surrounding tiles (255 as the wizards of you already have figured out) and assign the ID for the center tile that needs to be drawn when this combination occurs. I then stored this in a so called lookup-table which I can access from the program code, et voilá:
Now I am able to display any complex pattern that the player will carve in the fog of war. I still need to make some adaptions for the stuff that jumps on you when you turn the wrong stone, but I am already happy that this works as intended now.
This concludes my adventures in tilesets. Please know that I neither consider this being a complete programming tutorial, nor do I think that “this is the best way to program tilesets”. There might be much better solutions for your personal tileset troubles. The goal of this blog post was just to give you a little insight on what kind of things I’m working on at the moment, nothing more.
If the description helped or inspired you nevertheless, I’m glad that my expectations have even been excelled. 😉