thedivergentai/godot-procedural-generation
Expert blueprint for procedural content generation (dungeons, terrain, loot, levels) using FastNoiseLite, random walks, BSP trees, Wave Function Collapse, and seeded randomization. Use when creating roguelikes, sandbox games, or dynamic content. Keywords procedural, generation, FastNoiseLite, Perlin noise, BSP, drunkard walk, Wave Function Collapse, seeding.
npx skills add https://github.com/thedivergentai/GD-Agentic-Skills --skill godot-procedural-generation
Seeded algorithms, noise functions, and constraint propagation define replayable content generation. Do not paste inline algorithm tutorials — load the MANDATORY scripts below.
WorkerThreadPool or a background Thread to keep the UI responsive.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].randi() for reproducible seeds — Always store and reuse a specific seed within your random number generator (RandomNumberGenerator.new()) to ensure consistent world generation.max_iterations safety break.add_child().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.Every generator starts here — seed isolation, async data, main-thread commit:
RandomNumberGenerator per level/chunk; persist seed + state for shareable runs.WorkerThreadPool.add_task → compute data off-thread → call_deferred("_finalize_chunk") for SceneTree/node work.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.
| 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.
RandomNumberGenerator with push/pop state historycall_deferred chunk finalize patternrandi())max_iterationsFor voxel-like or smooth organic terrain, use ArrayMesh to generate geometry from code.
add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) to create the mesh.create_trimesh_collision() only for the current chunk to keep physics updates fast.Don't generate your dungeon geometry first. Build a logical graph using AStar2D.
Drunkard walk, noise biomes, BSP, loot tables, WFC loops — references/algorithm-recipes.md.
> 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.
get_image()/get_noise_2d() for heightmaps and biome masks.RandomNumberGenerator seeds beat global randi() for shareable runs.seed/state APIs for deterministic sequences and undoable RNG history.add_task + call_deferred finalize pattern for async chunk generation.call_deferred, and WorkerThreadPool task patterns used across every generator script.set_pattern / terrain connect batching so large CA/WFC grids do not call set_cell per tile.Take thedivergentai/godot-procedural-generation from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.