Epic's Procedural Content Generation (PCG) framework has gone from "interesting experiment" in UE5.2 to "production-grade system with real quirks" in UE5.7. If you've tried PCG before and bounced off it — the graph editor felt clunky, the debugging was opaque, the World Partition interaction was confusing — UE5.7 is worth another look. The framework has settled into a clearer mental model, the tooling has improved, and enough studios have shipped with it that the production patterns are now knowable rather than being reverse-engineered from each project individually.
This tutorial covers those production patterns. We'll start with how to think about PCG graphs (as data pipelines, not as scatter tools), work through composition patterns that scale, walk through debugging approaches that actually work, cover the World Partition and data partition interplay, discuss when runtime PCG makes sense vs. bake-time PCG, and close with concrete workflows for the two most common use cases: dressing a large open world and dressing interior spaces.
We'll also compare PCG against the Procedural Placement Tool where that comparison is relevant, because these tools cover overlapping but distinct use cases and the right choice depends on your specific workflow.
The Mental Model: PCG as a Data Pipeline
The single most important thing to internalize about PCG is that a PCG graph is a data pipeline, not a scatter tool. The graph processes points — lightweight data structures with position, rotation, scale, and arbitrary named attributes — through a series of operations, and the output of the pipeline is a set of points that are then spawned as meshes, actors, or splines.
This is different from a traditional scatter tool (including older Unreal scatter workflows and most plugin-based scatter systems) that think in terms of "place these assets in this area." PCG thinks in terms of "here's a bunch of data, transform it through these operations, and the result is the scene."
The consequence of this mental model: PCG graphs benefit enormously from thinking like a data engineer rather than like a level designer. Good PCG graphs are composable, debuggable, parameterized, and testable. Bad PCG graphs are one-off spaghetti that only the original author understands.
Points, Attributes, and Why They Matter
Every PCG graph operates on a collection of points. A point has a fixed set of core properties (transform, bounds, density, seed, steepness) and an arbitrary set of named custom attributes. You can attach attributes to points at any stage in the graph and read them downstream.
This is the mechanism by which PCG graphs express complex behaviors. A "spawn rocks on steep slopes" graph doesn't hardcode that logic — it computes a "slope" attribute for each point, then filters by that attribute downstream. A "vary rock size based on biome" graph computes a "biome" attribute, then branches on it.
The pattern we recommend: treat attributes as your primary abstraction. Each graph should compute attributes that describe the points (what biome, what slope, what distance from a path, what density) early in the pipeline, then use those attributes to drive placement decisions downstream. This separation — attribute computation vs. placement logic — makes graphs substantially easier to debug and modify.
Graph Composition: The Pattern That Scales
The single biggest difference between PCG graphs that scale and ones that don't is composition. A 40-node graph that does one thing is manageable. A 400-node graph that does ten things is not.
Subgraphs Are Your Primary Tool
PCG subgraphs let you encapsulate a chunk of graph logic behind an interface and reuse it. In UE5.7, subgraphs support parameters (exposed inputs that let the caller customize the subgraph's behavior), which means you can build a library of reusable graph pieces.
Our baseline approach: every PCG graph at any real scale should be decomposed into subgraphs. A good top-level graph is maybe 20-30 nodes and consists primarily of subgraph calls and the connective tissue between them. The actual work happens inside subgraphs.
Canonical subgraphs we build for most projects:
Biome_Sample— samples an input attribute (biome map, environment mask) at each point and attaches a biome ID attribute.Slope_Compute— computes slope angle from underlying landscape/mesh, attaches as attribute.Density_Mask— applies a density texture or curve to filter points.Distance_From— computes distance to a set of reference splines or actors, attaches as attribute.Jitter_Position— applies position jitter within specified bounds.Orient_To_Surface— orients points to the surface normal of the underlying landscape.Spawn_From_Library— takes a library of mesh variants and an attribute that selects among them, spawns the selected mesh.
These subgraphs are project-agnostic and get copied forward between projects. The top-level graphs for "forest biome," "desert biome," "village interior" are then composition of these shared subgraphs with biome-specific parameters and logic.
Subgraph Versioning
A pitfall we hit early: when you update a shared subgraph, every graph that uses it is potentially affected. PCG graphs don't give you the kind of compile-time error surface that code does — a subgraph change can silently break a dependent graph.
Our mitigation: version your shared subgraphs explicitly. Name them Slope_Compute_v1, Slope_Compute_v2. When you make a breaking change, create a new version and migrate dependent graphs deliberately. This is awkward but prevents silent breakage.
Parameter Conventions
Subgraph parameters are how you make subgraphs reusable. A few conventions we've found useful:
- Expose everything that a caller might reasonably want to customize. Err on the side of too many parameters rather than too few. Unused parameters are cheap; hardcoded values that need to be changed force a subgraph edit.
- Use sensible defaults. Every parameter should have a default that produces reasonable output. A subgraph that requires all parameters to be specified at the call site is painful to use.
- Document parameters in the node description. PCG supports descriptions on nodes. Use them. Future-you will thank past-you.
- Group related parameters. PCG's parameter UI groups parameters by prefix when you use consistent naming (e.g.,
Slope_Min,Slope_Maxgroup together).
Debugging PCG Graphs
Debugging PCG graphs was the roughest part of the framework in earlier versions. UE5.7 has improved this substantially but it still requires deliberate technique.
The Visualize Nodes
PCG has a family of "Visualize" nodes that let you see point data at any stage in the pipeline. Use them liberally during development. Stick a Visualize node after every meaningful transformation during debugging, then clean them up when the graph is working.
The most useful visualize configurations:
- Point count. How many points are flowing through this stage?
- Attribute distribution. What values does the
biomeattribute actually have at this stage? - Spatial distribution. Where in space are the points?
- Colored by attribute. Visualize points colored by a specific attribute. Invaluable for sanity-checking things like "is my biome mask being sampled correctly?"
The Debug Node
The Debug node is distinct from Visualize — it dumps point data (positions, attributes) to the output log and optionally to a file. For graphs where you need to verify exact values rather than spatial distribution, Debug is more useful than Visualize.
A pattern we use: add a Debug node gated behind a graph parameter (bEnableDebug). Leave the Debug node wired up but disabled in production. Flip the parameter on when debugging, off when done. Beats commenting/uncommenting.
Deterministic Seeds
PCG graphs produce randomized output by default, and the randomization is per-graph-invocation by default. This is generally what you want, but it makes debugging miserable — the graph produces different output every time you re-run it.
For debugging, pin the seed. Every PCG node that uses randomness has a seed parameter. Pin it to a constant value while debugging. This makes the output deterministic and makes it possible to reason about "what changed between runs."
For production, use the default seed behavior (seed derived from world position), which produces consistent output for a given location but varied output across locations.
Node Performance Profiling
In UE5.7, the PCG graph editor has a built-in profiler that shows per-node execution time. Turn it on when your graphs get slow. The common performance culprits:
- Unnecessary "Transform Points" operations. Each one iterates the full point set. Combine adjacent operations where possible.
- Attribute computation that could be cached. If multiple downstream nodes read the same computed attribute, compute it once and branch.
- Oversized input sampling. Sampling a huge landscape or mesh at high density is slow. Sample at lower density and interpolate where possible.
- Actor-spawning nodes doing too much work per actor. If you're spawning 10,000 actors, each actor's BeginPlay cost compounds. Consider ISMC (Instanced Static Mesh Component) output instead.
The "Simplify Then Restore" Debugging Pattern
When a graph is producing wrong output and you don't know why, our go-to technique:
- Make a copy of the graph.
- Rip out everything downstream of where you suspect the problem is.
- Add a Visualize node right at the cut point.
- Observe what the point data actually looks like at that stage.
- If the data is correct, the problem is downstream. Restore the next segment and repeat.
- If the data is wrong, the problem is upstream. Cut further back and repeat.
This is tedious but it works. The alternative — staring at a 200-node graph and hoping the problem announces itself — doesn't work.
World Partition and Data Partition Interplay
PCG's interaction with World Partition is where a lot of studios get confused. The mental model that helps: PCG graphs are associated with partitioned volumes that map to World Partition cells. When a cell streams in, its PCG graphs evaluate. When the cell streams out, the generated content is unloaded.
Partitioned Grid Volumes
A PCG Volume can be either non-partitioned (generates once, exists as actors in the level) or partitioned (generates per-cell, streams with World Partition). For open-world content, partitioned is almost always what you want — non-partitioned PCG volumes in a large open world load the entire generated content at once, which defeats the purpose of World Partition.
The configuration: set the PCG Volume's Generation Grid Size to match your World Partition grid size (typically 12,800 units, but configurable per project). The PCG graph will be evaluated per-cell, and the spawned content will be associated with the cell's streaming level.
Data Layers
PCG integrates with World Partition data layers, which means you can associate generated content with specific data layers for visibility control. This is useful for "dress two versions of this area differently" scenarios — a "normal" data layer and a "destroyed" data layer, each with its own PCG graph, toggled at runtime.
Hierarchical Generation
For very large open worlds, the pattern that's emerged is hierarchical PCG:
- Top-level graph runs at a coarse grid (large cells, infrequent evaluation) and decides high-level biome placement. Outputs biome regions as spline or volume data.
- Mid-level graph runs at a medium grid and uses the top-level output to place major features (villages, landmarks, river sources).
- Low-level graph runs at the World Partition grid and dresses individual cells with fine-grained detail (grass, props, small rocks).
This hierarchy lets you reason about content at the appropriate scale — you don't want to decide "this cell is in a forest biome" inside the same graph that's placing individual trees. Decomposing the decisions by scale makes graphs smaller, faster to iterate, and easier to debug.
Streaming Cost
The downside of PCG + World Partition: graph evaluation happens when a cell streams in, which means streaming cost is higher than it would be with pre-placed content. For most projects this is acceptable, but for games with tight streaming budgets (fast movement, racing games, flight-heavy games), it's worth measuring.
Mitigations:
- Keep per-cell graph execution time under 50ms. Profile and optimize graphs that exceed this.
- Use baked PCG output for hot-path cells. PCG supports "baking" — running the graph ahead of time and storing the output as regular actors. Cells that stream in hot paths (near the player's spawn, near common travel routes) can be baked while cells further out remain generated on-demand.
- Use async generation. UE5.7 PCG supports async graph evaluation on a worker thread. Enable it for partitioned volumes unless your graph has to block for some reason.
Runtime vs. Bake-Time PCG
The single most impactful decision for a PCG workflow is whether to run the graph at bake time (cooking the generated content into the level) or at runtime (evaluating the graph when the cell streams in).
Bake-Time PCG
Bake-time PCG runs the graph during the editor cook process, freezes the output as regular level actors, and ships the generated content as part of the level data.
Advantages:
- Zero runtime cost — the content is just regular level actors
- Deterministic — same cook produces same output
- Content is fully in the editor after baking — you can hand-edit specific areas if needed
Disadvantages:
- Level file size is larger (the baked content takes disk space)
- Iteration is slower (you have to re-bake when the graph changes)
- Can't easily have content that varies at runtime (difficulty-scaled enemy placement, time-of-day-scaled lighting variants)
Runtime PCG
Runtime PCG evaluates the graph when a World Partition cell streams in, generating content on the fly.
Advantages:
- Level file size is smaller (graphs are cheaper than baked content)
- Iteration is faster (just edit the graph, no rebake)
- Can vary by runtime context (difficulty, player state, time of day, save game state)
Disadvantages:
- Runtime cost — graphs execute during streaming
- Non-determinism can surprise you if not managed
- Harder to hand-edit specific areas
Our Recommendation
For most indie and mid-size projects, use bake-time PCG by default, and runtime PCG only where you specifically need runtime variation.
The reasoning: bake-time PCG gives you most of the benefits of procedural content (fast iteration on the graph, scalable content volume, parameterized output) without the runtime cost surface. Runtime PCG is powerful but adds a category of performance concerns that has to be managed.
Specific scenarios where runtime PCG is the right call:
- Procedural dungeons or levels generated per-run (roguelikes, procedural story games).
- Content that varies by save state (e.g., different NPC populations based on quest progress, or different resource node distributions).
- Content that must vary by difficulty or player progression.
- Very large worlds where baking would produce unwieldy level files.
For everything else, bake.
Workflow: Dressing a 4km² Open World
Let's work through a concrete example. We have a 4km × 4km open world (16 km² total). We need to dress it with terrain vegetation, rocks, environmental props, and small details.
Step 1: Establish the Hierarchy
- Biome graph runs at a 4-cell grid (every 51,200 units) and assigns biome IDs (forest, desert, grassland, rocky, wetland). Outputs a biome attribute per cell.
- Feature graph runs at a 2-cell grid (every 25,600 units) and places major features — landmarks, ruins, named locations. Uses biome attribute to filter what's placeable.
- Dressing graph runs at the 1-cell World Partition grid (every 12,800 units) and does the fine-grained work — trees, rocks, grass, small props. Uses biome and feature attributes to decide what to place.
Step 2: Define the Asset Libraries
Each biome has a library of asset variants:
- Forest biome: 8 tree variants, 4 bush variants, 6 rock variants, 3 fallen-log variants, 5 mushroom cluster variants, grass types.
- Desert biome: 5 cactus variants, 4 rock variants, 3 dried-bush variants, dust/sand particle configurations.
- Grassland biome: 6 tall-grass variants, 4 flower variants, 3 small-rock variants, occasional-tree variants for visual interest.
- Rocky biome: 8 rock variants at different scales, sparse vegetation, occasional pine tree.
- Wetland biome: 5 reed/cattail variants, 4 tree variants (willows, swamp cypress), water-edge decorations.
Each asset library is a Data Asset that the relevant PCG graph reads. Adding a new asset variant means adding it to the Data Asset — no graph edits needed. This is the "data-driven" pattern that makes PCG workflows scale.
Step 3: Implement the Dressing Graph
The per-cell dressing graph is where the bulk of the work happens:
- Sample the landscape — generate points on the landscape mesh at configurable density.
- Read biome attribute — sample the biome map at each point (biome map is a texture that the biome graph populated).
- Compute slope and altitude — derive slope and altitude attributes from the landscape.
- Compute distance from features — compute distance to feature locations (from the feature graph output).
- Filter points by biome compatibility — each point is candidate for placement of biome-appropriate assets only.
- Select asset variant — based on biome, slope, altitude, distance from features, and random seed.
- Orient to surface — align each point to the landscape normal.
- Jitter position — slight random offset to break grid patterns.
- Spawn as Hierarchical ISM — instanced static meshes for performance.
This graph is maybe 40-50 nodes total, heavily factored into subgraphs. The subgraph decomposition is what keeps it readable.
Step 4: Bake, Test, Iterate
Bake the PCG content for representative cells. Drop a debug camera into the world and fly through. Observe. Iterate on graph parameters (density, selection weights, placement masks). Re-bake. Observe. Iterate.
Typical iteration cycle on a mature graph is 30-60 seconds for re-bake of a single cell, 2-5 minutes for a larger region.
Where Procedural Placement Tool Fits
The Procedural Placement Tool shines for curated procedural placement — scenarios where you want authored control over specific high-value placements rather than graph-driven bulk placement. In an open world like this, we'd typically use PCG for the bulk content (vegetation, rocks, ambient props) and Procedural Placement Tool for hand-curated hero locations (the specific vista that frames a mountain, the carefully-arranged landmark ruins, the deliberately-placed encounter setups).
The tools complement each other rather than competing. PCG covers "there should be trees in this forest"; Procedural Placement Tool covers "this specific grove of ancient oaks should frame this specific player-reward view."
Workflow: Dressing Interior Spaces
PCG for interiors is a different beast from open-world PCG. Interiors have structured shapes (walls, floors, ceilings), semantic regions (living room, kitchen, corridor), and strong spatial constraints that pure point-scattering doesn't handle well.
The Spline-Driven Approach
Our approach for interiors: use splines to define regions, use PCG to populate them.
- Floor splines define floor regions (with material, style tags).
- Wall splines define walls (with tags for wall type, height, material).
- Zone splines define semantic regions (kitchen, bedroom, bathroom) that influence what dressing is placed.
- Fixture markers (Actors placed by hand) mark specific fixture locations — appliances, fireplaces, large furniture.
The PCG graph reads these splines and actors and produces dressing appropriate to each region.
Interior-Specific Patterns
- Surface-targeted placement. Many interior props go on surfaces — tables, shelves, counters. PCG can sample surface points from marked mesh components and place props on them. Use mesh tags to identify "shelf," "counter," "table" surfaces.
- Clearance constraints. Indoors, you need clearance around objects (can't place a chair touching a wall, can't place a rug under a table). PCG supports distance-based filtering — compute distance to the nearest wall/fixture, filter points that are too close.
- Style coherence. A bedroom's dressing should be coherent — not random mixing of modern and vintage. Use a "style" attribute on the zone spline that constrains asset selection within each room.
- Clutter variation. Real rooms have clutter, but also negative space. A common mistake is uniform high-density placement. Use density curves (high density near focal points, lower density in negative space) to create readable interiors.
When to Author Interiors By Hand
Honestly: for hero interiors (the player's home base, story-critical locations, tutorial spaces), hand-author. PCG is better at bulk content than at the specific visual storytelling that hero spaces need. Use PCG for the dozens of secondary rooms and hand-author the half-dozen that matter most.
Common Mistakes to Avoid
A few patterns we've seen repeatedly:
Building monolithic graphs. A single 300-node graph is unmaintainable. Decompose into subgraphs ruthlessly.
Not using Data Assets for asset libraries. Hardcoding mesh references inside PCG graphs makes them inflexible. Read assets from Data Assets, which can be edited without opening the graph.
Runtime PCG where bake-time would work. Adding runtime cost for no real benefit. Default to bake-time.
Ignoring the attribute abstraction. Trying to express complex logic directly in node connections rather than computing attributes and filtering by them. Attributes make graphs readable.
Not seeding deterministically during authoring. Makes debugging miserable. Pin seeds while iterating, default them for production.
Overlooking Hierarchical ISM. Spawning as regular static mesh actors instead of Hierarchical ISM costs runtime performance at scale. Use ISMC where possible.
Treating PCG as a replacement for everything. It's not. Hand-authored content, spline-driven procedural tools, and scatter plugins all have places. PCG is best at bulk procedural content with clear rules.
The Path Forward
PCG in UE5.7 is production-ready for the workflows we've described. Studios shipping with it get meaningful leverage — substantially larger content volumes per content-creator-hour than hand-placed workflows, better consistency across regions, and the ability to iterate on art direction by editing graphs rather than hand-re-placing hundreds of assets.
The barriers to adoption are real but surmountable: learning curve for the graph paradigm, time investment to build up a subgraph library, care required to manage World Partition interactions. For indie teams, the barrier is probably higher than the benefit for small projects (a tight 4-hour game doesn't need scalable procedural tooling). For mid-sized and larger projects, the ROI is clear.
Combined with complementary tools — the Procedural Placement Tool for curated placement, the Unreal MCP Server for editor automation and batch operations — PCG becomes part of a broader procedural content toolchain rather than a standalone system. That's where the workflow actually pays off.
We'll publish follow-ups on specific PCG workflows (biome-driven open-world dressing in detail, dungeon generation, crowd-placement patterns) over the next several months. For now: decompose your graphs, use attributes as your primary abstraction, visualize aggressively, and default to bake-time unless you genuinely need runtime variation. That gets you most of the way there.