Skip to content

paullaffitte/lua-map-generator-workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lua Map Generator [WORKSHOP]

This workshop will introduce you to 2D map generation in lua language, with the help of LÖVE2D.

Here is an example of what you could obtain. island

What is map generation ?

Map generation is a powerful technique used in many games to create map or parts of a map with algorithms. The method of creating data from algorithms is named procedural generation. It has been used in a lot of games, like The Elder Scrolls (most of them), Age of Empire, The Binding of Isaac, No Man's Sky, or the well known Minecraft.

The boilerplate architecture

You can find at the root of the repository three folders.

  • assets basic assets to quickly bootstrap you generator
  • example example project
  • src you already know ;)

Launch the generator

To launch the generator, you obviously need to have lua and LÖVE2D installed. Then you can run love in the root of this repository with love . and you can even give a specific seed to your generator with love . 8436.

If somewhere you get lost, you can run the example project by running the start.sh script in the example folder and look at the sources. But if you want to enjoy this workshop I highly encourage you to write your own code! Don't just copy paste, at the end it's often a waste of time.

The src folder

In the src folder, you can found the terrain.lua file, it's in this file that you're expected to code. But feel free to look at the other files, you could learn some interesting stuff, like how chunks works.

game.lua contains the main loop and handle rendering using the terrain:render function. utils.lua contains some functions that you could find useful.

Make some noise !

What is perlin noise ?

Perlin noise is a algorithm that generate noise with a pseudo-random appearance, yet all of its visual details are the same size. It can be use in any dimensions. This function is only pseudo-random and not random, therefore it can be represented in a mathematical way since for an input A, it will always return an output B, thus f(A) = B.

perlin noise

Perlin how to

You can find a function utils.noise(x, y) in utils.lua, this function wrap a 3D perlin noise from LÖVE2D, the third dimension being used as a seed. The function takes two parameters which are the coordinates of the point to generate from the perlin noise. It can easily be used in terrain:render(x, y), since they share the same prototype.

Now that we know how to generate noise, it's time to render it! You just have to return the color that you want at the position (x, y) in terrain:render, just like that return 0, 0.7, 0.3. The values should stay between 0 and 1.

A pretty easy way to debug your values is to use the function utils.valueToPixel(value, min, max). It takes a value and return a pixel in gray scale with black being min and white being max.

Get down to business

Hawaii

Let's generate an island! To do so, let's imagine that the noise that we are generating correspond to the altitude of our map, with the sea level being 0.75, so 75% of our map will be water, the remaning 25% being earth.

You can use the fonction utils.pixelFromTexture(x, y, texture) to get a pixel from a texture of terrain.assets. Try to render either water or grass depending on the altitude. You can also merge easily two textures with utils.mergeTextures(x, y, t1, t2, ratio)

Tweak parameters

You should get a pretty wierd result for now but as you can see, there is water and grass. But maybe you would like something looking more like islands. First of all, you could use several noises with different scales as described here. You can combine them in several ways depending on what you are trying to do, by sum, by average, by multiplication.

perlin noises 1D

combined perlin noises 1D

You can also apply modifications on noises, maybe adjusting the contrast with utils.contrast(value, factor), it's a mathematical function represented as contrast(value, factor) = (value - 0.5) * factor + 0.5.

contrast(value, factor) = (value - 0.5) * factor + 0.5

Going further

Once you got fine results, you may want to add some more details. You could try to use one more noise to generate temperature, that you can use to adjust colors consequently with a blue shift when it's cold, and a red shift when it's hot. You could also generate some snow on montains or icebergs in the ocean. On the same model, why not trying to generate humidity ?

And what about biomes ? Now that you have temperature and humidity, you could try to define conditions on those both parameters to determine in what biome you are ! Let's imagine that we have two axis, the temperature is on the X axis and the humidity on the Y one. You can define a surface on the graph that describe a biome like on this one from wikipedia. Climate_influence_on_terrestrial_biome

Well, it's now up to you to continue to tweak your generator, add new rules, and maybe even trying to generate maps in 3 dimensions ?

Some links

Perlin

Vornoi

About

An introduction to 2D map generation with lua and LÖVE2D

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages