Blueprintable component loads with a lot of errors

Note: I am on 4.12, issue was already present in 4.10. I had it in a “contained” state: at some point I had a successful compile/save/restart editor cycle and I had not touched the troubled asset ever since. On 4.12 update things broke again badly.

Problem description: I have a function inside a blueprintable component (inside an actor class) that has a return type of reference to a class of specific type (this class is child of an Actor). Within that function there is some logic that among other things:

  • Gets component owner, gets its class, casts it to a particular class which is later used in a comparison. Link from class cast to comparison node breaks.
  • Gets class defaults of an assets whose parent is UObject (i.e. not Actor). Those defaults contain arrays of structs. Links from those arrays to “for each loop” break.
  • Uses a temp variable of type reference to particular class. This variable’s type is supposed to coincide with functions return type. Both of them (variable type and function return type) are reset to literally “class” instead of the class I specify. As a result - a lot of links break and I get a lot of compile errors.

From this point on, some other things that depended on the outcome of this function break, but I assume it is a chain reaction.

If I fix all the errors (i.e. correct all variable types, recreate all the missing links, etc.), everything compiles nicely and the game works as expected. Then I save. Then restart the editor and the problem is back. As I said - I seem to have had successful save/restart cycle at some point and that is the version I am using, but the moment I touch that asset (a simple recompile+save) it all breaks.

I believe it would not be trivial for you to repro this, I would gladly provide any further details. I would be thrilled if you could somehow assist me on this one.

Hi AINTD,

  • Does this occur in a clean, blank project with no additional content or is it limited to one project?
  • Are the links that are broken all from your Get Class Defaults nodes? If so this is a known issue and is in our system as UE-31725.
  • What steps can I take to reproduce this on my end if the above is not the case?

Hello,

  • This error is happening in a project I am working on, no code changes, just content (i.e. Blueprint project).
  • Class Defaults links that break are an issue, but I believe they are a separate thing. I could work around this until the bug gets fixed.

They way it looks, there is some sort of nasty cyclic dependency that does not get resolved on editor load. I am attaching a few screens, but I am not sure how helpful would these be.

And if I save that BP in that state and close the editor, the editor would not even load again - crash with no decent callstack at 93% load - need to revert that asset.

What is Return Results original class? Is it just class (Actor)?

It is a Class Reference to a Blueprint I created - ActionGeneric (or one of its children), which is an Actor.

Can I see an example project with the assets you are experiencing this with? If you upload them I’ll be happy to take a look and see what may be occurring.

Can do. Which assets would you need specifically? Entire dependency tree of the problematic asset? The structure is as follows:

  • WorldObject class, based on Actor. Is base class, has many children. Contains ObjectActions blueprintable component and calls “Initialize” on it.
  • ObjectActions component, contains an array of ActionGeneric references that it needs to fill during initialization.
  • Initialize function + GetActionBPClass function are the ones that break, specifically the latter.
  • GetActionBPClass also relies on BP_Relation_ClassToAction to get class defaults (those broken structs arrays links).

These are sort of immediate references, but of course, if you go deeper, these references also have references of their own.
Am I right in thinking that the ObjectAction component, ActionGeneric and BP_Relation_ClassToAction are the ones that you need?

Where do I upload them to?

Hi AINTD,

The 4.12.3 hotfix had a fix for the class defaults issue you have, can you update and see if this addresses the other issues as well? I have a feeling that the break in the defaults is what is causing the other errors but it would be good to eliminate this possibility if it is still occurring.

Hi ,

4.12.3 refuses to launch altogether. I reverted to 4.10.4 (class defaults worked fine there too), which was the last version when the asset in question successfully compiled and saved.

It looks like a case of cyclic dependency. ObjectActions component makes use of ActionGeneric class (directly), whereas ActionGeneric class will end up referencing something that in turn references ObjectActions component. The moment I add something with “ActionGeneric” class to ObjectActions component and restart the editor, it breaks (PLACEHOLDER-CLASS is set for variables/function outputs that try using ActionGeneric).

It is possible that the reason it saved successfully once, is due to there not being a particular reference loop at some point. Then that new reference got introduced, but it did not dirty the component, so no recompiling was needed, it all kept working nicely until the moment I recompiled.

Any advise? Any efficient way for me to search for the exact place that makes it break?

It would be hard for you to repro it in a sterile environment, since I would need to submit entire project for you to recreate that dependency tree.

Unfortunately no, there isn’t an easy way to find exactly where a dependency loop is occurring, the best I can suggest is to trace through the function that the errors are occurring in and find if the code requires information from an actor that is requesting information from the actor running the function or any form of chain such as this. Cyclic dependencies become harder to trace the more complex a project becomes, but it is necessary to remove them to prevent later compilation errors such as the one you are experiencing now. Please go through your blueprint and follow the logic to see if you can find where the dependency loop occurs.

I see there is no easy way out of it. :slight_smile: I have been digging through older revisions of the asset and the funny thing is that the “successful” change list (i.e. when I compiled, saved and it was loading correctly from then on) is not that successful, meaning that if I get that revision and recompile - errors start happening again. Somehow I got a successful compile and save once and persisted for some time, but the issue has always been there. I will be posting updates as I go along trying to solve this, maybe it will be useful to someone.

UPDATE 1:

  • Successful compile/save was done with 4.10.1. I cannot go back to it, opening that revision with 4.10.4 and recompiling - breaks things.
  • 4.12.3, as mentioned crashes on editor load.
    UPDATE 2:
  • I went back to 4.10.4 and deleted the GetActionBP
    Class function altogether. SpawnActor from class uses statically ActionGeneric class. This compiles and saves and reloads correctly, including in 4.12.3
    UPDATE 3:
  • After the previous change, if I add “get class defaults”, the one that gives me those 2 arrays of structs, just add the node, without connecting it to anything, save and reload editor - it crashes on 4.12.3. Need to go back to 4.10.4, open and remove it.
    UPDATE 4:
  • I have tried adding arrays of structs locally to the ObjectActions component, so it would not need to query class defaults. Guess what: just declaring those arrays, i.e. creating variables, not using them anywhere, saving, reloading - the issue is back. Actually, it does not even need to be an array, single variable of type struct is enough.

UPDATE 5:

  • I removed WorldObject class reference and ActionGeneric class reference from the struct in question. ONLY then everything works (makes sense, since at this point that struct is pretty much empty). Removing just either of those class reference members was not enough. It seems the loop goes like this: WorldObject → ObjectActions component → struct variable → class reference to WorldObject
    UPDATE 6:
  • It seems the issue is NOT about ObjectActions component referencing WorldObject or ActionGeneric. I have created class reference variables with those values and they work fine. The issue arises specifically when a struct variable has class reference members with those values.
    ** UPDATE 7:**
  • More interesting things. It seems that thing work fine if my class reference variables reference the base blueprint class, in my case ActionGeneric. However, if that variable references a child blueprint class (for example: Action_Build is a child of ActionGeneric), editor crashes on load. Furthermore, to actually be able to SET class ref variable to the child blueprint class, I first need to open that blueprint and recompile, only then would it appear in the dropdown list for the variable. Following this logic - when editor loads and finds that class ref variable with a value set to something that it has not loaded yet (nor is going to?), things break. I have had this issue before a couple of times - specifically some var values being lost/reset because assets they were referencing are not loaded. Opening/compiling would allow to set those variables to reference those assets again, but issue would repeat on editor restart.

UPDATE 8:
Managed to fix it. Seems to have been a complex problem. Things I have done:

First:
Created a game singleton class with asset id reference array containing reference of all ActionGeneric children. Set it in defaultengine.ini. This seems to solve the issue of assets not loading in time on editor startup.

Second:
Recreated original GetActionBPClass graph (not the function itself). Got rid of casting to Owner to WorldObject (not needed and was breaking things, possibly introducing reference loop). Recreating the original function, even with these changes was not possible: it would still break putting function return result to PLACEHOLDER-CLASS. So I put the graph in the Initialize function instead. It ends up being a bit bloated, but works fine.

Third:
Removed Initialize call from WorldObject and put it on BeginPlay of the component instead. Once again, a potential contributor cycled reference.

Fourth:
Beautify pass - comments and straightened links. I am sure it helps. :slight_smile:

Have tested mutliple times with recompiling, resaving, restarting the editor. Seems to hold up nicely. I am sort of glad 4.12 came along as it made me to properly fix a nasty bug that laid dormant for more than 4 months.

I’m happy to hear you were able to fix the error you were seeing. I am marking this as answered for tracking purposes.