Blueprint corruption, missing authoritative class at Engine reload

TLDR: I am trying to have a BP class deriving from my AThermalWind actor. However, the BP corrupts at every restart. I believe that’s because I am loading the modules improperly, but have no idea how to fix this.

Architectural Explanation:

AThermalWind, the class I want to BP-derive, belongs to a module called SkillSpawnedEntities. It implements an interface that belongs to a different module, called SkillSystem. SkillSpawnedEntities has a public dependency of SkillSystem, and both of them are a public dependency for the main module of the game. Here is a UML:

image

I can create the BP deriving from AThermalWind without issues, and the game runs as I expect. If I close and reload the engine, however, the BP corrupts. I get the following errors:

If I delete the corrupted BP and make another one, no issues until I restart again.

I may be loading my modules in the wrong way, can somebody help me?

Here is a snippet from my .uproject file:

image

SkillSpawnedEntities.Build.cs has “SkillSystem” in its PublicDependencyModuleNames array. The main game, “ScalarField”, has both “SkillSystem” and “SkillSpawnedEntities” modules in the same array in its .Build.cs.

Someone on Unreal Slackers made me notice that this could be a redirectors-related problem. I don’t think so but, to be sure, I’ll add these informations:

  1. Before my latest changes, the interface was on the “SkillSpawnedEntities” modules and named “ISkillSpawnedEntity”. The “SkillSystem” module depended on the “SkillSpawnedEntities” one.
  2. After moving the interface and inverting the dependencies between the two modules, I renamed the interface and added the following code redirect to DefaultEngine.ini, under the [CoreRedirects] section:
[CoreRedirects]
// ...
+ClassRedirects=(OldName="/Script/SkillSpawnedEntities.SkillSpawnedEntity",NewName="/Script/SkillSystem.NewSkillSpawnedEntity")

Have you tried setting the loading phase from SkillSystem to “PreDefault”?

Hi @pladux, thanks for your reply! And sorry if I’m late.

Yeah, I tried that, but then my computer started acting weird (the compilation taking ages, CPU usage percentage skyrocketing, cursor lagging as hell) and I interrupted it. Maybe what happened had nothing to do with the change in the .uproject, but I was kinda scared and reverted to “Default” :sweat_smile:

Since you’re pointing it out to me, I’ll give it another shot as soon as I find some spare time (I reverted every change I had). In the meantime, could you direct me toward some online resources properly explaining the modules’ loading phases? Because I don’t understand them at the moment.

For example, suppose I have a 3rd module such that the one you suggested I set to “PreDefault” depends on it. Is there some kind of “PrePreDefault” loading phase? Is there a simple way to just tell the UBT “Hey, build this module before this other specific one”?

Sure. Head over to Plugins in Unreal Engine | Unreal Engine 5.1 Documentation which will lead to FModuleDescriptor | Unreal Engine Documentation which will lead to ELoadingPhase::Type | Unreal Engine Documentation cannot be more obvious :crazy_face: At least the phases are well documented. If you need precisely when loading happens I believe you have to look at the sources.

I don’t know about the possibility to configure module dependencies. There is a “AdditionalDependencies” setting but afaik that used to be a configuration for build time, nowadays replaced by the “PublicDependencyModuleNames” thing in your .Build.cs files. That’s also only used when building.

Hi @pladux! Sorry for the very late reply!

Unfortunately, the “PreDefault” option on the “SkillSystem” module didn’t work. However, I discovered that the problem is more general than I initially thought.

The problem is:
Blueprints that derive or use classes that inherit from an interface/abstract class of another module break at engine reload.

In my previous example, I was trying to do this:

image

And AThermalWind, deriving from an interface of another module, was corrupting at every engine reload, even by setting

{
	"Name": "SkillSystem",
	"Type": "Runtime",
	"LoadingPhase": "PreDefault"
},

as suggested by @pladux.
I started working on a different feature, that has a very similar architecture: some concrete classes inheriting from an abstract class in a different module.

I can fill the array of skill conditions of my concrete skill without problems:

But when I reload the engine…

This is for sure a problem linked to dynamic libraries, but I am not being able to figure this out on my own :weary:

Here is the log for this last problem:

LogLinker: Warning: [AssetLog] E:\Dev\ScalarField\Content\Skills\BP_ConeOfColdSkill.uasset: VerifyImport: Failed to find script package for import object 'Package /Script/SkillCastConditions'
LogLinker: Warning: Unable to load TemperatureCastCondition_0 with outer BP_ConeOfColdSkill_C /Game/Skills/BP_ConeOfColdSkill.Default__BP_ConeOfColdSkill_C because its class (TemperatureCastCondition) does not exist

Blueprint corruption and missing authoritative class during Engine reload can severely disrupt development workflows. These issues might stem from improper data serialization or synchronization, causing conflicts between blueprint representations and their corresponding classes. Addressing this is critical for maintaining a stable and efficient development environment, preventing data loss and ensuring seamless collaboration among team members working on complex projects involving blueprints and code.