Building the maps in Idle Realm (Part 3)

Randomly generating entity data on new games

In Part 1, I talked about building the terrain and in Part 2, I talked about placing entity locations on the map. But when the player starts a new game and is randomly slotted into a starting location, what happens with the enemies? All enemy troops and bases are defined on the map as just locations, so the game needs to assign what type of enemy gets slotted into these locations when the game starts.

All of this will be calculated based upon the enemy spawn location distance from the player starting location!

When the starting location is chosen, every enemy troop and base location will be placed in a list and sorted based upon their distance to the starting location. The game will then set the closest enemy as the Tutorial Wolf which is super easy and is always next to the player base, due to how we generate starting location data. All other enemies will be separated into some tiers, with tier 1 enemies being close by, and tier 5 enemies being the furthest from the player.

These tiers are used for deciding what troops can exist in the pool of enemies we will select from. Tier 1 will have very weak enemies, namely wolves and hyenas, and tier 5 will have a majority of very strong enemies with some easier enemies sprinkled in. Each enemy type has weighted odds based upon the tier they are in, so tier 1 might have a lot of 10-200 strength enemies, but occasionally a 400 strength enemy might be pulled to shake things up.

Once an enemy is randomly picked in the tier, the game will set the strength of the enemy based upon its min and max strength. Just because you found a wolf doesn’t mean it will always have a strength of 5. It might have a strength of 50 and you’ll need to bring more troops to defeat it. Likewise, you might find a wolf in tier 5 territory and will be treated with an easy victory.

The same technique is applied to the enemy bases, but since there are fewer types of bases, it basically breaks the map down into easy, medium, and hard areas for the enemy bases, radiating out from the starting location.

By generating enemies and bases in this way, the player is faced with incremental difficulty as they expand past their initial base, no matter where their starting location appears on the map. With the occasional sprinkling in of easier enemies in the higher tiers, the outer areas will appear more diverse and the difficulty might be hidden a little bit.

That wraps up the three part series about how maps are generated for Idle Realm!

Building the maps in Idle Realm (Part 2)

Randomly generating entity locations

In Part 1, I talked about the creation of the map’s terrain. But that’s not all that the map has! The map data file also has player starting locations, enemy troop and base locations, as well as ruins locations. Dropping down all of these locations so that the enemy spread is pretty good is time consuming as well, with this process taking around 15 minutes to place 400 or so enemies.

Time for more randomization!

The map generator was modified to also grab every terrain type that a troop can be on and then apply a min and max fill percentage, dropping down all enemies on the map. With all enemy locations taken care of for me, I just need to drop down player starting locations, enemy bases and ruins, which is only about 50 items. These items I actually want to place by hand, making sure they appear in interesting or useful areas.

Although I am placing the player starting locations by hand, the terrain around them will typically not have the starting requirements I need, so more randomization to the rescue! Starting areas need specific counts of each type of land and they also need only one enemy troop touching the border. To take care of this, when I drop down the player starting location in the editor, it will apply a special starting location brush that will grab all the terrain within a 5 tile radius, convert it all to grass, and then populate the terrain types it needs at the distances required from the center of the location. We get mountains on the edges due to this. Any enemies in this range will be removed and one new enemy will be spawned on the edge of the starting location. This method ensures that every starting location is the same, functionally, and I don’t have to manually craft the starting location 10-12 times per map.

The great thing about the map generator is that it works for all map sizes I support, from 32×32 all the way up to 96×96. If I want to try a new map size, such as 32×96, I can just generate it, drop a couple starting locations and start testing that map in 2 minutes. If it works out, I can add details and make it final.

Generating player starting locations, enemy base locations and ruins locations can also be handled procedurally. Although I don’t need it right now, I might add that feature in the future if I want completely randomized maps generated on the client machine every time they start a new game instead of picking from pre-made maps.

For player locations, the generator could visit every land tile and do a search to find how many tiles away the closest water tile is, and possibly if any other starting location is within 15 tiles away. Then, build a list of all tiles that are at least 5-6 tiles away from water and pick a location from that list. Do this multiple times until all player locations are set, with the starting location check ensuring that no two locations overlap or are too close.

Enemy bases would do the same thing, but can relax some of the water tile requirements and also ensure they aren’t too close to another enemy base.

Ruins can be placed randomly, just like enemy troops, but they need to make sure they are not close to other ruins. Also, the land around a ruin should look interesting, so depending on the biome that it is generated in, perhaps it can have a preset ruins brush that affects the terrain at its location, so it looks more unique and special. Dropping it in the forest? Surround it by trees. In the mountains? Make it look like it is surrounded by mountains, with one tile open as if a path exists to the ruins. That type of thing.

In the end, thanks to lots of procedural generation and a little bit of hand crafting, terrain creation takes about 4 minutes and placing starting locations for entities also takes about 4 minutes. 8 minutes to generate a map is much better than over an hour.

Next time, I will talk about randomly generating the entity data when the player starts a new game!

Building the maps in Idle Realm (Part 1)

 Combining procedural map generation with handcrafted details

If you’re creating a game that has a large area of land for the player to interact with, you will probably create a very simplistic map to use while you create the features of the game. It will have the bare minimums required to test your features and, since it will be thrown away later, will probably look like a hot mess. On a small team with limited resources, we decided that building the final maps would happen when the features were complete, otherwise we ran the risk of rebuilding maps from scratch or doing heavy modifications to deal with new or updated features.

At first, Idle Realm had a map that was 128×128 tiles in size and was populated with nothing but water, with the exception of the center of the map, which had 6 of each type of land type next to each other. The map was hard-coded into the source code and was fairly ugly, but got the job done.

When the features were nearly finished, it was time to start sending the build out to more beta testers and for that, I needed a real map saved in a file. All maps in Idle Realm are typically large islands, always surrounded by a border of at least 2-3 tiles of water. To make this happen, an in-game map editor was created. I personally like working with in-game editors because I can modify the content in real-time and see the results. Also, painting a map while in the game is fun!

The editor’s first purpose was to simply let me pick a terrain type and then paint the tiles on the map. There was no configurable brush size, so it was one tile at a time. Also, the map was still hard-coded to be 128×128 in size. It turns out that building such a large map was a pain with this method, so I dialed down the test map by creating a smaller 64×64 sized island in the middle of a giant water map. Surprisingly, having the map be this small felt good in the game and if I had done the 128×128 size version, it would have felt too large. In the end, I settled on a map that is about 80×80.

More testing and more updates to the map created the need to save and load the map into separate files, pick a size for the terrain brush and toggle the ability to overwrite water tiles (useful when you have a larger brush and want to add sand to the edges of the water without killing your water tiles in the process). This was really all I needed to make maps, but making a full size map with all the details still took close to an hour.

Time for some procedural generation!

The first way to add randomization to the editor was via the terrain brush size. Terrain brushes, when painting an area with a radius of 20, looked pretty bad. It converted everything to that one tile!

To deal with this, I added a fill percentage to the brush. The editor would grab all tiles within the radius of the brush and then roll the dice. A fill rate for 50 would convert 50% of the tiles into the new tile, and the other tiles would be converted to grass. Painting a mountain range with a fill rate for 60 made for a pretty nice grouping of mountains in a line, sand near the water with a fill rate of 80 worked out well too. Littering a large area of grass with 10% bushes or trees worked great. With this tool, the map creation process dropped down to 40 minutes.

When analyzing the amount of time it took to build a map, I discovered about half of the time was spent building the silhouette of the island. To help in that area, I added a new button to the editor called Generate that would create a new island full of grass, surrounded by water. The generation process involved using perlin noise for a height map combined with a radial gradient at the center of the map to push the terrain further into the water near the edges of the map. This resulted in some fairly quick, fairly nice island shapes!

Even with the generated island, I would need to touch up some of the island edges to make them more interesting. Also, it was all grass and I needed dirt, trees, mountains, rivers and more to be added by hand. Still, the map creation process dropped down to about 20 minutes after this change.

Of course, I wanted even more to be generated randomly, so I added more layers of noise to the generation process to get heat and moisture maps, combining them with the height maps to generate a biome map. The great thing about the biome map was that I could define the odds of all the terrain types appearing in the biome and then select every tile of a biome type and roll more dice, generating all the terrain needed for the biomes. Deserts would be mostly sand with some dirt and trees appearing, high mountains would be mostly dirt and mountain terrain, etc.

Now, I would simply generate an island, look at the overall look and biome layout and if I didn’t like it, I would generate another. Once I found one I liked, I needed to make some customized changes to make certain areas feel better as well as add rivers, because those still needed to be hand crafted. Still, the whole process would take around 7 minutes. Going from an hour down to 7 minutes to make a map is huge! I can pump out quite a few maps anytime I wanted without it being a huge chore.

But rivers… I wanted to tackle those too, so I turned to ridged perlin noise. When generating this type of noise, it kind of looks like rivers on a map:

So, I used it for that exact purpose. Now, I drop the ridged noise on the map to carve out where the rivers should be and the end result looks pretty good. Map creation time is now down to about 4 minutes!

Next, in Part 2, I talk about randomly generating entity locations on the map!

Hello World!

Why shoot for the moon, when you can eat it?

Hi, my name is Michael! Together with Melissa, Roz and Nick, we’re Eat the Moon!

Although we are a small team, we have big goals and huge plans, so we hope you can join us on this crazy journey we’re about to begin.

After lots of hard work, Idle Realm, our first dip into the mobile space, is officially in soft launch in select territories! We can’t wait to push the button and bring this game world wide, so stay turned for more information on that!

There were a lot of lessons learned during the production of this game, both technical and personal. Over the next few months, we’ll be releasing blog entries that talk about certain aspects of the game’s creation. Some entries will be technical, others will offer a glimpse into the creative process behind how we made the game and offer insight into how and why things came to be.

When the first line of code was written, I also started a journal that would be used to record my thought process and decisions behind what ultimately became Idle Realm. The journal is quite long, so I have a lot to parse and pull from for future blog posts.

Thanks for reading and we’ll see you soon!