Hello there! Here, have a hug! Don’t worry it’s free. Today we will talk about the world map. More precisely, we will focus on the system we thought about to make a cellular map look more organic. You guessed it right, this blog entry is more about technical stuff than game design. If you are interested to know more about the world map gameplay-wise it is right here.
map that we have
P.S: The following art is not final, and is subject to change.
The world map is a set of hexagonal cells that are neighbor to each other. This is a small chunk of the whole thing.
To procedurally generate the map, we need each area to be an independent object so we can assemble them like a puzzle. It is indeed convenient when it comes to generating a random map, but it does have its limitations. One of the limitations is what gathered us today (and made you have a “free” hug).
As you can see in the first picture. The edges between the areas are pretty obvious. That’s exactly what we are aiming to rectify.
Blending the areas
I do not know about you but, where I live (the earth),
Brainstorming for solutions
Superposing the areas with built-in blending zones
A straight forward solution would be to draw the blending zones directly in the areas’ sprites then superpose them on each other. But “nope” says the universe. Since this is a
Since we want the blending zones to be the combination of both neighbor biomes, this solution won’t quite fit our needs.
Superposing the blending zones as independent objects
This method consists of having the blending zone as an independent sprite and superposing it between two neighbor hexagons. We were not too fan of this method, since it seemed to lack a fair bit of… finesse. Oh boy! finesse it definitely lacked. The final look seemed more like an untidy room (See the room that you just pictured in your mind? Now add a slice of pizza on your favorite shirt that you didn’t even bother to put on that chair that is now working as a closet) than an actual organic map that naturally blended.
The object count in the map increased drastically, which also hurt the generation time. Generating the map was not much slower, but it was slower enough for us to consider it. And since we love to write code that worships “the god of scalability” (sometimes more than it should), we were convinced that the drop in performance will show with bigger map size.
Directly drawing on the tile at runtime (The weather channel style)
Spoiler alert! This method is the one we ended up working with. The idea behind it is similar to a commonly used technique in 3D. Such as in normal maps and height maps. As the revolutionary minds that we are, we included world maps to that panoply (pun shamelessly intended).
Since each area (hexagon) will be affected by a maximum of 6 neighbors, we will need 6 variables for each neighbor. These variables are the colors that you see here.
The area above is
As you already know, we do have mountains in our world map. Mountains are tall, thus (yeah, I do wear glasses), their shadow should be of the same caliber. We thought of this as an opportunity to further contribute to the organic aspect of the map. Instead of only drawing a mountain’s shadow on its own tile, we decided to make it overextend to neighbor tiles to further express the feeling that the tiles exist in the same world.
As for the chromakey colors, we used 2 variations for each one of them to know if a pixel should be shadowy or not. We are also using 2 variations of each tile. One with shadow overextending in it (in case there is a neighboring mountain) and one without. After what is said and done we ended up with this render.
Well that’s it folk! Tell us what you think about our approach, would you have done the same?
“By the way, I want my “free” million dollars for the “free” hug. C’mon man! A free hug is priceless.”