Blueprint instances in level losing data when compiling different blueprint

UE Version: 4.13.0

Problem:

In our level we have a number of instances of a blueprint class M03_InspectionTrigger. If I compile a different, but specific, blueprint class LocationLogic, I lose instance data for instances of M03_InspectionTrigger in the level.

I’ve have been unable to reproduce this bug in a clean project. I’m not sure how we got into this state. There is clearly something strange with our project. Compiling classes other than LocationLogic doesn’t seem to cause any data loss.

Repro:

  1. Open the project.
  2. Open level M03_Game.
  3. Find the actor M03_Iceball within the level. Notice in the actor details the values for the fields called Name, Description, Special Action, Map Name, Interaction Audio, and Name Sleuth Point.
  4. Compile the class LocationLogic.
  5. Force save M03_Game.
  6. Close the UE4 editor.
  7. Open the project again and open level M03_Game.
  8. Find the actor M03_Iceball again and notice all the fields mentioned in step 3 now have default values.

In Closing

Because this is a private project, I am not attaching anything to this bug but will be able to provide a private link to someone from Epic to aid in tracking down this problem.

The only viable workaround we have found is to always shut down the editor after making changes to LocationLogic while making sure to never save our game level in the same editor session.

Hi .Hpe,

Do you have any circular dependencies or references within the project that could be causing this error to occur?

According to the Reference Viewer within the editor, yes.

A little bit more info:

  • Blueprint class, LocationLogic
  • Blueprint class, InspectionTrigger
  • Blueprint class, M03_InspectionTrigger, which inherits from InspectionTrigger.

Data loss ONLY occurs in M03_InspectionTrigger instances, not in instances of InspectionTrigger. When data loss does occur only members of InspectionTrigger lose data, the M03_InspectionTrigger members do not lose data.

In the reference viewer:

  • LocationLogic has a dependency on InspectionTrigger.
  • InspectionTrigger has a dependency on LocationLogic.

The references are because:

  • LocationLogic has a protected member variable that is of type InspectionTrigger.
  • InspectionTrigger has a reference to LocationLogic because functions within that blueprint use a function from our BlueprintFunctionLibrary to get a reference to the currently active LocationLogic instance.

EDIT:

After I posted the above I did some more experimentation, here are my results.

Test 1
Removed code from InspectionTrigger that caused the reference to LocationLogic. Using the reference viewer showed no more circular dependency.

Result of Test 1
Bug DOES NOT repro. Data loss does not occur and everything behaves as expected.

Test 2
Added code to M03_InspectionTrigger to cause a reference to LocationLogic. Now both the parent (InspectionTrigger) and derived class (M03_InspectionTrigger) contain a reference to LocationLogic.

Result of Test 2
Bug DOES NOT repro. Data loss does not occur and everything behaves as expected.

Theory
It appears that if a blueprint B contains a circular reference to blueprint A, and blueprint BC derives from B, but does not reference A, then instances of BC will lose data from members of B anytime A is compiled.

A circular reference, as you are describing, can cause this type of data loss or data reset. Try re-routing the circular dependency to a more linear progression and see if this gives you the same functionality while preventing the data loss.

Thanks for the suggestion. Creating a more linear progression does work, but I don’t like it. Seems like a maintenance nightmare to create extra classes just to wrap methods to prevent a circular dependency. A method I found that I’m going to try using is an interface.

So, now I have:

  • ILocationLogic, which contains all public facing functions.
  • LocationLogic, implements ILocationLogic.
  • InspectionTrigger and M03_InspectionTrigger now reference ILocationLogic.

Doing the interface seems to be sufficient enough to break the tight circular dependency and prevent our data from resetting.

On another note, is this a bug that Epic is working on fixing? Would providing an example project that reproduces this problem help?

Thanks!

This is expected behavior when circular references are present within blueprints. The best course of action is to avoid circular references as much as possible within blueprints. I am happy to hear the interface fixes your error, I will mark this as answered for tracking purposes.

Thank You for Your effort to fix this issue.
However, I look throught some(I think) similar bugs, like: link text
In our project we lost data also, but there is no dependency in reference object from any other objects. This happened extremely rare and I cannot figure out the reproduce steps, but it’s ruin all level setup… Any advice?

Is there any chance (shortcut or sth?) that when I have selected instance at level there is invoking “EditBlueprint->Reset Instance Changes to Blueprint default” ? May be there is sth?

These were similar, but UE-22557 deals specifically with renaming variables within a parent blueprint and UE-21201 is a duplicate of another issue that was resolved in 4.9.2. If you could, can you upload a sample project showing what you have been experiencing? I can see if it is anything else that could be affecting the variables or if this is limited to the circular dependency. In general, it is best practice to avoid circular references, as they bring with them a host of additional issues that are difficult to account for in the long term.