Map tile terrain transitions with 3-4 different types

Making transitions between two different tiles is a fairly well understood problem. The easiest way is to look at the 0.5, 0.5 and use the resulting 4 corner points to select a transition tile, as mentioned here for example: http://playtechs.blogspot.se/2007/04/tileset-design-tip.html

The problem comes when three or four tiles meet, for example:

(s for swamp, p for plains and . for water)

pppp
..sp
..pp


If we look at the offset in the corner, the edges in our transition tile looks like:

pp
.s


In this case there are no suitable transition tiles to be found, as they typically are created to work between 2 types only. Unless we work out a three way transition tile with these types, we appear to be stuck.

I'm well aware of this often referenced article on the tile transitions in Artifact: http://archive.gamedev.net/archive/reference/articles/article934.html

But looking at the actual screenshots from that game, it doesn't seem like it will yield professional looking maps: http://www.samugames.com/artifact/screenshots.htm

Aside from using intermediary tiles (which frankly would be problematic since two out of grassland/swamp/desert would then not be able to border directly to water), are there any solutions?

EDIT

I think I've found a solution that can will create terrain transitions for 3-4 different types, using only one extra transition tile to each set of transition tiles. I've yet to make an implementation of the algorithm, but the mockups look fine. This solution will work well for pixel art.

• Maybe I'm not seeing it, what about the Samugames screenshots are not professional looking? I imagine you don't mean the art style because that can be changed. What's wrong with their transitions? They appear to have multiple places merged that fit your problem description. – MichaelHouse Jul 19 '12 at 0:21
• Look at the (awful) hill/grassland/water transitions here: samugames.com/artifact/images/screen4.png It might be possible to salvage, who knows? In any case, there's no evidence one will be able to make it look good in practice. This is a pretty old article too, but despite that I can't recall seeing this method used in any recent game, contrary to what one would expect if it had yielded sufficiently good results. – Nuoji Jul 19 '12 at 1:28
• @Nuoji: What exactly do you want the hill->water transition to look like? – Nicol Bolas Jul 19 '12 at 1:55
• The professional look depends on point of view. I find it quiet appealing, but it looks kind of retro. But the "unprofessional" look you mentioned is because of the assets and maybe the transitions, and not because of the technique that was used. If you have a very talented gfx guy (or girl), the output can be very nice. – tom van green Jul 19 '12 at 14:18
• @Nuoji I don't see any difference other than art assets. Maybe I don't have the keen eye for such details. Doesn't a hill with water behind it look exactly like that? You can't see the shore because the hill is there... – MichaelHouse Jul 19 '12 at 15:33

4 Answers

I'm currently working on a terrain mapper, that should do exactly what you want. First of all i pregenerated all transitions between the tiles (so per 2 terrain types there would be 2 tiles for the plain terrain textures and around 12 tiles for the transitions). As the number of needed tiles would grow pretty high, when you have multiple terrains and want to support transitions between all the terrain, the tileset would grow pretty big.

Now currently I'm working on another approach, that in theory (and in my prototype) worked pretty well. I still have to implement it, so the needed tilesets are created on the fly, but this is how I do it:

I have a terrain definition, where all terrain types (for example water, grass, rocks, mountains, desert etc.) are stored. After that I establish an order. I'll explain later, why this order is needed. This order defines, how the different terrain types are related to each other. For example, water is lower than sand (beach), sand is lower than grass, grass is lower than mountains. Therefore you can also say, that water and sand are lower than mountains.

Now I have a special alpha texture, that defines the possible transitions.

Here is the tileset I used in my prototype:

You can see, that you have some terrain textures and an alpha map. I handle the alpha map also as tiles, but they are half sized (terrain textures are 64x64, blend textures are 32x32), this means that every terrain can have up to four blend textures (northwest, northeast, southwest, southeast).

Now basically what you do, when you have a transition is this: - Draw the ground texture (blends are always applied on the higher terrain types). - Draw the alpha map with ALPHA_MAP (this only renders the alpha channel) - Draw the second texture with ALPHA_BLEND (this uses the underlying alpha channel, we rendered out before as alpha for the tile).

So basically this is the theory... But you need to do some things, that it works properly.

What I do is following:

• First generate the level (I use perlin noise, to assign the different terrain types). The output is simply a 2d array containing the terrain types (eg: water, dirt, sand).
• A processor goes through this array and checks for some things and outputs a MappedTileLayer (this is my datastructure, to hold the output). The processor does following:
• Map all terrain types to the according tile in the mapped layer.
• Find tiles, that have neighbours with different (lower) terrain types. If there is a lower neighbour, you also have to render this neighbour terrain underneath actual terrain tile, as otherwise the terrain would just blend to black.
• Based on the neighbours, the correct blend tiles are used. Every terrain type consists of 4 blend tiles. So depending on the existing neighbours, the blend tiles are chosen.
• My renderer renders the tiles on the viewport:
• Render all tiles without any transitions (also render the lowest terrain, where blends will be applied). The tiles rendered in this run can be rendered without the need to apply a blend, as they are the lowest terrain tiles.
• Select first overlay tile (currently there are max 4 overlayes. This is the case, when the tile handled has the highest height in relation to the neighbours and every neighbour is from a different terrain type).
• Render the four blend tiles with ALPHA_MAP
• Render the overlying tile with ALPHA_BLEND
• Repeat this step with the next overlay tile, until there are no tiles left

Like this, you do not have to care about multiple terrain types getting together, as they are rendered from lowest to highest terrain type and the transtitions only concern the higher type.

I know that it is a bit complicated at first, but I currently don't have more graphics, because I'm in the middle of refactoring my source. I will add some graphics representing what I do as soon as possible (also better explaining every step).

I hope this will help you.

One small addition: My mapper is built, that there is a default blend texture. But you can define specific blend textures for every terrain type. So for example if you want to make smoth transitions for all mappings besides the beach to water transition, you put the smooth transition as default and only set the custom transtition for the beach tiles. Also, my mapper allows to define multiple transition tiles for each tile type (so if you have a straight edge, you can make multiple blends, so they will alternate).

** Appended ** Because I currently have no assets to show, I created a schematic drawing in paint.net. Keep in mind, I'm a programmer and not and 2d artist, so artistically it is very badly drawn, but it should show, how I tackle the problem with multiple terrain types (>2) coming together). I left out optimizations for simplicity and applying the blending is also not mentioned, as I concentrate on the problem with the multiple terrains.

I will add an example with real textures and blends as soon as I find the time to do so, so this gfx is only temporary.

A explanation to the image I added:

1. In the first grid you see the terrain configuration. W stands for water, S for sand and G for grass.
2. The second grid shows, how the blend tiles are applied. Like I mentioned earlier, the width and height of the blend tiles is the half of the terrain tiles.
3. Here now the first render action happens. The lowest terrain type is water, so we fill all the cells (and all adjacent cells) with the water tiles. So allthough the water tiles only fill the first column of our definition, we have also to fill the second column.
4. Now we draw the next layer, but we only draw the tiles, that won't be blended. Water is a lower terrain then sand, so we do not need to expand to that side. But because the grass is higher, we have to fill the adjacent tiles with sand, where the grass blend will be rendered over.
5. Now based on some patterns, we render the blending parts of the sand. (Now you see, why we need to also fill the adjacent tiles).
6. Here we have repeated steps 4 and 5 (allthough step 4 wouldn't produce any output, as all grass tiles in this examples will contain a blend).

Now you see, in the fourth row in the second column, there is a grass tile. Left of it is a water tile and on top and bottom of it are sand tiles. When we look at the rendering only for this tile, this is what happens:

• The water tile is rendered without a blend.
• The sand tile is rendered with a blend.
• The grass tile is rendered with a blend.

And we could also switch one of the sand tiles and the grass tile on the right to different terrain types, it would still produce correct results.

• You should add some "final result" screenshots if you have them. – DampeS8N Jul 19 '12 at 12:58
• Yeah, I would like to do that, but currently I'm in the middle of the refactoring and I wiped all outputs I made before, so I would need to create the output by hand in paint.net or something similar. I think I should find the time this weekend, to complete my refactoring. Then I can add some screens (and maybe also a video) showing what exactly happens in my implementation. – tom van green Jul 19 '12 at 14:16
• It would be good to see the final output, otherwise it's real hard to decide if it is a viable solution or not. – Nuoji Jul 19 '12 at 14:35
• Like I said, I will add the output as soon as I'm finnished... Though I added a small schematic image, that explains how I tackle the multi terrain problem. I hope it makes things a bit clearer. But the output itself strongly depend on the graphic assets (and as I am no 2d artist, my demo won't look as professional, as you could achieve with this technique). – tom van green Jul 19 '12 at 15:20
• I finished a basic version of my mapper. There are still some quirks and the used blend set is currently not very representativ (professional), but it should work as an example. Until I update my answer, I want to share two videos showing the mapper in action (used two different blend sets): youtu.be/l8PfO2eLaNc , youtu.be/V91KDzWwO24 . These are the tilesets I used: imgur.com/a/Cx8Cs . In the videos I first first drawn some tiles, but later I try to recreate my example from above. I'm also switching the max layer rendered, so you see how the renderer handles every layer. – tom van green Jul 23 '12 at 7:43

Since you're presumably in a situation where you don't need an extremely low-budget solution for technical reasons, and you are also presumably not interested in creating the 200+ unique different tiles that you would need to handle every possible case, you may want to consider a solution that allows you to use alpha testing or blending to handle most cases (like Artifact's solution), but override specific transitions that look poor.

The "base" for any given tile type would be a single solid tile, and then you'd have the 16 or 32 transition tiles, like Artifact. But you could also add a customized transition tile set (another 16 or 32 tiles) between a specific pair of tiles that need additional help. The transition tiles could either be done alpha tested/blended, like the generic transitions, or they could completely replace the lower-precedence tile. This still isn't perfect—say you have a custom water-grass and water-hill transition, but what happens to water that has grass on one side and water on the other?—but it does at least allow you to prioritize.

Ultimately, though, I think this is very much about visual design. There's an art involved in getting a limited range of tiles to look correct, and I suspect that shading is extremely important—a boundary with no appearance of depth will be more jarring than one that's carefully designed.

I researched a lot about this and found only 2 or 3 articles with outdated graphics.

What I would suggest today to render a 2d game-map is to use textures and dominance-based approach, where each terrain-type defines its dominance value: more dominant tiles always overlap the less dominant ones and "blend" into them. Then instead of pre-rendering specific terrain transitions use "blendmaps" to render everything on-the-fly. One blendmap can be used to render many transitions between various textures.

Initially, you can start with this:

• define 3 terrain types and provide 3 textures for rendering
• define 1 blendmap that will be used to blend terrain transitions

If you go with the dominance-based approach then you must account for a possibility that rendering a single tile may require at most 9 blits, one for the tile itself and 8 for neighboring tiles that are more dominant. If you aggregate all surrounding tiles that have equal dominance then you will probably end up with 1-2 blits per tile, at least according to my experience.

Also, when you start implementing a renderer that takes into account surrounding tiles and requires expensive calculations to resolve "how" the tile should be rendered, I suggest to implement a mechanism to invalidate tiles that need such recalculation, and to not do this during the rendering process itself.

Some textures / blendmaps benefits:

• Textures look much nicer when the same tile repeats multiple times
• Adding a new terrain type is a matter of providing a new texture

Here is a high-level article about my implementation of such problem in JS:

I know this is old but this has not been mentioned. Your assumption of the transition tile is wrong. Your transition tile gets 8 transitions instead of your 4. On top of that it can have multiple overlapping layers in order of precedence. In the article they mention they have the following precedence.

Jungle over forest -> forest over rocks -> rocks over hill -> hill over swamp -> swamp over desert -> desert over grass -> grass over water.

Of course this comes with it's limitations but not in the scope you are asking for. I'll take your example layout but cut off the eastern tiles so we end up with 9, we don't need more since there won't be overlaps with tiles not being direct neighbors.

ppp
..s
..p


The middle water tile has a double transition in it's top right corner and bottom right corner. So since swamp goes over plains we first draw all the plains transitions. Then we draw the swamp transition. And thus the 2 corners will end up with 2 transitions drawn over the original water tile. It is up to you to set precedence and the art but this should give you good results. This solution does not offer different transitions for each other type but it is possible with a simple if statement, however your needed assets grow exponentially and that may not worth your while. But I can imagine a transition from swamp into water looks very different then into plains. This is essentially what you are showing in the comments, the mountains blend in very well with the grass but they won't blend in with the water that well. The reason you don't see the grass blend with the water is because the mountain overlaps it. Personally I think it looks fine but I see a lot of room for improvement, the tiles used are not much better then your average programmers art (Sorry to offend the artist, but I'm sure he agree's if he practiced more since then :) ).