Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

LuaintermediatemobileAI generated

Procedural Island Generator

Build a procedural island generator in Lua with LÖVE (which also runs on Android): from a seed number it creates a unique island with a height map, a clean coastline, beaches, rivers flowing downhill, and biomes such as forest, grassland, desert and snow, decided by height and moisture. The same seed always creates exactly the same island, so worlds can be shared with just a number. You can explore different seeds and settings on screen and export the map as an image and as data for a game. You'll learn noise functions and layering them, shaping terrain into islands, flood fill and flow algorithms, seeded randomness, drawing large maps efficiently, and testing algorithms that produce random-looking output.

Estimate
~13h
Steps
7
Completed by
0
Proposed by
codeseed.app

LÖVE · Lua · busted

Project roadmap

  1. 01

    Define inputs and outputs

    ~1.5h

    Write DESIGN.md: the inputs (seed, map size, sea level and noise settings), the outputs (a grid of cells with height, moisture, biome and whether it's water, land, beach or river, plus a PNG image and a JSON or Lua data file), the biome table (height and moisture ranges) and the rule that everything must depend only on the seed. Done when: DESIGN.md defines the inputs, outputs and biome rules.

  2. 02

    Generate the height map

    ~2.5h

    Using love.math.noise (seeded by offsetting coordinates with values from love.math.newRandomGenerator(seed)), layer several octaves of noise, then multiply by a falloff based on distance from the center so the edges become ocean and the middle forms an island. Normalize heights to 0 to 1. Keep the generator in modules that don't draw anything. Done when: different seeds give different islands surrounded by water, and the same seed gives the same heights.

  3. 03

    Shape coastlines and add rivers

    ~2.5h

    Mark water below the sea level, then flood fill from the map edge to separate the ocean from inland lakes. Remove tiny islands and lakes below a minimum size. Mark beaches next to the ocean. Start rivers at random high points (from the seeded generator) and let them flow to the lowest neighboring cell until they reach water. Done when: islands have clean coasts, lakes and rivers that flow downhill to the sea.

  4. 04

    Assign biomes

    ~1.5h

    Generate a second noise layer for moisture, increased near rivers and lakes, and assign each land cell a biome from the table using its height and moisture. Done when: the island shows sensible biomes, with snow on peaks, forests near water and deserts in dry lowlands.

  5. 05

    Draw and explore

    ~2h

    Draw the map once into a love.graphics.newImage (from ImageData) or a Canvas instead of drawing every cell each frame, with a color per biome. Add controls: a new random seed, entering a seed, adjusting the sea level, toggling layers (height, moisture, biomes and rivers), and zooming and panning with touch or the mouse. Show the seed on screen. Done when: exploring seeds and settings is smooth.

  6. 06

    Export the island

    ~1h

    Export the map as a PNG (with ImageData:encode) and the grid as a data file in the save folder, including the seed and settings, so a game can load it. Loading an exported file must give the same map as regenerating from its seed. Done when: exported files are written and match the map on screen.

  7. 07

    Test it

    ~2h

    Write tests for the generator modules (with busted, providing a small noise function when running outside LÖVE): the same seed gives identical grids, rivers always flow downhill and end in water, no water cell is marked as land, biome assignment at table boundaries, and small islands and lakes are removed. Done when: the tests pass.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~13h · 7 steps

Tech stack

LÖVELuabusted