BP World Subsystems in Play In Standalone mode

This question regards the “Standalone Game” launch option from editor, not the actual standalone build of the game. Does it have it’s own name or abbreviation? I haven’t found any and it’s making it hard to find any information about this mode.

When using a blueprint class derived from WorldSubsystem, then in “Standalone game” this subsystem is not initialized, unless it is referenced by some asset outside of level (= it is loaded before level). If it is only referenced from level assets (e.g. from some actor), then during FSubsystemCollectionBase::Initialize, it is not found in reflected classes, and therefore not created.

I have temporarily “solved” this by referencing the asset from GameInstance, however that is inconvenient. I suspect the same issue is going to appear anywhere where reflection is queried for derived classes ( GetDerivedClasses() is called at 50 different locations in engine), and it’s not feasible to manually list all blueprint classes that are needed somewhere.

  1. Is WorldSubsystem subclassing with blueprints unsupported? I use it so that I can reference some data tables from them.
  2. Is “Standalone game” just always broken?
  3. Is there a way to solve this automatically? E.g. marking an asset type as always loaded in Standalone game?

This question regards the “Standalone Game” launch option from editor, not the actual standalone build of the game. Does it have it’s own name or abbreviation?

It’s quite confusing. I say “Testing standalone from editor” and “testing in a packaged build”, more verbose but less likely to run into confusion.

Blueprint subsystems

Hello, creating blueprint WorldSubsystems is indeed unsupported. They should be kept native and you should be wary of inheritance, because detected native UWorldSubsystem classes are automatically created so long as their implementation of ShouldCreateSubsystem returns true, so it’s very easy to run into redundant subsystems being created unless parent classes return false there.

Blueprint subsystems aren’t supported because blueprint assets are loaded late (unlike modules which are immediately loaded), and because blueprints can be recompiled at any time. We haven’t made work of extending the subsystems to support that.

Ensuring certain assets are loaded when playing Standalone

“Is there a way to solve this automatically? E.g. marking an asset type as always loaded in Standalone game?”

As you noticed, hard referencing them from another loaded asset works. GameInstance, GameMode BP, the map’s WorldSettings etc. Other methods include:

  • A hard reference in a custom UDeveloperSettings subclass that you can set in Project Settings and which are saved in INI files. Note that a hard reference to a BP asset here does mean the asset will be loaded very early on application startup, which is when settings are loaded from INI files.
  • Hardcoding an asset path in a UObject constructor. An example of this is in the ThirdPersonTemplate’s GameMode class:

AThirdPerson55RGameMode::AThirdPerson55RGameMode() { // set default pawn class to our Blueprinted character static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPerson/Blueprints/BP_ThirdPersonCharacter")); if (PlayerPawnBPClass.Class != NULL) { DefaultPawnClass = PlayerPawnBPClass.Class; } }Since you mention you made the WorldSubsystem a blueprint in order to reference some data assets, I would recommend either the FObjectFinder approach if the data asset can be hardcoded, or referencing the data assets by introducing a custom UDeveloperSettings with blueprint editable fields via Project Settings. Then your native WorldSubsystem class can read them out from GetDefault<UMyDeveloperSettings>().

If the assets must be discoverable (“find all assets of class X”) then configuring the asset type in Asset Manager in Project Settings is the way to go. You would include some asset folders to scan for those assets, then an UAssetManager call to scan them (ScanPathsForPrimaryAssets) + retrieve results (GetPrimaryAssetDataList) at runtime. Some info on that here and here. Discoverable assets aren’t automatically loaded, but you after retrieving them you can choose to async load them.

Does this answer your questions?

1 Like

"I was under the impression that it is common practice to create a BP inheriting from c++, just to fill in references to other assets into default properties. "

That impression is correct, that’s a great use of blueprints. Subsystems are indeed an exception to that because we don’t support blueprint subsystems.

Thank you, I think I can avoid the BP subsystem in this case.

I was under the impression that it is common practice to create a BP inheriting from c++, just to fill in references to other assets into default properties. Is this also wrong? Or is it fine, just not for subsystems?