Project Polis (Dev Journal #1): Generating the hexagon grid

The news of Lionhead shutting down was quite a shock for all of us in the studio and whilst the following weeks were quite busy, I’ve decided to start working on a game idea I had in my mind for quite a while. The idea itself is quite simple and it evolved from a much more complicated one to its current form, which theoretically should be easier to prototype in a few months. The goal is to create a simple resource management / city building game and write a post every two weeks to document the progress, the challenges faced, how I solved them and planned future work.

The game runs in real time, taking place on a radial hexagon grid centered around your one and only city tile. You place buildings on tiles to gather resources, expand your storage and population capacity and keep your citizens happy. I can best describe this as a simulation, resource management and city building type of game, where the city building and building placement part is completely dynamic and procedural.

Much like CIV and CIV style games I’ll have a hexagon grid, though with a minimal, abstract art style. The prototype will be limited to one city, the center tile, with the adjacent tiles being resource tiles. Resource gathering and management will be similar to most strategy games and mostly inspired by Banished, Tropico and Anno. Finally, and this is the part I wanted to focus in this project, the city will evolve as you build buildings, unlike most CIV games where your city remains pretty much the same while you build it and only changes visually when you advance to a new era.

Generating the grid

First thing we need to do is to generate the hexagon grid. We’ll be constructing a radial hexagon grid with the center tile as the city tile, the next six adjacent tiles will be resource tiles and the outer ring of tiles will be a dead zone, at least for now. The grid will be constructed using separate tiles instead of a big mesh, but later on we’ll investigate the option of having a single continuous mesh and just project a hexagonal grid texture on it. For now we try to design things independently of how the grid is done so we can easily refactor our grid generation if needed.

We’re constructing a tile using the triangular grid found in this post I wrote a long time ago, which allows us to specify the tile’s size and the number of triangles (subdivisions). The grid is then constructed by placing instances of a tile around the city tile using axial coordinates and simple trigonometry to calculate their position in the world.

Image 1: Radial hexagon grid. Radius = 3

Randomizing the resource tiles

Now that we have our grid we’ll need some resources. For now we just randomize the six tiles adjacent to the city, to mountains, forest or plains. From mountains we can get stone, from forest, wood and in plains we can build farms and pastures and get food. Stone and wood are building materials and will be a required cost for buildings, while food and food variety are necessary to keep the population alive and happy. We have a simple randomization algorithm that makes sure that a “required” tile is placed at least once.

base_resources

Image 2: Randomizing resource tiles

Generating the terrain and mountains

Next we need to create the base terrain and the mountains on the mountain tiles. For this a few layers of Perlin noise are sampled in various frequencies and then a smoothing function, that relies on the distance of the vertex from the center of the grid (0, 0, 0), is applied. The good thing with this kind of noise is that we don’t have to worry about our terrain being composed of separate meshes since we can simply translate each vertex to world position and get a value for y using the x and z coordinates. For the noise part we are using the C# port of LibNoise [3]. The reason for the smoothing function is because we want the vertices closer to the edges of the grid to be flat (y = 0).

base_terrain

Image 3: a. two layers of Perlin noise sampled at different frequencies, b. smoothing function, c. end result

With the base terrain done we need to generate the mountains in the mountain tiles. We employ pretty much the same technique as the smoothing function only locally to the affected tile’s mesh and using more “peak” points. We randomly pick 2 or 3 peaks and a random radius for each of them, while making sure the radius is not too big and the points are not too close to each other. Then we raise the vertices around these points and apply a random height factor for each peak – radius pair. Finally we add two layers of noise to give a more organic look. The algorithm is pretty rough but it’s good enough for now.

mountains

Image 4: a. mountains debug, b. mountains

Experimenting

So we’ve got the terrain, we can randomize the tiles and create mountains, but so far it looks a bit boring. I want to achieve a minimal, abstract kind of art style hence the low poly and flat shaded terrain. One of the things I want to definitely try in the future is to colour the vertices depending on the height, resources, biome type, etc, but that requires lot more work and probably some custom shaders, so for now let’s try something simpler.

Initially I added some post processing effects, found in Unity’s standard assets pack, specifically depth of field, ambient obscurance and bloom, which makes it look cooler. If we decide to go mobile we’ll probably have to generate AO textures on the grid generation stage and figure out why DoF and Bloom don’t work on Android, but for now as a proof of concept it’s good enough. Finally I tried distorting each vertex position on the terrain but on the XZ axis. So far we’re using each vertex’s x and z to get a value for y and create a seamless terrain, but why not use it to distort x and z as well? Here are the results and they look quite nice:

Future work

The next two weeks I’ll concentrate mostly on getting some base game mechanics working. I need to get resource distribution on tiles, a system for building things on tiles, the mechanics of how some buildings transform tile resources to resources we can use (eg: food and building materials) and core stats like population, population cap, happiness, population growth rate, etc. There are many things I need to simplify in my mind, so I can lay out the core mechanics and build the basic gameplay systems I need. The next dev journal is probably going to be mostly equations and class diagrams…

References

Be Sociable, Share!
  • Reddit

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *