Dev: Making the world map look more organic.

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.

The 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.

Initial tiles

“Yeah, okay. But is the map procedurally generated?”

“Yes, the map is procedurally generated. That’s what led us to this problematic”

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), i have never encountered an area where you could find a shining sun, singing birds, igloos and penguins meters away from each other. Biomes evolve progressively. Not respecting this law made our map look more like an interface than an actual world seen from above. Since the areas are implemented as independent objects, blending the edges ended up to be a bit tricky

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 2 dimensional world with an orthographic camera, we have the X and Y axis to determine an object’s position in the world. While the Z axis determines the drawing order of that object.

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).

“That technique is called “Chromakey”. Since I am a good fella, I am not just going to feed you, but also teach you how to fish. There is something called Google where you can search for anything. Magical, huh? Use that before embarrassing yourself in here.”

“Hey calm your fishing rod! Here’s an anecdote:

We call this method “the weather channel style” because, for some weird reason, a handful of brainstorming technical folks could only find the weather channel green screen as an example, despite the fact that it was a commonly used technique in their field.”

Implementation

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 a plain with regular weather. The black pixels will be filled with colors from the northeastern neighbor. The pink pixels filled with colors from the eastern neighbor and so on. After the map has been procedurally generated and every area has taken its place, we call our little painter guy to draw over those eye wrecking colors.

Managing shadows

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.

Tadaaa!

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.”