Description

SetPrimaryAssetRules sets the "is overridden" variables (e.g. bOverrideApplyRecursively) based on a comparison with the global default rules:

static FPrimaryAssetRules DefaultRules;
...
	ExplicitRules.bOverrideApplyRecursively = (Rules.bApplyRecursively != DefaultRules.bApplyRecursively);

but GetPrimaryAssetRules applies those overrides to the per-type default rules:

const TSharedRef<FPrimaryAssetTypeData>* FoundType = AssetTypeMap.Find(PrimaryAssetId.PrimaryAssetType);
...
Result = (*FoundType)->Info.Rules;
...
FoundRulesOverride->OverrideRulesExplicitly(Result);

This has the effect that, both for PrimaryAssetRules defined in config for a label, and for a PrimaryAssetLabel's instance values, if the lable sets bApplyRecursively=true that value will be ignored.

This dates back to CL 6631436. The behavior was intended to allow a PrimaryAssetLabel or PrimaryAssetRule to specify that one of its values is "Unset" by leaving that value equal to the default value on the global PrimaryAssetRules. Consider this case:
Default: bApplyRecursively is true and ChunkId is -1
Type: bApplyRecursively is false and ChunkId is 1
Asset override: bApplyRecursively is true and ChunkID is -1.
Prior to 6631436 the value for the asset would be bApplyRecursively true and ChunkID -1 but we want it instead to be ChunkID 1. However bApplyResursively should be true, since in a bool value it is not clear that matching the base value should mean unset.

The value for the asset should be set to true. That is the correct value to use both by the principle of least surprise for boolean overrides and because otherwise there is no other way to set the value of any PrimaryAssetLabel to true if the default value for PrimaryAssetLabels is false.

Suggested fix:
Set the default value used to decide whether an override exists in SetPrimaryAssetRules
to match the default value used in GetPrimaryAssetRules. Make this change config driven so that licensees have a way to turn it off. Add a warning that the turning it off will be deprecated in two releases. Fix up all content on Epic projects that wanted their values to be unset, by making them equal to the global default, and are no longer unset, because the type-specific default has different values than the global default, to change the desired-unset values to be equal to the type-specific default.

Steps to Reproduce

In EngineTest's DefaultGame.ini, override PrimaryAssetTypesToScan's entry for PrimaryAssetLabel and set bApplyRecursively=False.

-PrimaryAssetTypesToScan=(PrimaryAssetType="PrimaryAssetLabel",AssetBaseClass=/Script/Engine.PrimaryAssetLabel,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path="/Game")),SpecificAssets=,Rules=(Priority=-1,ChunkId=-1,bApplyRecursively=True,CookRule=Unknown))

+PrimaryAssetTypesToScan=(PrimaryAssetType="PrimaryAssetLabel",AssetBaseClass=/Script/Engine.PrimaryAssetLabel,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path="/Game")),SpecificAssets=,Rules=(Priority=-1,ChunkId=-1,bApplyRecursively=False,CookRule=Unknown))

Create a PrimaryAssetLabel, set bApplyRecursively = false. Set Priority=999999999. Set ChunkId=1009. Set CookRule=AlwaysCook.

Put this PrimaryAssetLabel in a directory under /Game.
In its specific assets, point it to a new Material using an existing Texture used by a Map under /Game/Maps.

Cook with -manifests.

The Texture should be added into chunk 1009, but it is not, it is still in chunk 0 with the Maps.

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-202315 in the post.

0
Login to Vote

Unresolved
ComponentUE - Foundation - Core - Cooker
Affects Versions5.3
Target Fix5.5
CreatedDec 11, 2023
UpdatedFeb 29, 2024