"Editoronly" fields?

I’ve been investigating why our cinemas (UMovieScene objects) are cooking and loading assets that would, in the previous engine, be considered “preview meshes”. Presuming our artists haven’t bunged something up with the data definitions, our scenes have a variety of FMovieSceneSpawnable objects with hard links to UObject pointers to spawn. The spawn can be suppressed at runtime if the FMovieSceneSpawnable was tagged and we bind a runtime actor to it. We called those Proxy actors before. The consequence of these being hard links is that we are cooking and loading extra garbage every time we process one of these cinemas. A lot of garbage. It also throws off the SizeMap tools we use for figuring out how big things should be.

In the old days, we’d have those things as separate fields. Preview Mesh would be an editor-only field, so it would drop out during cook. Editor-only-ness was a property of the old reflection system. In the current situation, you can put a field inside #if WITH_EDITORONLY_DATA, but it looks to me like that only fulfills part of the contract. The cooker still sees it (of course), but it also still considers the thing pointed at a dependency. So it cooks that other thing, something we’d like to not do because we’re trying to reduce cook times, and the SizeMap tools which use the cooker’s dependency data include the pointed at thing.

Have I missed something? Did you set up the data incorrectly? Is there a fix? We’re processing GBs worth of garbage,

I’ve gone quite a bit deeper on this in the last week. I’ve decided what I’m seeing is a bug in FArchiveSaveTagExports::operator<<(UObject*& Obj). It is during the traversals of a base UObject* that we decide what pointed to things are used in game (ie: not editor-only). Operator left shift gets called during Serialize() and has a FArchiveSerializedPropertyChain* that indicates accurately the object is being pointed to by an Editor-only field. I was wrong in my earlier assessment that’s not a known property in the cooker. It knows. It just ignores it – at least under this circumstance? I think it’s used in other places.

Anyway, so you have the property chain. We’re reading a UObject* from an editor-only field. And we queue the discovered UObject for later traversal, by adding it to TaggedObjects array. In a moment, we’ll call ProcessTaggedObjects() and peer into it, but we’ll have lost our FArchiveSerializedPropertyChain. We’ve forgotten that it was editor-only. So when the FArchiveSaveTagImports asks IsEditorOnlyObject(), it gets the wrong answer.

FArchiveSaveTagImports ImportTagger(Linker.Get(), NameMapSaver, ImportsUsedInGame, SoftPackagesUsedInGame, IsEditorOnlyObject(Obj, true /* bCheckRecursive */, true /* bCheckMarks */));

That initializer value feeds into the field named bool bReferencerIsEditorOnly. Because it doesn’t know that, editor-only objects are flagged as being used in-game.

Later on, during save of the cooked .usasset, the field gets skipped. But the dependency evaluation for those fields is wrong. It causes us to cook extra things and the Size Map to attribute them incorrectly to the target disk size.