[4.5.1] Compiling interface blueprint will always crash

I’m crashing on trying to load a map that uses Blueprint interfaces. Looking at the source, I’m puzzled at how it ever works.

BlueprintEditorUtils.cpp\PreloadInterfaces calls UBlueprint::RegenerateClass with PreviousCDO explicitly set to nullptr, which calls FBlueprintEditorUtils::RegenerateBlueprintClass. Right at the top of RegenerateBlueprintClass, it does a check to make sure PreviousCDO is not a nullptr if the blueprint hasn’t been regenerated yet. This seems like it’s never going to work.

It doesn’t seem like RegenerateBlueprintClass is setup to work with interfaces at all.

I recently added several interface classes to get around another blueprint limitation with circular references. I had BP_A which referred to BP_B, which referred to BP_A. I setup an Interface_A and had BP_A implement it, so then BP_B would just refer to Interface_A. It seemed to fix things until I shut down and reloaded. At that point, I got crashes trying to load that were related to RegenerateBlueprintClass.

So, my choice is roll back to not fix my circular references (ok, not really a choice, since the game doesn’t work) or try to fix this blueprint compile issue of interfaces.

I’m hoping someone could help me figure out how RegenerateBlueprintClass is supposed to handle interfaces and I can fix my project.

(I’m not using 4.6.0 because it introduces a project busting issue with dispatchers in blueprints)

Blueprint interfaces are totally broken, don’t even try to use them or memory corruption will bite you. Though looks like you found one more way they’re broken.

Hi ,

Sorry for the delayed response. Would you be able to provide a callstack for the crash that you are experiencing? Project and Editor logs (if available) would also be helpful.

Thanks .
I am in the middle of integrating 4.6.1 and verifying its stability. After that I will attempt to restore my use of interfaces and try to get the crash again. I won’t be able to get to this until the end of the week or early next week. I’m letting you know so you don’t think this issue is dormant.

Not a problem at all. Whenever you get a to look into this again, just post an update and we can start digging into this issue with you.

I was finally able to get 4.6.1 working, so I tried this crash using 4.6.1 and verified it still exists.

I wasn’t sure what the editor log was. Just found a log in my game project saved\logs folder. Log and callstack attached.interfacecrash.zip

Repro:

  1. Have 3 classes refer to each other.
  2. To remove circular dependencies, abstract classes through interfaces.
  3. Load map that contains these blueprints.
  4. Crash.

I tried to introduce a circular dependency in Blueprints, but it looks like the Editor has some safeties in place to protect against the circular dependency I was trying to create. I created three Actor Blueprints, and gave each one a Child Actor Component. Blueprint A’s child actor component was set to Blueprint B, Blueprint B’s child actor component was set to Blueprint C, and Blueprint C’s child actor component was set to Blueprint A. This should have created a circular dependency, but there were no errors or crashes when adding any of the Blueprints to a level or when playing the level. Loading the level did not provide any problems either.

Could you let me know exactly how you set up your original circular dependencies? If you were able to reproduce this issue in a new project, could you upload that so I can take a look?

Unfortunately, when I rollback my project to the changelist with the interfaces being used, I get a crash on launch, but I think it’s more of a function of having a non-clean get than a real crash. So, I can’t get at my blueprints to give a more detailed description than what I have given already.

I attempted recreate it in a new project, though. I didn’t get the crash I show in interfacescrash.zip callstack, but I get a different crash. I think I can’t get the interfacescrash.zip crash because looking at the code it appears to be very order dependent. In a simple project, it might be getting lucky in the order of loading the blueprints. The crash I point out in RegenerateBlueprintClass would occur if it needed to rebuild a interface while in the middle of building a blueprint. RegenerateBlueprintClass is called explicitly with nullptr which RegenerateBlueprintClass forces a crash on, so I’m hoping someone could take a look at UBlueprint::RegenerateClass and figure out why it calls RegenerateBlueprintClass with nullptr.

Even though I didn’t repro interfacescrash.zip crash, I did find a different possibly related crash. In the project, MyCharacter calls MyHUDInterface::MyHUDFn. MyHUD implements MyHUDFn. In it, it calls MyCharacterInterface::DoMyCharacterFn. This is implemented by MyCharacter. It crashes when it calls this function. To put it more simply: A::Foo calls B::Bar through an interface, which calls A::Norf through an interface and crashes.

I have attached the example project here.

Thank you for the project that you provided. I was able to see the crash that you described, and I was able to get it to stop occurring by disconnecting the exec connection to DoMyCharacterFn in the implementation of MyHUDFn. I think there may still be a minor circular dependency occurring (and for some reason I could not identify the DoMyCharacterFn was being called periodically ever 3-4 seconds or so even when I was not doing anything). Would you be able to provide more information regarding what your end goal is?

Right, not calling DoMyCharacterFn will clear the crash. Sorry I didn’t point out the use of the timer. That timer call calls the same function. To trigger the crash, I just fire, since the projectile calls it.

As for my end goal, I wasn’t actually trying replicate my project’s setup with this example, I was just trying to setup a simple way to show the crash. But I would think the setup shown by the example should be valid and should be supported. Consider an example of a playercharacter, and a pickup. You might have a playercharacter activate a pickup, so calling a function on that pickup. Then that pickup doing some tests and then giving the pickup bonus to the character, so in a sense A calls B, which then calls back to A.

My project has multiple sorts of setups similar to this, just not actually with character, hud and projectile.

Oh, please. I was just about to clean my circular references using interfaces since as it is my project crashes 4.6.1 if I as much as glance at it. How on Earth am I supposed to make a complex project without circular references then? Geez, if I wasn’t 6 months into the project I’d just scrap it and move everything to Unity.

Instead of adding new fancy features maybe Epic should concentrate on making sure the whole Blueprint and UMG stuff actually works?

I am also experiencing a lot of instability with 4.6.1. I wasn’t able to use 4.6.0 at all, but 4.6.1 crashes a lot more frequently than 4.5.1.

As far as what to do to get your circular references to work, I’ll tell you what seems to be working for me. I setup a blueprint function library to handle all the cross blueprint function calls that get broken by circular references. This seems to be enough to break the circle. The inputs and outputs from any of the functions in the function library only take base C++ defined types. So instead of passing MyCharacter reference, I pass Character. Then inside the function, I do the cast from Character to MyCharacter. Then call the real function on the MyCharacter. Also, my blueprints only store variables in base C++ types, not the other blueprint types.

Here’s an example of a function in my function library:

It’s ugly, fragile and inconvenient, but it got my project working.

It is certainly possible to have two (or more) Blueprints communicate data back and forth between each other without running into a circular reference.

I did a quick set up this morning where I have a character run into a pickup which causes the character Blueprint to call a function in the pickup’s Blueprint.

The function in the pickup Blueprint takes the character’s current health value and, depending on that value, adds an additional amount of health, then calls a function on the character to update the character’s health.

The function on the character checks to make sure the new health value is not greater than the character’s maximum health value.

Finally, the character destroys the pickup that it collided with (in the character event graph).

No circular reference occurs in this instance (though when you compile one of the Blueprints the other one is marked as dirty and indicates that it needs to be recompiled, but it will work correctly). Admittedly, this is a fairly simple setup, but it should be possible to do the same for more complex situations if it is planned carefully.

We are still working on making Blueprints more robust in these situations as well. The number of problems that are being seen currently will start to decrease in upcoming releases of the Engine, and hopefully disappear entirely.

I am still working on reproducing the original crash involving interfaces. I might see if I can modify this setup that I created to force a circular dependency and add interfaces to try to reproduce the crash you initially described.

Yes, having A refer to B which refers to A (which I’m calling a circular reference) can work in blueprints. I had plenty of those setups in my project and they all worked, until they didn’t. Some level of complexity pushed it over the edge to make it start failing. Usually, when compiling one blueprint makes another dirty is the sign of problems. Also, things can end up working in PIE and then fail in standalone. Standalone seems to go through a different compile process, which is more sensitive. From trying to trace through the issues I’m having, it appeared that it’s all dependent on the order the blueprints are compiled. I don’t have a strong handle on this process but it seems like it does something like start compiling A and gets to a reference to B, so it starts compiling B, which then gets to a reference to A, but it’s already compiling A, so fails in some way. I’m definitely over simplifying it, but you get the gist.

I thought interfaces would be the crutch to get over the circular references, but they seemed to make things worse. The only solid fix I have found was to try to only store references to C++ types in my blueprints and do my casts in a neutral blueprint function library. It’s definitely not the way I want to go, but I can’t afford to do any rewrites. Also, I don’t even know why my circular references are bad, so I can’t improve my blueprints without knowing the problems.

What we generally mean when we refer to a circular reference is a situation where Blueprint A has a function that needs a result from a function in Blueprint B, but Blueprint B’s function requires the result of the function in Blueprint A in order to complete its calculation. That particular scenario is relatively easy to track down. The more complex ones involving multiple Blueprints can be a bit of a nightmare.

When I have run into these problems in the past, and I’m sure I will again in the future, the solution usually involves moving a function (sometimes even just a variable), or part of a function, from one class or Blueprint to another class or Blueprint. It is not always a simple process to go through, but after having done so I often realize that the new location for that function or variable is actually a better place to have it.

Hi ,

I took another look at this again today and noticed something that I had missed the last time. In the example project that you provided, you were using Interfaces as the parameters for your interface functions. This may have been contributing to some of the problems you were experiencing. I reconfigured the functionality that you had set up in the example project to use Actors as the parameters, and used message nodes to trigger the events.

Instead of using this:

27325-original.png

I set it up like this:

Using this setup, I was able to play the game and fire projectiles without crashing, and I received a total of four messages each time I fired a projectile: one each from the Character and HUD events, and two from the Projectile event. Compiling either the MyCharacter or MyHUD Blueprints will cause the other to indicate that it is dirty and needs to be compiled, but they will both work fine.

I am not sure if we have done any testing with Blueprint Interface functions taking other Interfaces as parameters. I believe the original intent for Blueprint Interface functions was that they would take Actors as parameters. I have submitted a report to have this investigated further (UE-7920).

Unfortunately, this defeats the purpose of what I was trying to achieve. With the problem of blueprints not doing well supporting circular references, the interface approach was an attempt at getting around those limitations. By passing Actors, you will then have to do the CastTo in the called function, which will re-introduce the circular reference. Also, you have less type safety.

I have not been able to repro the circular reference issue in a small project like SwingNinja. I realize that would make it a lot easier for Epic. It would be great if there was a private support channel available.

I had come up with another way to get around the circular references by putting all the CastTo calls inside blueprint function library calls. This seemed to work, until it didn’t. The compiler just started failing on standalone.

The only thing I have found that reliably works is to avoid blueprints, at least as base classes. I have moved all my base classes to C++. Blueprints only pass C++ base classes around. This completely avoids the inability of blueprints resolving references to other blueprints.

Hi ,

I just wanted to provide a quick update for you on this issue. The report that I had submitted just came back as fixed. I checked it out with our latest internal build and it looks like the developer who worked on it added in a compile error message if an Interface pin is connected directly to an Object pin in a Blueprint.

Now, if you try to connect an Interface pin to an Object pin, such as in the example project you provided from one of the interface event nodes to a Get Display Name node, the connection will include a node to convert the Interface to an Object. This may not be quite what you want, so using a Cast To node here is probably more ideal. I added some Cast To nodes to the sample project you provided and was able to get all four on-screen messages to appear properly when firing, as well as the timed message that appears every 5 seconds. I did not see any crashes at all.

We also have some significant improvements coming to this area of Blueprints specifically in version 4.7. Most, if not all, crashes caused by circular dependencies should disappear.

I’m looking forward to a stable 4.7 to help with the circular reference issues. That was the whole reason for me to try to use interfaces anyway, so in a way that has solved my problem.

But on the topic of a having a robust interface support, I’m not sure if the solution does that or not. It sounds like in order to use an object that supports an interface, I would need to cast to its type first. Since an interface is supposed to provide access to an assorted set of classes that are otherwise not related, this seems like it forces the caller to be able to determine those types, which somewhat defeats the purpose of using the interface. Maybe I don’t quite understand the setup. I’ll have to try it out.