Skip to content
Development
Skill

/procedural-generation

Procedural generation patterns — Perlin/Simplex noise, BSP dungeon generation, random walk, loot tables with weighted random, wave function collapse basics, seed-based reproducibility.

From plugin
everything-claude-unity
2442 skills20 agents27 commands
Install
$ npx -y skills add XeldarAlz/everything-claude-unity --skill procedural-generation --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/procedural-generation

Context preview

The summary Claude sees to decide when to auto-load this skill.

Procedural generation patterns — Perlin/Simplex noise, BSP dungeon generation, random walk, loot tables with weighted random, wave function collapse basics, seed-based reproducibility.

SKILL.md

procedural-generation.SKILL.md
name: procedural-generation
description: "Procedural generation patterns — Perlin/Simplex noise, BSP dungeon generation, random walk, loot tables with weighted random, wave function collapse basics, seed-based reproducibility."
globs: ["**/Procedural*.cs", "**/Generate*.cs", "**/Dungeon*.cs", "**/Noise*.cs", "**/Loot*.cs"]

Procedural Generation Patterns

Patterns for generating content at runtime: terrain with noise, dungeons with BSP, caves with random walk, loot with weighted tables, and tile layouts with wave function collapse. All patterns support seed-based reproducibility.

Seed-Based Reproducibility

Every generation algorithm should accept a seed. Given the same seed, the output is identical. This enables shareable worlds, bug reproduction, and daily challenge modes.

**Critical rule:** Use `System.Random` (not `UnityEngine.Random`) for deterministic generation. `UnityEngine.Random` is a global singleton; any other code calling it between your generation steps will change the sequence.

public class SeededRandom
{
    private System.Random _rng;
    public int Seed { get; }

    public SeededRandom(int seed)
    {
        Seed = seed;
        _rng = new System.Random(seed);
    }

    public int Next(int min, int max) => _rng.Next(min, max);
    public float NextFloat() => (float)_rng.NextDouble();
    public float Range(float min, float max) => min + (max - min) * NextFloat();
    public bool Chance(float probability) => NextFloat() < probability;

    /// <summary>Shuffle a list in place using Fisher-Yates.</summary>
    public void Shuffle<T>(IList<T> list)
    {
        for (int i = list.Count - 1; i > 0; i--)
        {
            int j = _rng.Next(0, i + 1);
            (list[i], list[j]) = (list[j], list[i]);
        }
    }
}

For world generation, derive sub-seeds from the master seed so different systems (terrain, dungeons, loot) do not interfere:

int masterSeed = 12345;
var terrainRng = new SeededRandom(masterSeed);
var dungeonRng = new SeededRandom(masterSeed + 1);
var lootRng = new SeededRandom(masterSeed + 2);

---

Noise-Based Terrain Generation

Use Perlin noise to generate height maps for terrain, biome maps, moisture maps, and other continuous fields.

Basic Height Map

using UnityEngine;

public static class NoiseGenerator
{
    /// <summary>
    /// Generate a 2D noise map. Values range from 0 to 1.
    /// </summary>
    public static float[,] GenerateNoiseMap(
        int width, int height, int seed,
        float scale, int octaves, float persistence, float lacunarity,
        Vector2 offset)
    {
        var map = new float[width, height];

        // Use seed to generate random octave offsets
        var rng = new System.Random(seed);
        var octaveOffsets = new Vector2[octaves];
        for (int i = 0; i < octaves; i++)
        {
            float ox = rng.Next(-100000, 100000) + offset.x;
            float oy = rng.Next(-100000, 100000) + offset.y;
            octaveOffsets[i] = new Vector2(ox, oy);
        }

        if (scale <= 0f) scale = 0.001f;

        float maxNoise = float.MinValue;
        float minNoise = float.MaxValue;

        float halfW = width / 2f;
        float halfH = height / 2f;

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                float amplitude = 1f;
                float frequency = 1f;
                float noiseHeight = 0f;

                for (int o = 0; o < octaves; o++)
                {
                    float sampleX = (x - halfW + octaveOffsets[o].x) / scale * frequency;
                    float sampleY = (y - halfH + octaveOffsets[o].y) / scale * frequency;

                    // Mathf.PerlinNoise returns 0-1; remap to -1 to 1
                    float perlin = Mathf.PerlinNoise(sampleX, sampleY) * 2f - 1f;
                    noiseHeight += perlin * amplitude;

                    amplitude *= persistence;  // Each octave contributes less
                    frequency *= lacunarity;    // Each octave has finer detail
                }

                map[x, y] = noiseHeight;

                if (noiseHeight > maxNoise) maxNoise = noiseHeight;
                if (noiseHeight < minNoise) minNoise = noiseHeight;
            }
        }

        // Normalize to 0-1
        for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
                map[x, y] = Mathf.InverseLerp(minNoise, maxNoise, map[x, y]);

        return map;
    }
}

**Parameter guide:** | Parameter | Effect | Typical Value | |-------------|--------------------------------|---------------| | scale | Zoom level (higher = smoother) | 20-100 | | octaves | Layers of detail | 4-6 | | persistence | Amplitude decay per octave | 0.4-0.6 | | lacunarity | Frequency increase per octave | 1.8-2.2 |

Applying Noise to a Tilemap

using UnityEngine;
using UnityEngine.Tilemaps;

public class TerrainGenerator : MonoBehaviour
{
    [SerializeField] private Tilemap tilemap;
    [SerializeField] private TileBase waterTile;
    [SerializeField] private TileBase sandTile;
    [SerializeField] private TileBase grassTile;
    [SerializeField] private TileBase stoneTile;
    [SerializeField] private TileBase snowTile;

    [Header("Generation Settings")]
    [SerializeField] private int width = 100;
    [SerializeField] private int height = 100;
    [SerializeField] private int seed = 42;
    [SerializeField] private float scale = 30f;
    [SerializeField] private int octaves = 4;
    [SerializeField] private float persistence = 0.5f;
    [SerializeField] private float lacunarity = 2f;

    [Header("Height Thresholds")]
    [SerializeField] private float waterLevel = 0.3f;
    [SerializeField] private float sandLevel = 0.4f;
    [SerializeField] private float grassLevel = 0.7f;
    [SerializeField] private float ston
Read more
Ships witheverything-claude-unity

The ultimate Claude Code toolkit for Unity game development. A production-ready, plug-and-play system that gives Claude Code deep Unity expertise — from writing performant C# to building scenes, profiling performance, and triggering iOS/Android builds — all

Get the whole plugin

Other skills on everything-claude-unity.