Procedural World Generation

Deniz TrakaDeniz Traka
3 min read

The foundation of any open-world survival RPG lies in its world generation. For the 2D RPG Project Accelerator, I’ve built a procedural terrain system that creates natural-looking islands using noise functions, terrain templates, and smart resource placement.

Let’s break it down.


🌍 Island-Based Procedural Generation

The world map is generated on a grid using Perlin Noise to determine elevation. Each tile’s height decides what kind of terrain it becomes.

But to make sure the map actually looks like an island (and not a weird square blob), I applied a falloff function to lower elevation near the edges.

🔁 Island Falloff Function

The falloff function is essentially a radial gradient from the center of the map:

float distanceX = Mathf.Abs(x - mapCenterX) / mapHalfWidth;
float distanceY = Mathf.Abs(y - mapCenterY) / mapHalfHeight;
float distance = Mathf.Max(distanceX, distanceY);

float falloff = Mathf.Pow(distance, falloffStrength);
heightValue -= falloff;

This ensures the center stays high enough for land while the edges naturally fade into water — perfect for island generation.


🌳 Terrain Templates

Each tile gets a terrain type based on its final height:

if (height < 0.3f) return TileType.Water;
if (height < 0.4f) return TileType.Sand;
if (height < 0.7f) return TileType.Grass;
return TileType.Rock;

These thresholds are defined in terrain templates, which makes the system super customizable.

Each template includes:

  • Height thresholds

  • Tile sprites and colors

  • Spawn rules for resources and props

You can easily create new biome types (snowy, volcanic, desert) just by tweaking or swapping templates.


🌾 Resource Distribution with Poisson Sampling

Resources like trees, ores, and berry bushes shouldn’t be placed randomly or uniformly. That’s where Poisson Disc Sampling comes in — it ensures evenly spaced, natural-looking placement.

📐 What is Poisson Sampling?

It’s an algorithm that places points with a minimum distance between them. Perfect for spreading objects in a way that feels organic.

✅ Example Usage

List<Vector2> treeSpots = PoissonSampler.Generate(
    regionSize: new Vector2(chunkWidth, chunkHeight),
    radius: 4f,
    sampleAttempts: 30
);

Once you have the points, just check the terrain type under each point, and if it’s valid (e.g., grass), place the resource.

foreach (var pos in treeSpots)
{
    if (GetTileAt(pos) == TileType.Grass)
    {
        Place(TreePrefab, pos);
    }
}

This method gives forests, berry clusters, and ore veins a believable, spaced-out look.


📃 Procedurally Generated Tilemap with Resources


🚀 Why This Matters

The combination of island shaping, terrain templates, and resource placement ensures every new world feels handcrafted — without any manual work. It’s procedural generation with just the right amount of control.


📆 What’s Next?

With this system in place, upcoming features will focus on:

  • Saving/loading generated maps

  • Dungeon entrances and POI markers


📃 Try It Now

This procedural generation system is available as part of version 1.2.0 of the 2D RPG Project Accelerator.

https://assetstore.unity.com/packages/2d/2d-rpg-project-accelerator-296300

As always, hit me up with ideas, bugs, or questions. Can’t wait to see what kind of worlds you build! 🌍

0
Subscribe to my newsletter

Read articles from Deniz Traka directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Deniz Traka
Deniz Traka