pcg
DevelopmentCreate, inspect, and edit PCG Graph assets — add nodes, configure settings, connect pins, and wire procedural generation graphs (native PCG Python API). Use when the user asks to build a PCG graph, add PCG nodes (Surface Sampler, Static Mesh Spawner, filters), wire PCG pins, place a PCGVolume and generate, or set up procedural scattering.
How to use this skill
Bring this guide into your coding agent with a prompt tailored to the tool you use.
- Open your project in Codex.
- Copy and paste the prompt below.
- Review files and risks before approving any action.
Inspect the Agent Skill at https://github.com/kevinpbuckley/VibeUE/blob/HEAD/Content/Skills/pcg/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/pcg, but wait for my approval before writing files or running scripts.
Copying this prompt does not install or run the skill. Review third-party files before use.
PCG Skill
PCG (Procedural Content Generation) in UE 5.7 is production-ready and fully scriptable via
the PCGPythonInterop plugin. No VibeUE service wrapper is needed — the Python API is complete.
⚠️ Read this before writing any code
These are the mistakes that cause infinite retry loops. Check each one before executing:
Do not call discover_python_class or discover_python_function on any PCG class — this skill contains everything you need. Calling discover bloats context and causes content filter failures.
- Volume Sampler input pin is
"Volume", not"In"—add_edge(input_node, 'In', sampler_node, 'Volume'). Using'In'silently no-ops and produces 0 points. voxel_sizeis aVector, not a float —set_editor_property('voxel_size', unreal.Vector(200, 200, 200)). Passing a float raises a TypeError.graphproperty on PCGComponent is protected — usepcg_comp.set_graph(graph), neverset_editor_property('graph', ...).- After modifying a graph, always: save → reload → reassign → generate — skipping reload means the component runs the old cached version.
- Check for existing nodes before adding — always inspect
[type(n.get_settings()).__name__ for n in graph.nodes]first. Adding a node type that already exists creates duplicates that break wiring. - Always save AND reload after every change — call
save_assetthenreload_packagesevery time. Without the reload the PCG graph editor window won't update and users will think nothing happened. - Use Volume Sampler for empty levels, not Surface Sampler — Surface Sampler requires geometry to sample from. An empty level has no geometry, so Surface Sampler always produces 0 points. Use
PCGVolumeSamplerSettingswithunbounded=Truefor empty or sparse levels. - Never spawn test actors to verify meshes or materials — do not use
spawn_actor_from_classto place test cubes. Verify by checking ISM instance counts on the PCGVolume instead:sum(c.get_instance_count() for c in volume.get_components_by_class(unreal.InstancedStaticMeshComponent)).
⚠️ Prerequisites
Both plugins must be enabled in the project's .uproject:
{ "Name": "PCG", "Enabled": true },
{ "Name": "PCGPythonInterop", "Enabled": true }
Verify they're loaded before executing:
import unreal
assert hasattr(unreal, 'PCGGraph'), "PCG plugins not enabled — check .uproject"
Creating a PCG Graph Asset
import unreal
factory = unreal.PCGGraphFactory()
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
graph = asset_tools.create_asset('MyPCGGraph', '/Game/PCG', unreal.PCGGraph, factory)
unreal.EditorAssetLibrary.save_asset('/Game/PCG/MyPCGGraph')
Loading an Existing PCG Graph
import unreal
graph = unreal.EditorAssetLibrary.load_asset('/Game/PCG/MyPCGGraph')
# graph is a PCGGraph — access nodes, input_node, output_node directly
Or search first with the Asset Registry (or Epic's AssetTools toolset):
ar = unreal.AssetRegistryHelpers.get_asset_registry()
hits = ar.get_assets_by_class(unreal.TopLevelAssetPath("/Script/PCG", "PCGGraph"))
⚠️
PCGGraph.is_standalone_graphis deprecated (issue #465) — it logs a deprecation warning in 5.8. Use the graph'sGraphUsageContext/ usage flags instead ofis_standalone_graphto tell a top-level graph from a subgraph.
Adding Nodes
Use add_node_of_type(SettingsClass) — returns a (PCGNode, PCGSettings) tuple.
All Settings classes are direct attributes of the unreal module — no find_class needed:
import unreal
# Surface Sampler node
node, settings = graph.add_node_of_type(unreal.PCGSurfaceSamplerSettings)
settings.set_editor_property('points_per_squared_meter', 5.0)
settings.set_editor_property('point_extents', unreal.Vector(50, 50, 50))
node.set_node_position(200, 0)
# Static Mesh Spawner node
spawner_node, spawner_settings = graph.add_node_of_type(unreal.PCGStaticMeshSpawnerSettings)
spawner_node.set_node_position(500, 0)
Settings can also be read/written after creation via node.get_settings():
settings = node.get_settings()
settings.set_editor_property('unbounded', True)
print(settings.get_editor_property('points_per_squared_meter'))
Identifying Nodes
node.get_editor_property('node_title') is None by default. Identify nodes by their settings class:
for node in graph.nodes:
print(type(node.get_settings()).__name__)
Note: the nodes array does not include the graph's Input and Output nodes.
Access those via graph.get_input_node() and graph.get_output_node().
Discovering Available Node Types
import unreal
node_types = sorted([x for x in dir(unreal) if x.endswith('Settings') and 'PCG' in x])
print(node_types)
Task Index
| Task | Sub-doc | Sample script |
|---|---|---|
| Create / load a PCG graph | (above) | scripts/build_pcg_graph.txt |
| Add / identify / discover nodes | (above) | scripts/build_pcg_graph.txt |
| Connect pins / position / remove | workflows.md | scripts/build_pcg_graph.txt |
| Place a PCGVolume and generate | workflows.md → Placing a PCGVolume | — |
| Surface Sampler → Mesh Spawner | workflows.md → Full Example | — |
| Settings property names / SMS config | reference.md | — |
Sub-docs
workflows.md— pin inspection/connection, node positioning/removal, editor notify, save/delete, placing a PCGVolume + generating, the full surface-sampler→mesh-spawner example, subgraphs.reference.md— settings property names, lowercase struct properties, Static Mesh Spawner config, common node settings classes.
Sample scripts (run via execute_python_code)
scripts/build_pcg_graph.txt— create a PCG graph and add Surface Sampler + Static Mesh Spawner nodes (native PCG API).