Are you looking for ways to speed up development, create endless worlds, and bring your dream game to life without spending years crafting content by hand? Join us for an exclusive live Q&A with the PCG team behind UEās plugin and THE CASSINI SAMPLE PROJECT!
When? February Wednesday 12th at 3PM EST Where? Our Discord server
What to Expect:
How UEās Procedural Content Generation (PCG) plugin can revolutionize your workflow Tips on integrating PCG into your indie projectāno matter the genre A deep dive into PCG and how it can save time while keeping creative control Live Q&Aāget your questions answered in real time!
Drop your questions in the comments below if you canāt make it live, and weāll cover them during the session. But if you can, join us on Discord to ask your questions directly!
Letās make game development faster, smarter, and more creativeātogether.
Hello. I have a question for you if I canāt watch the live today:
Iām currently working on a kind of rogue-like where the entire dungeon environment (walls and vegetation) will be randomly generated by PCG at every run, just using a handful of basic meshes to get this kind of result:
So I would like to know what is the recommended pipeline to combine Nanite, Lumen and huge PCG?
As far as iāve understood, the performance of Nanite is not great when used with Instanced Static Meshes (ISM) or Hierarchical instanced Static Meshes (HISM), and it is recommended to rather use Nanite with simple StaticMeshesā¦ But the PCG can only spawn ISM or HISM when using the StaticMeshSpawner node, so should I rather spawn thousands of StaticMeshActors with the SpawnActor node? Or should I keep using ISM/HISM and disable Nanite entirely?
Also, Iām experimenting with the Hierarchical Generation to increase performance, but my PCG is so heavy that my game briefly freezes every time a new tile loads. (So instead of a single 1 minute freeze at BeginPlay, I got many 1 second freezes every time I moveā¦) Is there any way to run PCG asynchronously at runtime to not freeze the game?
IIRC Nanite does fine with regular meshes or ISMs. HISMs are a problem b/c the system decimates the meshes on itās own, outside Nanite so it basically gets in the way.
Nanite doesnāt āseeā meshes so much as the totality of all the vertices and then assigns render-bins based on information it gathers therein. Thus, if the mesh is just-a-static-mesh or an ISM, Nanite ought to not really care.
Using ISMs ought to be better on the CPU though, so there is no reason NOT to use them.
-=-=-=-
@Epic ā What I would want to know is how PCG integrates, replaces, or otherwise dovetails with Landscape grass. Using Landscape grass is effectively like using a boundless PCG volume, with accessability to materials-logic. Is there intent for something similar or landscape-material sensativity with the PCG tool?
I can see in 5.5 we can use PCG on the GPU, will grass-systems transition to this model, Landscape grass included?
You definitely want to use ISMs with Nanite meshes when you can.
Yes, HISM is an overhead thatās not really needed for Nanite meshes vs ISMs.
You can do a lot of bad decisions in PCG, including spawning one static mesh component per instance, but by all means, donāt. Also, spawing one actor per instance will be extremely costly for nothing, so I very much suggest you not to.
And now to the meaty part of the question: is there a way to run PCG asynchronously at runtime to not freeze the game?
There are multiple levers for you to try:
Adjust the pcg frame time (āpcg.frametimeā cvar) so that itās more in line with what youād like, at the cost of generation taking more frames to finish
Enable pcg multithreading at the graph-level (pcg.GraphMultithreading) also enables processing outside of pcgās subsystem tick.
Try to do things that are long in larger cells or only once (at the Unbounded level in Hi-gen), especially things like sampling on meshes. This will make the smaller cells update a lot faster, and normally you can do very limited & very fast things then (like basic transforms + copy points).
Revisit your custom nodes - native & blueprint. Take example on the nodes that do time-slicing and allow running off the main thread.
Reconsider some nodes that are costly (for example: self pruning) when at runtime and find better approaches (create less/no overlap by design, etc.)
So while in 5.5 we havenāt given users the tools to replace landscape grass outright, itās possible to do a lot already with hierarchical generation (on CPU), and some more on GPU too (in 5.5).
Weāll be providing more content/code to replace landscape grass in time, but if you want to live on the edge (i.e. main branch), know that we already have added a node to get the grass maps on GPU for example as a first step to get there. You can expect more in 5.6!
Thanks for this detailed answer! Iāll try to apply all those different tips to get a runtime generation as smooth as possible.
Iām just not sure about one thing: what are the time-slicing nodes youāre talking about? And how can I check if a node does that? Do you mean all nodes that have more than 1 ExecFrame?
No sure how technical I need to be for you, but yes, if a node shows more than 1 frame in either Prep Frames or Execute Frames, then it was either time-sliced, or we had to put it in sleep because we were waiting for something (like loading a mesh, material, etc.)
Code-side, the execution states of the IPCGElement (the processing unit behind the node) return either true (phase done!) or false (phase not done!) that controls whether they will progress or be reexecuted later.
There are some levels of abstractions in the native nodes as we built āsimilarā nodes and didnāt want to reimplement some of these things more than once, but you can get a feel for it in a few nodes (pathfinding, attract, etc.) - generally used in conjunction with the āShouldStopā predicate on the IPCGContext object.
Itās not something weāve exposed at the blueprint level yet - for many reasons - but at least blueprints can be marked as ānot requiring the game threadā so we can execute them off frame too.
Ok thanks, itās a little more clear now. I dived into the PCG code for the first time, to see how time-slicing was used in the PathFindingElement class and I have to admit itās a bit too abstract for me at the moment, but at least i know where I should start looking.
So, for the moment, iāll just try to optimize as much as I can in blueprints only, and then Iāll consider coding my own custom nodes if I really need to do so.
I mean, personally, getting what-exists to just-take-advantage of the gains the GPU can provide would be enough; simply-faster would be great. Coupled with the gains of nanite it really, to my mind, maximizes the ability of grass as far as the eye can see at a performant level.
If it gets replaced, Iām OK with new tools, but I would suggest that the ease of which isolating material-layers, logically, that the landscape-grass provides and the consequential things you can do with it is MIGHTY handy. I would imagine the boffins on your end have already appreciated this so any forward-looking solution would hopefully be able replicate this kind of sensitivity.
Again, thanks for the response; glad to know someone is listening.