"In the beginning God created the heaven and the earth." - The Bible, Genesis 1 verse 1
Genesis is a Lua / LÖVE2D based world generator.
My goals with Genesis are:
- To have a library that can be easily integrated into games
- To be able to generate interesting random patterns
- Worlds should be seedable: the same seed value should generate the same world
- Worlds should be easily usable with cubemaps: it should be possible to wrap the world around a cube
- Worlds should have biomes, rivers, seas, lakes, mountains
- Allow some configuration of the generator, e.g. sea level
The maps that are generated by Genesis are based around a cube. As such, every time a world map is generated, actually there will be 6 face maps generated, one for each side of an imaginary cube.
The faces are oriented as such:
5
1 2 3 4
6
So face number 5 is the north pole, face number 6 the south pole. The equator runs through faces 1 to 4.
A face is compromised of tiles. Tiles contain various data for a coordinate on the cube, like the height, heat and moisture values.
The API is still a work-in-progress and as such, subject to change. With that said what follows is a short description of the API at time of writing.
First we need to import the library, which can be done as follows:
require 'genesis'
Assuming the genesis directory is in the root of your project.
To generate a new map, just call the generate
function with a size and
optionally a seed value and sea level. When using the same seed value, the same
map will be created. In no seed value is supplied, a random seed will be used.
local tileMap = genesis.generate(100) --> generates a map of 6 x 100 x 100
After a map is generated, it is possible to request tiles based on face number, x- and y-coordinates.
local tile = tileMap[1][20][30] -- get tile at face 1, x-coord 20, y-coord 30
It is easy to loop through all tiles, by using the eachTile
function.
genesis.eachTile(function(tile, face, x, y)
-- do something with the tile
end)
A tile is just a number value composed of several integers. In order to retrieve specific information of a tile, we can use the following functions:
local tile = tileMap[1][20][30] -- get tile at face 1, x-coord 20, y-coord 30
-- height info
local height = genesis.getHeightValue(tile) --> number in range 0 .. 255
local heightType = genesis.getHeightType(tile) --> number in range 1 .. 6
--> see: genesis.HeightType
-- moisture, heat & biome type
local moistureType = genesis.getMoistureType(tile) --> number in range 1 .. 6
--> see: genesis.MoistureType
local heatType = genesis.getHeatType(tile) --> number in range 1 .. 6
--> see: genesis.HeatType
local biomeType = genesis.getBiomeType(tile) --> number in range 1 .. 12
--> see: genesis.BiomeType
-- adjacent height & biome flags, see: genesis.EqualityFlags
local adjHeightFlags = genesis.getAdjHeightFlags(tile) -- EQ_TOP, EQ_LEFT, EQ_RIGHT, EQ_BOTTOM, EQ_ALL
local adjBiomeFlags = genesis.getAdjBiomeFlags(tile) -- EQ_TOP, EQ_LEFT, EQ_RIGHT, EQ_BOTTOM, EQ_ALL
With regards to height, the height type indicates that neighbouring tiles are inside same height range. When tiles are inside the same height range, they get the same height type. Height types are defined in heighttypes.lua.
The moisture and heat types are used to generate the biome type. The biome type can be used to render appropriate tiles on the map for different biomes, like desert, savanna, tundra, etc... See biometype.lua for a list of all biome types.
Finally the adjacent flags functions can be used to figure out if neighbouring tiles are of the same height or biome type. This can be useful for rendering maps. For example, if the neighbouring tiles are not of equal type, it is possible to draw a border.
The Genesis source code is based on a variety of ideas and posts found on the internet. For reference I've added the most important links here.