This is part 23 of a tutorial series about hexagon maps. It is the first of a few tutorials that will cover how to generate maps procedurally.

This tutorial is made with Unity 2017.1.0.

Generating Maps

While we can manually create any map we like, this can take a lot of time. It would be convenient if our app could help a designer get started by generating a map for them, which they could them modify as desired. A step further is to do away with manual design entirely, fully relying on the app itself to generate a finished map for us. That would make it possible to play a game with a new map every time, ensuring that each new game session will be different. Not knowing the layout of the map you'll play on beforehand is essential when exploration is a big part of a game that's meant to be played more than once. To make all this possible, we have to create an algorithm for generating maps.

What kind of map-generating algorithm you need depends on the kind of maps that your app requires. There isn't a single best approach for this, but there will always be a trade-off between believability and playability.

Believability is about the player of a game accepting that a map is possible and real. This doesn't mean that maps have to appear like they're part of our planet. They could be for another planet or a completely different reality. But if it's supposed to represent earthen terrain, it should at least somewhat look the part.

Playability concerns whether maps support the gameplay experience that you're going for. It is often at odds with believability. For example, while mountain ranges might look great, they also logically severely limit the movement and vision of units. If that's not desired, you have to make do without mountains, which might lower believability and limits the expressiveness of your game. Alternatively, you could keep mountains but lessen their impact on gameplay, which might also lower believability.

Besides that, there's also feasibility. For example, you could produce a very realistic-looking earth-like planet by simulating plate tectonics, erosion, rainfall, volcanic eruptions, meteor impacts, lunar influence, and so on. But that will take a long time to develop. Also, generating such a planet might take a while, and players won't appreciate having to wait minutes before they can start a new game. So while simulation can be a powerful tool, it has a cost.

Games are full with trade-offs between believability, playability, and feasibility. Sometimes, these trade-offs go unnoticed, seem perfectly normal, or are arbitrary, inconsistent, or jarring, depending on the choices and priorities of whoever made the game. This isn't limited to map generation, but it's something that you have to be very aware of when developing a procedural map generator. You could end up spending a lot of time creating an algorithm that generates beautiful maps that are also useless for the game you're trying to make.

In this tutorial series we're going for earth-like terrain. It should look interesting, with a lot of variety, no large homogenous areas. The scale of the terrain will be large, with maps covering one or more continents, oceanic regions, or even an entire planet. We want to have reasonable control over the geography, including the landmass, climate, how many regions there are, and how rough the terrain is. This tutorial will lay the foundation for the landmass.

Starting in Edit Mode As we're going to focus on the map and not gameplay, it's convenient to directly start our app in edit mode. That way we'll immediately see the maps. So adjust HexMapEditor.Awake to set the edit mode to true and enable the edit mode shader keyword. Also adjust the default state of the edit toggle in the GUI. void Awake () { terrainMaterial.DisableKeyword("GRID_ON"); Shader.EnableKeyword("HEX_MAP_EDIT_MODE"); SetEditMode( true ); }

Map Generator Because procedural map generation requires quite a bit of code, we're not going to add that to HexGrid directly. Instead, we'll create a new HexMapGenerator component for it, keeping HexGrid unaware of it. This also makes it easier to switch to a different algorithm later, if you would like to. The generator requires a reference to the grid, so give it a public field for that. Besides that, add a public GenerateMap method that will do the algorithm's work. Give it the map dimensions as parameters, then have it use those to create a new empty map. using System.Collections.Generic; using UnityEngine; public class HexMapGenerator : MonoBehaviour { public HexGrid grid; public void GenerateMap (int x, int z) { grid.CreateMap(x, z); } } Add an object with the HexMapGenerator component to the scene and hook it up to the grid. Map generator object.

Adjusting the New Map Menu We'll adjust NewMapMenu so it can also generate maps, besides creating empty ones. We'll control what it does via a boolean generateMaps field, which is set to true by default. Create a public method to set this field, like the we did for toggle options of HexMapEditor . Add a corresponding toggle to the menu UI and connect it to the method. bool generateMaps = true; public void ToggleMapGeneration (bool toggle) { generateMaps = toggle; } New map menu with toggle. Give the menu a reference to the map generator. Then have it invoke the generator's GenerateMap method instead of directly going for the grid's CreateMap , when appropriate. public HexMapGenerator mapGenerator; … void CreateMap (int x, int z) { if (generateMaps) { mapGenerator.GenerateMap(x, z); } else { hexGrid.CreateMap(x, z); } HexMapCamera.ValidatePosition(); Close(); } Hooked up to the generator.