Assuming the UActorComponent you created as part of the repro steps is named UTestComponent.
As far as I can tell, the flow behind this data loss is:
- FBlueprintCompilationManageImpl::FlushCompilationQueueImpl creates a FBlueprintCompileReinstancer, and its constructor calls FBlueprintCompileReinstancer::MoveCDOToNewClass. which duplicates the UBlueprintGeneratedClass. The UBlueprintGeneratedClass::InheritableComponentHandler is duplicated, but the UTestComponent template that it stores as one of its `Records` is not, because of the comment on `KismetReinstanceUtilities.cpp:2055`, where any RF_ArchetypeObject owned by the class are moved temporarily to the transient package and renamed.
- In the following call stack: FBlueprintCompilationManageImpl::FlushCompilationQueueImpl -> FKismetCompilerContext::CompileClassLayout -> UInheritableComponentHandler::ValidateTemplates, the template for UTestComponent is invalidated, and renamed, this also affects the template in the duplicated REINST class (as this object was NOT duplicated in 1.)
- When the actor in level is rebuilt, FComponentInstanceDataCache::ApplyToActor is called, but FActorComponentInstanceData::MatchesComponent fails when restoring the custom value to the component variable, because its name is something like TestComponent_SOMENUMBER, instead of TestComponent_GEN_VARIABLE.
- Data is lost
EDIT: Looks like this doesn’t occur immediately, but at some point when ValidateTemplates happens, there is an old template still outer’ed to the transient package (with flag RF_MirroredGarbage) which prevents the template from getting the same correct name (TestComponent_GEN_VARIABLE), which kicks off the whole bug.
I’ve also tried calling ValidateTEmplates() on the duplicate class, but it immediately empties the UInheritableComponentsHandler::Records array because all the templates have the wrong (non-REINST) owner class (although this *does* fix the bug, and those records seem to get regenerated correctly anyways)