To generate a random world I need two main classes: TileData and WorldData.

World Data

WorldData is a ScriptableObject and has members to modify the generation of a world with different values. The WorldData object will also have the Generate() function to make a new world and store the TileDatas that belong to that world.

Here’s the pseudocode for the world generation:

func Generate(int width, int height)
    set Tiles as empty list of TileData
    for int in width
        for int in height
            CreateNewTile()
            SetTileNeighbours()
            AddTileToTiles()
        end for
    end for

    set landBudget = (int)(width * (float)height * m_landPercentage);

    while landBudget > 0
        landBudget = GenerateLandChunk()
    end while
end func

The values that can be changed in the inspector modify how the generate function works: world data inspector

TileData

When the WorldData generates a new world it stores a list of tiles as TileData, the WorldData object does not handle the instantiating of the world, only generating the data for it and so holds the TileData it generates.

The core of the TileData class resides in the HexCoordinates HexMatrics structs. These handle the positioning and the size of the tile.

HexCoordinates

On a traditionl 2D grid there are the X and Y axis which determine the coordinates of a cell, in a hexagonal grid there also needs to be a Z axis.

In my implementation the axis are as follows:

  • X is the horizontal axis, where 0 is on the left and increases to the right
  • Y is the vertical axis, where 0 is on the bottom and increases up
  • Z is the diagonal axis, where 0 is the bottom left and increases to the top right.


Along with the coordinates there is a HexDirections enum is used to determine neighbours and contains the values NE, E, SE, SW, W, NW.

HexMatrics

The HexMatrics class determines the size of the tile using the outer radius and calculating the inner radius.

hex matrics

public HexMatrics(float outerRadius)
{
    OuterRadius = outerRadius;
    InnerRadius = outerRadius * 0.866025404f;
}

World Instantiater

The WorldData scriptable object holds all the information about the generated tiles, the WorldInstaniater component uses the WorldData to instantiate a tile prefab and create the world in the scene.

Here is the world instantiated into the scene, currently I make each land chunk a random terrain type this gives the illusion of biomes, however I will be implementing a more realistic biomes system. world map generation