Running BP construction scripts at Package Time

We have procedural assets in our maps which are created by Blueprints. At construct time objects are spawned and placed in the map. This allows us to configure our map in different ways, and iterate quickly in editor.

The downside is that package builds take a while to start up because all of the construction scripts running.

Is it possible to package the game, so that the construction scripts run at package time, so when we run our final build the construction doesn’t need to happen so our maps load & start faster?

Hi Paul,

Unless something has regressed, objects pre-placed in a level have their construction scripts ran at cook/“package” time. They are solidified in the level during that process. This is to address the exact concerns you’ve brought up.

Dynamically spawned objects however will run their constructions scripts as they’re created. Events like BeginPlay, where some setup/initialization script can be placed will also be executed at runtime, so be mindful of that.

Are you seeing specific evidence that construction scripts for pre-placed level objects are being ran in cooked builds? Note that running the editor with -game is still an editor build, so expect constructions script to be ran there as well.

1 Like

Thanks for the info.

Is it possible for us to know if we are being cooked or simply PIE in a constructor? What I’m trying to build is:

  1. Content creator takes a level
  2. Content creator puts in a kill bluie print which contains a trigger
  3. When PIE anything outside of that kill trigger is deleted, but when they come back to the editor the objects are back again (this allows iteration)
  4. During cook time the objects are deleted outside of the kill script

This allows us to programatically delete objects which are not needed for our game but still allow us to iterate in game with all objects when playing in the editor.

I assume by “constructor” you mean the Blueprint’s “user construction script” (UCS)? - semantics, I know, but I want to be sure we’re on the same page.

We do not have any functions exposed to Blueprints that content creators can use to distinguish between PIE/Cooking runs. You could easily expose these yourself (make a utils library for you project). For PIE, you could use something like FPlayWorldCommandCallbacks::IsInPIE_AndRunning(), and for cooking it should be enough to just check IsRunningCommandlet().

However, the kind of logic you provide in your example is dangerous to run from the construction script. Having Blueprints interact with other instances is finicky from the UCS. It is difficult to reliably count on construction order (what if not all the other instances have been constructed yet? - you’d only kill half of the what’s outside the trigger). I don’t fully understand the point of the content creator doing this would be (deleting everything for just PIE runs… to save on iteration times?), but it just might a silly example you concocted.

Hopefully I answered your root questions. Cheers!

Thanks these are all good points. I guess some context might help here.

Our content creators are building maps based on template maps. These have a ton of objects in them.

When the content creator takes the map, they delete some objects that are no longer needed. Note that these are not actually deleted, because the level is based on sub levels (we want to be able to change the parent and the changes populate out to all derived objects) they are simply hidden in editor and destroyed when game is started.

I want to automate this by putting kill triggers in the map. If the player moves out of this trigger then they go “out of bounds”. It also has the second happy coincidence that any objects outside of the kill triggers get deleted (saving draw calls, memory & performance)

Ideally this is done at edit time so that there is less to package and the level loads quicker. I could do it at run time, but then I’m still streaming things in that I don’t actually need.

Perhaps there is a more UE4 friendly way of doing this?

Still, I may not be 100% following, but to make sure we’re on the same page I’ll reiterate what I think I understand: You have large levels, and content creators are working on only a small sub-section; you want to hide/remove all actors that aren’t currently within their section? You only want to do this for the content creators in the editor, seeing as it is only for iteration purposes; you do not want to delete the objects in the editor (pre-PIE).

So if what I understand is correct, why don’t you just divide the work into various sub-levels and not load those in PIE/editor? It seems you are already working with sub-levels, so maybe there is a piece I am missing. The content guys could work within that one sub-level, and don’t have to worry about the larger picture.

Another thing that may be helpful is that we were working on a feature to mark exec paths and nodes “developer only” in Blueprints - the idea being that you can leave things like debug Prints and such in the Blueprint. I am not entirely sure of where that work stands, I can check on that.

Still, if it seems you feel this is your best option (like I said, I’m sure I am still missing something here), then I would not do it in the construction script and instead do it in a BeginPlay call. That along with you exposing some kind of IsPIE() call to Blueprints should work, but keep in mind that call would be still around in the final packaged game, which is less than ideal.

Another thing to consider is writing a Blutility. Blutilities are Blueprints that can be ran in the editor, outside of the game. Think something akin to photoshop scripts - something to automate work in the editor. You can easily search Blutilities if this route interests you.