ue-procedural-generation
Use this skill when working with procedural generation in Unreal Engine: PCG framework, ProceduralMesh, instanced mesh, HISM, spline, runtime mesh, noise, terrain generation, or dungeon generation. See references/pcg-node-reference.md for PCG node types and references/procedural-mesh-patterns.md for
By quodsoler · 829 installs
npx skills add quodsoler/unreal-engine-skills --skill ue-procedural-generation
Source repository · Upstream listing
ue procedural generation
You are an expert in Unreal Engine's procedural generation systems, including the PCG framework, ProceduralMeshComponent, instanced static meshes, noise functions, and spline based generation.
Context Check
Before advising, read .agents/ue project context.md to determine:
Whether the PCG plugin is enabled (plugins list)
Target generation type: world layout, terrain, dungeon, vegetation, runtime mesh
Performance constraints (mobile, console, Nanite enabled)
Multiplayer requirements (server authority vs. deterministic seeding)
Information Gathering
Ask for clarification on:
1. Generation type : world population (PCG), runtime mesh (ProceduralMeshComponent), instanced geometry (ISM/HISM), or spline driven?
2. Timing : editor time baked result or runtime dynamic generation?
3. Instance count : hundreds (ISM) or tens of thousands (HISM)?
4. Collision : does generated geometry need physics collision?
5. Determinism : same seed must produce same result across sessions or network clients?
1. PCG Framework (UE 5.2+)
Node based rule driven world generation. Operates on point clouds with transform, density, color, seed, and metadata attributes.
Plugin Setup
Core Classes
Class Header Purpose
UPCGComponent PCGComponent.h Actor component driving generation
UPCGGraph PCGGraph.h Asset: nodes + edges
UPCGGraphInstance PCGGraph.h Graph instance with parameter overrides
UPCGPointData Data/PCGPointData.h Point cloud between nodes
UPCGSettings PCGSettings.h Node settings base class
UPCGBlueprintBaseElement Elements/Blueprint/PCGBlueprintBaseElement.h Custom Blueprint node base
UPCGComponent Key API (from PCGComponent.h )
Generation triggers ( EPCGComponentGenerationTrigger ):
GenerateOnLoad — one shot on BeginPlay
GenerateOnDemand — explicit Generate() call only
GenerateAtRuntime — budget scheduled by UPCGSubsystem
UPCGGraph Node API (from PCGGraph.h )
Custom Blueprint PCG Node
Derive from UPCGBlueprintBaseElement :
Key UPCGBlueprintBaseElement properties:
bIsCacheable = false — when node spawns actors or components
bRequiresGameThread = true — for actor spawn, component add
CustomInputPins / CustomOutputPins — extra typed pins
PCG Determinism
PCG graphs are deterministic by default — the same seed produces identical output. Each node receives a seeded random stream via GetRandomStreamWithContext() . To vary output across instances, set the PCG component's Seed property. For multiplayer, ensure all clients use the same seed (replicate via GameState or pass as spawn parameter).
PCG Data Types
Type Contains Use for
FPCGPoint / Point Data Position, rotation, scale, density, color Scatter placement, foliage, instance positioning
UPCGSplineData Spline points + tangents Roads, rivers, paths, boundary definitions
UPCGLandscapeData Height + layer weight sampling Terrain aware placement, biome queries
UPCGVolumeData 3D bounds Volume based filtering and generation
Point data is the most common — most PCG nodes consume and produce point collections. Also available: UPCGTextureData , UPCGPrimitiveData , UPCGDynamicMeshData .
See references/pcg node reference.md for all node types, settings fields, and pin labels.
2. ProceduralMeshComponent
Core API
Terrain Grid Example
Performance Notes
One draw call per CreateMeshSection . Keep vertex count < 65K per section.
UpdateMeshSection updates vertex positions and collision (if enabled) but cannot change topology — call CreateMeshSection for new triangles.
ProceduralMesh does not support Nanite.
Compute vertex data on background thread; call CreateMeshSection on game thread only.
Async Mesh Generation
Generate vertices on a background thread, then apply on the game thread:
Collision on Procedural Meshes
Set UProceduralMeshComponent::bUseComplexAsSimpleCollision = true to use the rendered triangles directly for collision. This is accurate but expensive — only use for static geometry. For dynamic or high poly meshes, generate simplified convex hulls instead.
3. Instanced Static Meshes (ISM / HISM)
Feature ISM ( InstancedStaticMeshComponent.h ) HISM ( HierarchicalInstancedStaticMeshComponent.h )
Best for < 1,000 dynamic instances 1,000 mostly static
Culling Distance only Hierarchical BVH + distance
LOD GPU selection Built in transitions
Remove cost O(n) async BVH rebuild
Key ISM API (from InstancedStaticMeshComponent.h )
Culling properties: InstanceStartCullDistance , InstanceEndCullDistance , InstanceLODDistanceScale , bUseGpuLodSelection .
Vegetation Scatter (HISM + Terrain Trace)
Foliage System
The editor's Foliage paint mode uses AInstancedFoliageActor which internally wraps UHierarchicalInstancedStaticMeshComponent . For procedural foliage at scale, use UProceduralFoliageComponent with UProceduralFoliageSpawner — it distributes foliage via simulation (species competition, shade tolerance) rather than manual painting.
Per instance collision : Enable bUseDefaultCollision on the ISM component. Each instance inherits the static mesh's collision. For custom per instance collision shapes, use separate actors — ISM does not support unique collision per instance.
Platform limits : HISM GPU buffer caps vary by platform (~1M on desktop, ~100K on mobile). Monitor with stat Foliage . Split large populations across multiple HISM components.
4. Noise and Math
Height/density maps : Sample UTexture2D pixel data via FTexturePlatformData to drive terrain height or placement density. Lock with BulkData.Lock(LOCK READ ONLY) , read, then unlock.
Poisson disc sampling (minimum separation scatter for natural placement) — full Bridson algorithm implementation in references/procedural mesh patterns.md .
5. Spline Components
USplineComponent API (from SplineComponent.h )
Point types: Linear , Curve , Constant , CurveClamped , CurveCustomTangent .
FindInputKeyClosestToWorldLocation(WorldLocation) — returns the spline key nearest to a world position (useful for snapping actors to splines).
Runtime modification : Call AddSplinePoint() , RemoveSplinePoint() , or SetLocationAtSplinePoint() then UpdateSpline() to rebuild. Batch modifications before calling UpdateSpline() — each call recalculates the entire spline.
Spline Placement Example
USplineMeshComponent (Mesh Deformation)
6. Runtime Mesh Generation Patterns
See references/procedural mesh patterns.md for full implementations:
Marching Cubes — isosurface from 3D density scalar field
Dungeon BSP — BSP partition into rooms, L corridor carving, tile to mesh
L System — string rewriting + turtle interpreter to HISM branches
Wave Function Collapse — constraint propagation tile grid layout
Async mesh generation — background thread vertex computation, game thread CreateMeshSection
Spline road extrusion — cross section profile swept along USplineComponent
Common Mistakes and Anti Patterns
PCG
Calling GenerateLocal() in Tick — generation is not free; use GenerateOnDemand and regenerate only on data change.
Using GenerateLocal() in multiplayer — it is NOT replicated; use Generate(bForce) (NetMulticast).
Heavy custom nodes with bIsCacheable = true — only cache if output depends solely on inputs + seed.
Graphs with bIsEditorOnly = true fail to cook into packaged builds.
ProceduralMeshComponent
Passing bCreateCollision=false to CreateMeshSection — characters fall through the mesh.
Calling UpdateMeshSection expecting topology to change — vertex count must match; use CreateMeshSection for new triangles.
Using ProceduralMesh for Nanite scale terrain — not supported; use Landscape or PCG + ISM.
Wrong triangle winding (CW instead of CCW) — polygons are invisible due to back face culling.
ISM / HISM
Using ISM above ~500 instances — switch to HISM for BVH culling.
Setting bMarkRenderStateDirty=true on every UpdateInstanceTransform in a loop — only set true on the last call.
Skipping PreAllocateInstancesMemory before bulk add — repeated realloc degrades performance.
Splines
Calling AddSplinePoint(bUpdateSpline=true) in a loop — rebuilds reparameterization table every call; use false and call UpdateSpline() once.
Using spline input key (not distance) for even spacing — key is NOT proportional to arc length.
Multiplayer
Procedural content must be deterministic (same seed) or server authoritative.
GenerateLocal() does not replicate; Generate(bool) is NetMulticast, Reliable .
Related Skills
ue actor component architecture — component lifecycle, registration, replication
ue physics collision — collision profiles, complex vs. simple on generated geometry
ue cpp foundations — NewObject , TSubclassOf , TArray , memory management
Reference Files
references/pcg node reference.md — all PCG node types, pin labels, settings fields, determinism checklist
references/procedural mesh patterns.md — quad grid, marching cubes, dungeon BSP, L system, WFC, spline road