godot-procedural-generation
Expert blueprint for procedural content generation (dungeons, terrain, loot, levels) using FastNoiseLite, random walks, BSP trees, Wave Function Col…
它会碰到什么
这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。
技能内容
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
WorkerThreadPoolor a backgroundThreadto keep the UI responsive. - NEVER query
FastNoiseLiteevery frame — Sampling noise per frame (especially in_process) is a massive waste. Generate your map into anImageorArrayonce and sample from memory [NoiseSampling]. - NEVER use
randi()for reproducible seeds — Always store and reuse a specificseedwithin 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_iterationssafety 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 aTileMapPatternand useset_pattern()orset_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:
- Seed & RNG — MANDATORY [proc_gen_seed_history.gd](scripts/proc_gen_seed_history.gd): one
RandomNumberGeneratorper level/chunk; persistseed+statefor shareable runs. - Async chunks — MANDATORY [multi_threaded_chunk_gen.gd](scripts/multi_threaded_chunk_gen.gd):
WorkerThreadPool.add_task→ compute data off-thread →call_deferred("_finalize_chunk")for SceneTree/node work. - 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](scripts/drunknard_walk_path.gd) |
| Structured rooms + hallways | BSP | MANDATORY [bsp_tree_rooms.gd](scripts/bsp_tree_rooms.gd) |
| Organic caves / smooth terrain | Cellular Automata (4/5) | MANDATORY [cellular_automata_dungeon.gd](scripts/cellular_automata_dungeon.gd) |
| Heightmaps, biomes, infinite terrain | FastNoiseLite → Image | MANDATORY [fast_noise_noise2d_master.gd](scripts/fast_noise_noise2d_master.gd) |
| Trees, rocks, spawns (no clumping) | Poisson Disk | MANDATORY [poisson_disk_sampling_2d.gd](scripts/poisson_disk_sampling_2d.gd) |
| Tile adjacency / city blocks | Wave Function Collapse | MANDATORY [wave_function_collapse_lite.gd](scripts/wave_function_collapse_lite.gd) (lite) or [wfc_level_generator.gd](scripts/wfc_level_generator.gd) (full rules) |
| Room graph before geometry | AStar graph layout | MANDATORY [proc_gen_graph_layout.gd](scripts/proc_gen_graph_layout.gd) |
| 3D voxel / smooth terrain mesh | Marching Cubes base | MANDATORY [proc_gen_marching_cubes_base.gd](scripts/proc_gen_marching_cubes_base.gd) |
| Infinite chunked 3D terrain | ArrayMesh + LOD chunks | MANDATORY [mesh_gen_infinite_terrain.gd](scripts/mesh_gen_infinite_terrain.gd) |
| Plants / branching structures | L-System | MANDATORY [l_system_tree_gen.gd](scripts/l_system_tree_gen.gd) |
| Contour / metaball maps (2D) | Marching Squares | MANDATORY [marching_squares_metaballs.gd](scripts/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](scripts/proc_gen_seed_history.gd) — MANDATORY seeded
RandomNumberGeneratorwith push/pop state history - [multi_threaded_chunk_gen.gd](scripts/multi_threaded_chunk_gen.gd) — MANDATORY WorkerThreadPool →
call_deferredchunk finalize pattern
2D layout & placement
- [drunknard_walk_path.gd](scripts/drunknard_walk_path.gd) — MANDATORY for tunnels/paths (pass local RNG, never global
randi()) - [bsp_tree_rooms.gd](scripts/bsp_tree_rooms.gd) — MANDATORY for structured floor plans
- [cellular_automata_dungeon.gd](scripts/cellular_automata_dungeon.gd) — MANDATORY for organic caves
- [poisson_disk_sampling_2d.gd](scripts/poisson_disk_sampling_2d.gd) — MANDATORY for blue-noise prop/enemy placement
- [wave_function_collapse_lite.gd](scripts/wave_function_collapse_lite.gd) — MANDATORY lite WFC with entropy +
max_iterations - [wfc_level_generator.gd](scripts/wfc_level_generator.gd) — full WFC with tile-library adjacency rules
- [proc_gen_graph_layout.gd](scripts/proc_gen_graph_layout.gd) — graph-before-geometry via AStar2D/3D
Noise & 3D
- [fast_noise_noise2d_master.gd](scripts/fast_noise_noise2d_master.gd) — MANDATORY FastNoiseLite → Image heightmaps
- [mesh_gen_infinite_terrain.gd](scripts/mesh_gen_infinite_terrain.gd) — runtime ArrayMesh terrain with LOD potential
- [proc_gen_marching_cubes_base.gd](scripts/proc_gen_marching_cubes_base.gd) — 3D mesh from voxel data
- [marching_squares_metaballs.gd](scripts/marching_squares_metaballs.gd) — 2D contour extraction
- [l_system_tree_gen.gd](scripts/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](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
RandomNumberGeneratorseeds beat globalrandi()for shareable runs. - RandomNumberGenerator —
seed/stateAPIs 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_deferredfinalize 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
- godot-tilemap-mastery —
set_pattern/ terrain connect batching so large CA/WFC grids do not callset_cellper tile. - godot-3d-world-building — GridMap/MeshLibrary/CSG placement backends that consume room graphs and heightmaps.
- godot-navigation-pathfinding — runtime navmesh bake after rooms, caves, or terrain chunks finish.
- godot-performance-optimization — budgets for mesh commits, collision trimeshes, and MultiMesh prop scattering after generation.
- godot-save-load-systems — persist seed + player deltas instead of serializing every generated chunk.
- godot-scene-management — threaded load/unload of chunk scenes that wrap generated data.
- godot-monte-carlo-balancer — sample spawn density, loot tables, and room difficulty against seed distributions before shipping.
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.
想直接用这个技能?
本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。
它属于哪个仓库
skills/godot-procedural-generation/SKILL.md