Slow Plugin loading issue?

Hello,

I would need some advice about a recent issue I met. To explain it in a straightforward way, when I load my main map in the editor, there is no problem, all the actors are loaded and with no error.

If I try to launch a commandlet (in my case, a DuplicateOrRename one) on this same map, most of my actors won’t load and be indicated as invalid! Having a look in the log, I see many errors like these:

  • [2025.05.08-07.19.16:916][ 0]LogWorldPartition: Warning: Unknown actor base class `/Unr/Blueprints/COR/Catenary/CatPole/BP_COR_CatPol_Simple.BP_COR_CatPol_Simple_C`: Actor: ‘BP_COR_CatPol_Simple_C_UAID_AC91A1451541E52602_1163448047’ (guid ‘3E5C1E84447499E147DBABBBCF027931’) from package ‘/Unr/__ExternalActors__/Maps/L_CorailKit_Showcase/9/1D/SI7WAQ77A1BO6WHJFR47TZ’
  • [2025.05.08-07.19.16:917][ 0]LogWorldPartition: Warning: Unknown actor base class `/Unr/Blueprints/COR/Catenary/CatSupport/BP_COR_CatSup_Kit.BP_COR_CatSup_Kit_C`: Actor: ‘BP_COR_CatSup_Kit_C_UAID_AC91A1451541E52602_1109311948’ (guid ‘DF869A4247332A1C7469308746CF44E6’) from package ‘/Unr/__ExternalActors__/Maps/L_CorailKit_Showcase/9/26/T4J8X1T682V5VZLKEJVOXM’

Fun fact, if I add this plugin in my uproject (it has only a content with a lot of assets), then, I don’t have these messages and my map is duplicated correctly:

“AdditionalPluginDirectories”: [

   "D:/CORAIL\_LIB/Workspaces/ppoupardin\-main\-latest/UnrealData/CorailLib/Plugins"

]

I feel like that there is a timing issue somewhere with an asynchronous process but I’m not sure. What can I check at this point?

Thank you,

Philippe

Bonjour Philippe,

Can you share the structure of the folders for the project and the additional plugin directories? Where is the “unr” plugin?

Can you also share the log for the editor that executes the WorldPartitionBuilderCommandlet?

You should probably change your code so it uses UnrealEditor-cmd.exe. This exe is the console version and will pipe more messages to the TTY.

Regards,

Martin

Hello Martin,

Thank you for having a look on my issue. I’m not sure to which level of description you are expecting on the structure of the folders (CorailKit is our reference and Unr is part of it). I joined to this message a basic framework without source and assets but included the uproject and uplugins.

CorailLib is mainly a container for all the assets that we could use in our different projects and is pretty basic. Normally, we do not include CorailLib in CorailKit (again, that was just a test to see if it would change the output and it did).

I also took the freedom to execute directly the commandlet, with UnrealEditor-cmd.exe as requested. I joined 2 logs. One with the problem and no call to the additional plugin (CorailLib) and the other one which includes the additional plugin and solves our issue.

Still, as you asked also the way I was calling the commandlet from the editor, here is the code :

`bool UUnrCookingCoreLauncher::DuplicateWorldPartitionMap(UWorld* WorldInput, USubworld* pSubWorld, const FString& NewPackageName)
{
FString strMapPackage = WorldInput->GetPackage()->GetName();
FString strSubWorldName = pSubWorld->GetSubworldName();
UClass* pDuplicateBuilderClass = UUnrCookingCoreDuplicateBuilder::StaticClass();

UEditorLoadingAndSavingUtils::NewBlankMap(false);

TStringBuilder<512> oCommandletArgsBuilder;
oCommandletArgsBuilder.Append(strMapPackage);
oCommandletArgsBuilder.Append(" “);
oCommandletArgsBuilder.Append(”-run=WorldPartitionBuilderCommandlet -Builder=“);
oCommandletArgsBuilder.Append(pDuplicateBuilderClass->GetName());
oCommandletArgsBuilder.Append(” “);
oCommandletArgsBuilder.Append(”-NewPackage=“);
oCommandletArgsBuilder.Append(NewPackageName);
oCommandletArgsBuilder.Append(” “);
oCommandletArgsBuilder.Append(”-SubWorldName=");
oCommandletArgsBuilder.Append(strSubWorldName);
FString strCommandletArgs(oCommandletArgsBuilder.ToString());

// Build the command line that will be launched by the process
FString strExecutablePath = FPlatformProcess::ExecutablePath();

FString strProjectPath = FPaths::IsProjectFilePathSet() ? FPaths::GetProjectFilePath() : FApp::GetProjectName();

FString strCommandLine;
strCommandLine += TEXT(“"”) + strProjectPath + TEXT(‘"’);
strCommandLine += TEXT(" -BaseDir="“) + FString(FPlatformProcess::BaseDir()) + TEXT('”');
strCommandLine += TEXT(" -Unattended");
strCommandLine += TEXT(" -RunningFromUnrealEd");
strCommandLine += TEXT(" ") + strCommandletArgs;

const bool bLaunchDetached = true;
const bool bLaunchHidden = true;
const bool bLaunchReallyHidden = true;

// Create new read/write pipes to retrieve the output of the process
void* pPipeRead = nullptr;
void* pPipeWrite = nullptr;

verify(FPlatformProcess::CreatePipe(pPipeRead, pPipeWrite));

UE_LOG(UnrCookingCoreLog, Display, TEXT(“Command for duplication: %s %s”), *strExecutablePath, *strCommandLine);

// Launch the process
FProcHandle oProcessHandle = FPlatformProcess::CreateProc(*strExecutablePath, *strCommandLine, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, nullptr, 0, nullptr, pPipeWrite, pPipeRead);

if (!oProcessHandle.IsValid())
{
UE_LOG(UnrCookingCoreLog, Error, TEXT(“Failed at duplicating production level process”));
return false;
}

// Print the output log of the process
while (FPlatformProcess::IsProcRunning(oProcessHandle))
{
const FString LogString = FPlatformProcess::ReadPipe(pPipeRead);
if (!LogString.IsEmpty())
UE_LOG(UnrCookingCoreLog, Display, TEXT(“%s”), *LogString);

FPlatformProcess::Sleep(0.1);
}

FPlatformProcess::ClosePipe(pPipeRead, pPipeWrite);

int pReturnCode;
FWindowsPlatformProcess::GetProcReturnCode(oProcessHandle, &pReturnCode);

if (pReturnCode)
{
UE_LOG(UnrCookingCoreLog, Display, TEXT(“RunUAT: Duplicating production level process failed with error code: %d”), pReturnCode);
return false;
}

// Reload the asset registry so that the HLODs directories appears in the Outliner
if (!IsRunningCommandlet())
{
// Force a directory watcher tick for the asset registry to get notified of the changes
FDirectoryWatcherModule& DirectoryWatcherModule = FModuleManager::Get().LoadModuleChecked(TEXT(“DirectoryWatcher”));
DirectoryWatcherModule.Get()->Tick(-1.0f);

// Force update before loading converted map
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(“AssetRegistry”);
IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();

FString MapToLoad = strMapPackage;

TArray ExternalObjectsPaths = ULevel::GetExternalObjectsPaths(MapToLoad);

AssetRegistry.ScanModifiedAssetFiles({ MapToLoad });
AssetRegistry.ScanPathsSynchronous(ExternalObjectsPaths, true);
}

return true;
}`Hoping you could find something in these data that would explain my problem.

Thank you again,

Regards,

Philippe

My colleague was able to reproduce the problem. It seems to be related to the WP level being part of a plugin. It is weird that adding the additional plugin is resolving the problem. I’m assuming that the CorailKit project doesn’t depend on it as you would have issues.

I would suggest that you keep using AdditionalPluginDirectories until we find a proper fix.

My colleague has confirmed that the problem is resolved in the 5.6 and Main stream.

Martin

Your assumption is right, CorailKit project does not depend on it. I just added CorailLib because it has a huge content and I wanted to know if the time spent to scan the content would delay somehow the boot process before loading the level itself. Maybe it has nothing to do with that, it was really a dumb test.

I was even wondering at some point if redirectors could be part of the problem and resaved all the actors of the level but it didn’t change the outcome.

It is important too to highlight the fact that this level is not new, it has always been in Unr, we use it as a showcase. It is just pretty unclear when this trouble occured…

For the time being, I will keep using the AdditionalPluginDirectories indeed.

Thank you again,

Philippe