SuperAPI AI Directory

godot-procedural-generation

Coding & development

View repository

Updated 10-15 18:28

About this skill

Procedural Generation

Seeded algorithms, noise functions, and constraint propagation define replayable content generation. Do not paste inline algorithm tutorials — load the MANDATORY scripts below.

NEVER Do in Procedural Generation

  • NEVER generate chunks on the Main Thread — Proc-gen is CPU intensive and causes frame-rate spikes. Use WorkerThreadPool or a background Thread to keep the UI responsive.
  • NEVER query FastNoiseLite every frame — Sampling noise per frame (especially in _process) is a massive waste. Generate your map into an Image or Array once and sample from memory [NoiseSampling].
  • NEVER use randi() for reproducible seeds — Always store and reuse a specific seed within your random number generator (RandomNumberGenerator.new()) to ensure consistent world generation.
  • NEVER use pure randomness for object placement — Pure random (white noise) causes clumping and overlapping. Use Poisson Disk Sampling or Jittered Grids for natural-looking distributions.
  • NEVER forget to bound your loops — Procedural loops (like WFC or Cellular Automata) can easily enter infinite states if constraints are impossible. Always include a max_iterations safety break.
  • NEVER instantiate nodes directly from proc-gen threads — You cannot touch the SceneTree from a worker thread. Generate the data in the thread, then notify the Main Thread to handle add_child().
  • NEVER use complex WFC for simple layouts — Wave Function Collapse is powerful but overkill for simple paths. Use Drunkard's Walk or BSP for lightweight structured layouts.
  • NEVER rely on TileMap.set_cell() for large-scale updates — Updating 10,000 cells individually is slow. Prepare a TileMapPattern and use set_pattern() or set_cells_terrain_connect() for batch updates.
  • NEVER forget to bake Navigation at the end — Procedurally generated worlds need their navmeshes rebaked at runtime or the AI will walk into walls.
  • NEVER ignore data serialization — If you generate a world, you must be able to save the seed and any player modifications. Don't try to save the entire raw chunk state if avoidable.

Golden Path (MANDATORY)

Every generator starts here — seed isolation, async data, main-thread commit:

  1. Seed & RNG — MANDATORY proc_gen_seed_history.gd: one RandomNumberGenerator per level/chunk; persist seed + state for shareable runs.
  2. Async chunks — MANDATORY multi_threaded_chunk_gen.gd: WorkerThreadPool.add_task → compute data off-thread → call_deferred("_finalize_chunk") for SceneTree/node work.
  3. Validate → bake nav — after tiles/meshes land on the main thread, rebake NavigationRegion (see godot-navigation-pathfinding).
var rng := RandomNumberGenerator.new()

func begin_generation(run_seed: int) -> void:
    rng.seed = run_seed
    WorkerThreadPool.add_task(_build_data.bind(run_seed))

func _build_data(seed: int) -> Dictionary:
    var local_rng := RandomNumberGenerator.new()
    local_rng.seed = seed
    var noise := FastNoiseLite.new()
    noise.seed = seed
    return {"heights": noise.get_image(64, 64)}

func _ready() -> void:
    # Worker returns here — safe for nodes
    pass

func _finalize_from_worker(data: Dictionary) -> void:
    # add_child / set_pattern / create_trimesh_collision — main thread only
    pass

Do NOT Load the full scripts/ folder. Open only the script that matches your algorithm row below.

Algorithm Decision Tree

Layout / content need Algorithm Script (MANDATORY when chosen)
Winding tunnels, rivers, simple paths Drunkard's Walk MANDATORY drunknard_walk_path.gd
Structured rooms + hallways BSP MANDATORY bsp_tree_rooms.gd
Organic caves / smooth terrain Cellular Automata (4/5) MANDATORY cellular_automata_dungeon.gd
Heightmaps, biomes, infinite terrain FastNoiseLite → Image MANDATORY fast_noise_noise2d_master.gd
Trees, rocks, spawns (no clumping) Poisson Disk MANDATORY poisson_disk_sampling_2d.gd
Tile adjacency / city blocks Wave Function Collapse MANDATORY wave_function_collapse_lite.gd (lite) or wfc_level_generator.gd (full rules)
Room graph before geometry AStar graph layout MANDATORY proc_gen_graph_layout.gd
3D voxel / smooth terrain mesh Marching Cubes base MANDATORY proc_gen_marching_cubes_base.gd
Infinite chunked 3D terrain ArrayMesh + LOD chunks MANDATORY mesh_gen_infinite_terrain.gd
Plants / branching structures L-System MANDATORY l_system_tree_gen.gd
Contour / metaball maps (2D) Marching Squares MANDATORY marching_squares_metaballs.gd

Routing hints: Simple path → drunkard; rectangular rooms → BSP; constraint tiles → WFC lite; open-world chunks → noise + multi_threaded_chunk_gen.gd. For roguelike run orchestration, hand off to godot-genre-roguelike.

Available Scripts

Core (always start here)

  • proc_gen_seed_history.gd — MANDATORY seeded RandomNumberGenerator with push/pop state history
  • multi_threaded_chunk_gen.gd — MANDATORY WorkerThreadPool → call_deferred chunk finalize pattern

2D layout & placement

  • drunknard_walk_path.gd — MANDATORY for tunnels/paths (pass local RNG, never global randi())
  • bsp_tree_rooms.gd — MANDATORY for structured floor plans
  • cellular_automata_dungeon.gd — MANDATORY for organic caves
  • poisson_disk_sampling_2d.gd — MANDATORY for blue-noise prop/enemy placement
  • wave_function_collapse_lite.gd — MANDATORY lite WFC with entropy + max_iterations
  • wfc_level_generator.gd — full WFC with tile-library adjacency rules
  • proc_gen_graph_layout.gd — graph-before-geometry via AStar2D/3D

Noise & 3D

  • fast_noise_noise2d_master.gd — MANDATORY FastNoiseLite → Image heightmaps
  • mesh_gen_infinite_terrain.gd — runtime ArrayMesh terrain with LOD potential
  • proc_gen_marching_cubes_base.gd — 3D mesh from voxel data
  • marching_squares_metaballs.gd — 2D contour extraction
  • l_system_tree_gen.gd — procedural plant/tree grammar

Expert Procedural Patterns

1. 3D Terrain via ArrayMesh (Marching Cubes)

For voxel-like or smooth organic terrain, use ArrayMesh to generate geometry from code.

  • Logic: Calculate vertices, normals, and indices in a worker thread.
  • Commit: Use add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) to create the mesh.
  • Performance: Use create_trimesh_collision() only for the current chunk to keep physics updates fast.

2. Graph-Based Dungeon Logic

Don't generate your dungeon geometry first. Build a logical graph using AStar2D.

  • Vertices: Represent "Rooms".
  • Edges: Represent "Hallways" or "Doors".
  • Benefit: You can easily run validation (is every room reachable?) before spawning a single mesh.

Deep dive (load on demand)

Drunkard walk, noise biomes, BSP, loot tables, WFC loops — references/algorithm-recipes.md.

Reference

Progressive disclosure: open Official Documentation links only when researching a specific API; load Related Skills when routing to a peer domain — do not preload the whole lattice.

Official Documentation

  • FastNoiseLite — seed, frequency, noise type, and get_image()/get_noise_2d() for heightmaps and biome masks.
  • Random number generation — why per-generator RandomNumberGenerator seeds beat global randi() for shareable runs.
  • RandomNumberGenerator — seed/state APIs for deterministic sequences and undoable RNG history.
  • Using multiple threads — offload chunk/WFC work without freezing the main loop.
  • Thread-safe APIs — which Godot APIs workers may call; SceneTree/node creation stays on the main thread.
  • WorkerThreadPool — add_task + call_deferred finalize pattern for async chunk generation.
  • Using ArrayMesh — commit vertex/normal/index arrays for marching-cubes and infinite terrain meshes.
  • Using SurfaceTool — incremental vertex building and normal generation for runtime planes.
  • Using TileMaps — TileMapLayer/pattern batch writes after BSP, CA, WFC, or drunkard-walk grids.
  • Using GridMaps — modular 3D cell placement backend for dungeon/terrain generators.
  • Navigation introduction (3D) — rebake NavigationRegion meshes after procedural geometry lands.
  • AStar2D — room/hallway graph validation before spawning tiles or meshes.

Related Skills

Prerequisites

  • godot-project-foundations — scenes, resources, and import basics before generators emit TileMaps, GridMaps, or ArrayMeshes.
  • godot-gdscript-mastery — typed arrays, call_deferred, and WorkerThreadPool task patterns used across every generator script.
  • godot-resource-data-patterns — Resource-backed tile libraries, adjacency rules, and seed configs instead of hard-coded magic tables.

Complements

Downstream / consumers

  • godot-genre-roguelike — run-based dungeon crawlers that consume BSP/WFC/drunkard generators and seeded RNG.
  • godot-genre-sandbox — voxel/chunk worlds and cellular-automata sandboxes built on infinite terrain and CA scripts.
  • godot-genre-open-world — chunk streaming and floating-origin layers that wrap multi-threaded chunk gen.

Master

  • godot-master — library router and mirrored module entry for cross-skill discovery.