Epic Office Hour Live Q&A: How to use UE's Procedural Content Generation plug in Your Indie Game!

Hey indie devs! :wave:

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!

:date: When? February Wednesday 12th at 3PM EST
:round_pushpin: Where? Our Discord server

What to Expect:

:small_blue_diamond: How UEā€™s Procedural Content Generation (PCG) plugin can revolutionize your workflow
:small_blue_diamond: Tips on integrating PCG into your indie projectā€”no matter the genre
:small_blue_diamond: A deep dive into PCG and how it can save time while keeping creative control
:small_blue_diamond: Live Q&Aā€”get your questions answered in real time!

:bulb: 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. :rocket:

3 Likes

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?

Hi dj-mindar,

First, letā€™s clear off some misconceptions:

  • 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:

  1. 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
  2. Enable pcg multithreading at the graph-level (pcg.GraphMultithreading) also enables processing outside of pcgā€™s subsystem tick.
  3. 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).
  4. Revisit your custom nodes - native & blueprint. Take example on the nodes that do time-slicing and allow running off the main thread.
  5. Reconsider some nodes that are costly (for example: self pruning) when at runtime and find better approaches (create less/no overlap by design, etc.)

Hope these help!

1 Like

Hi Frenetic,

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.

1 Like

Thanks for the reply; very much appreciated!

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. :smiley:

1 Like