Confusing behavior using External Data Layers

Hi,

We are using External Data Layers to segment content in our maps that is only included in certain build flavors. So far this works well, however we are seeing some confusing Editor behavior which is resulting in people accidentally assigning things to the wrong DataLayers. I was wondering if this is intentional or a bug?

Specifically, the code in UExternalDataLayerManager::GetMatchingExternalDataLayerAssetForObjectPath and the check here

if (FPackageName::GetPackageMountPoint(ExternalDataLayerAsset->GetPackage()->GetName()) == MountPoint)
{
	Candidates.Add(ExternalDataLayerAsset);
}

This makes sense if you are using GameFeature plugins where the EDL should be applied to all content from the GFP when that content is placed in maps in /Game/, however it’s even applied for maps inside the plugin which defines the EDL which seems incorrect since it means everything inside the plugin is basically put in the EDL unconditionally

Also, if you register an EDL in your game content (for example by calling UExternalDataLayerEngineSubsystem::RegisterExternalDataLayerAsset from your game’s UAssetManager subclass) this means that anything you drag from your game content gets put in it implicitly, which is not usually desired. But then for example adding a new actor from the Place Actors Menu doesn’t have the EDL applied, even if it is a class defined in the GameFeaturePlugin.

It seems like possibly the paths which call GetMatchingExternalDataLayerAssetForObjectPath passing the actor’s class, like UDataLayerEditorSubsystem::GetActorSpawningExternalDataLayerInstance, need to also consider the mount point of the level the actor is placed into? For example, the following scenarios:

  1. EDL is /PluginA/EDL_Feature, Class is /PluginA/BP_Something, Map is /Game/Map_Test - EDL_Feature is applied, this is what we would expect
  2. EDL is /Game/EDL_Feature, Class is /Game/BP_Something, Map is /Game/Map_TestFeature - EDL_Feature is applied, but should it be implicitly? there is no cross-plugin reference. Maybe in a plugin, but for /Game/EDL_Feature, this is problematic since it basically is assigned to everything in the game.
  3. EDL is /PluginA/EDL_Feature, Class is /Script/PluginAModule.Something, Map is /Game/Map_Test - EDL_Feature is not applied, This seems inconsistent with 1) since if the plugin is disabled, /Script/PluginAModule.Something won’t exist.

It seems like the code needs to handle /Script paths to be consistent and also check that the map’s mount point is different from the EDL’s mount point? That said, maybe there is there is an element we are missing here since there isn’t a lot of documentation on EDLs yet.

Thanks,

Lucas

[Attachment Removed]

Steps to Reproduce
Create an External Data Layer and assign it to a level. Drag assets from the content browser from the same plugin which defines the EDL into the level without the EDL being current. See they are assigned the EDL

[Attachment Removed]

Hello!

We are in the bug\out of design territory here. The first thing is that you should look at is CL53791161 which addresses the case actors are added to level that are part of the same GFP than the EDL.

Regarding point 2, EDLs have been designed to be part of plugins so this is a grey zone.

Point 3 is a bug could cause bugs at runtime. I’m not sure if there will be an easy fix as there is no rule that forces the name of the plugin to be part of its modules. That likely requires searching the records in the plugin manager.

I filled a bug report to get this reviewed by the engine team.

Regards,

Martin

[Attachment Removed]

Thanks! yeah, I’m aware we are possibly using these in a weird way :). EDLs seem pretty useful though even beyond the context of GFPs and there doesn’t seem to be an explicit dependency code-wise, so we figured why not since it wasn’t possible to rework code into a GFP due to other limitations (like GFPs not supporting AdditionalPluginDirectories)

I’ll check out that CL since that was the most painful part of it for us. It looks like it would solve our issue using the EDL in /Game content since it compares mount points not the plugin state specifically, so it would work here too.

For 3: I think you can use FPluginManager::PackageNameFromModuleName to get the plugin a module came from, but it could be weird if there are multiple mount points other than the plugin-named one. Thanks for following up on this, since as you say, it’s not trivial.

I mostly mentioned it because we got tripped up by it, since some people were trying to repro the other assignment issue but dropping a native actor class and couldn’t which confused the diagnosis on our end.

Thanks,

Lucas

[Attachment Removed]