Sporadic build error when running a Multi Process Cook

Hi! I’ve taken over to root cause a sporadic build failure that was originally reported here: [Content removed]

We’ve been unable to ever catch this issue in a debugger but, after some investigation, I believe this is happening as a result of an engine change our team made to address this issue: https://forums.unrealengine.com/t/skeletal-mesh-ref-skeleton-still-not-properly-initializing-virtual-bones/2570324

The change our team made within `USkeletalMesh::Serialize` can be seen with the <RGI> tags here.

if (Ar.IsLoading())
{
 	// <RGI> #VirtualBoneInit 5.4-5.6 bugfix: https://issues.unrealengine.com/issue/UE-289881
	USkeleton* MeshSkeleton = GetSkeleton();
 
	 if (MeshSkeleton)
	 {
		 MeshSkeleton->ConditionalPostLoad();
	 }
	 // </RGI>
 
	 const bool bRebuildNameMap = false;
	 GetRefSkeleton().RebuildRefSkeleton(GetSkeleton(), bRebuildNameMap);
}

which sometimes results in the failed ensure for the skeleton in ConditionalPostLoad if it still has RF_NeedLoad.

I’m not super familiar with either UE’s load patterns nor with this virtual bone init issue so I wanted to ask if you have any recommendations for how to proceed? I see that Jamie Hayes and Danny Couture made some changes in skeletal mesh serialization relating to async loading and the parallel loading thread. Should we trying pulling those changes early?

[Attachment Removed]

That code is definitely invalid. The serialize function can only be used for the object currently being deserialized to apply transformation on. You can’t poke other objects, and you can’t postload them since they could still be in an unserialized state.

Having said that, the code on our side is also invalid, I’ll contact the owner to see why this hasn’t been made in the postload step instead

I recently published an article that describes the different constraints of the loader.

https://dev.epicgames.com/community/learning/knowledge\-base/7Oxm/mastering\-async\-loading\-in\-unreal\-engine

[Attachment Removed]

Ty! That’s a very helpful article. I am not surprised that Serialize shouldn’t be accessing data external to the object.

Locally, I have modifications that remove that entire block (including the RebuildRefSkeleton call) from Serialize and adds this to ::PostLoad

// <RGI> #VirtualBoneInit 5.4-5.6 bugfix: https://issues.unrealengine.com/issue/UE-289881
if (USkeleton* MeshSkeleton = GetSkeleton())
{
	MeshSkeleton->ConditionalPostLoad();
 
	const bool bRebuildNameMap = false;
	GetRefSkeleton().RebuildRefSkeleton(MeshSkeleton, bRebuildNameMap);
}
// </RGI>

I have been unable to repro the Multiprocess Cook issue nor the virtual bone issue with these changes. Please let me know if you think this is the right course of action.

(I believe the call to RebuildRefSkeletonNameToIndexMap within Serialize is also incorrect but is irrelevant to us due to its condition)

[Attachment Removed]

Hi Joe,

Yes, that’s exactly what I will suggest to the team in charge of skeleton meshes.

[Attachment Removed]

Hi Joe,

The team made the fix and they moved the code to postload.

Change is in UE5/Main at 50892441.

Thanks for reporting this. You helped make UE better!

All the best,

Danny

[Attachment Removed]