We have a game where the level is fully generated at runtime using PCG, with multiple rooms and corridors. We recently moved from 5.5 to 5.6, and since then the generation time has increased from 10s to 90s in build.
I saw that with 5.6 there were changes to PCG performance, with pcg.GraphMultithreading going from false to true and pcg.FrameTime going from 16.6ms to 5ms. I tried disabling multithreading, which saved me about 20s, and then increasing the FrameTime to 30, which also improved the time.
However, even with these changes, a map that used to generate in 20s now takes 40s.
Are there other changes introduced in 5.6 that could explain why the generation time has doubled ?
Would you happen to have some example data to validated against? We’'ve mostly seen perf benefits from enabling multithreading.
As for the pcg.FrameTime defaults, they were made smaller to avoid PCG from having to big of an impact on framerate. Feel free to change that budget to suit your needs.
Also are you using custom nodes? C++ or Blueprint? We’ve introduced a new Point Data type and it is possible that there is some conversion happening on your nodes that can add to the cost.
It should be possible to validate between 5.5 and 5.6 where the time is spent to report where that time was lost using the Profiler window in the PCG Graph Editor. This could help us narrow down the issue, if you happen to have a UE Project to share that exhibits this slow down feel free to share and we can look into it.
I see you do use BP Custom nodes and this means there is some PointArrayData to PointData conversion happening.
Could you try and setting pcg.EnablePointArrayData to 0 and see how this impacts your performance?
5.7 brings new Blueprint Node base class to better support the new PointArrayData type to avoid this implicit conversion.
This is the response from our dev who works on the PCG graph :
1- We use a Volume sampler to get a point grid on the room volume
[Image Removed]
2- Room grid is used to create list of points called regions (next to wall, next to corner, center, etc.) using Intersection and Difference nodes, as well as actor (Room) specific properties like “Can spawn on north wall”, etc.)
[Image Removed]
3- For each of the regions, the points are partitioned and passed through a loop subgraph that will randomly assign a prop from a Data Table and then check with Intersection nodes if the prop can be spawned in comparison of the previous points that managed to spawn a prop through this subgraph and the previous regions.
[Image Removed]
In the loop subgraph, we assign a prop to the current point via a custom Blueprint node.
[Image Removed]
In the custom BP node, we check which props have already been spawned (via a string attribute of indexes) then do weighted proba to assign a pro and then we compose the metadata of the point by assigning it different properties (prop soft class path, dimensions, etc.)
[Image Removed]
4- Once the point has been assigned a prop, we check if it can be spawned with Intersection nodes and then we spawn it using either Spawn Static Mesh or Spawn Actor nodes (for Blueprints and Blueprints that spawns Level Instances)
[Image Removed]
5- The points that spawned a prop are then fed to the subgraph loop for the next region to make sure there are no intersections (with some overrides properties for some edge cases) up to the last region.