I’m attempting to assign new PrimaryAssetType rules for assets that previously were covered by a different rule to change some settings for these. However, the Old rule is still counted as a Valid rule (because it’s a valid rule, just not for this asset) and the AssetManager just reads it as a conflict instead of updating the rules.
Steps to Reproduce
Assign a new PrimaryAssetType in DefaultGame.ini
Save an asset of this type in the editor
Change the PrimaryAssetType’s Name in DefaultGame.ini
Ignoring PrimaryAssetType New - Conflicts with Old - Asset: Asset
Create a data asset. In our case a MissionConfig
Create a PrimaryAssetType entry in DefaultGame.ini
+PrimaryAssetTypesToScan=(PrimaryAssetType=“MissionConfig”,AssetBaseClass=“/Script/Project.MissionConfig”,bHasBlueprintClasses=False,bIsEditorOnly=False,Directories=((Path=“/Game/Missions/MissionData”),(Path=“/Game/Nonshipping”)),SpecificAssets=,Rules=(Priority=-1,ChunkId=-1,bApplyRecursively=True,CookRule=AlwaysCook))
Make a MissionConfig asset in the Game/Nonshipping folder
Now, in DefaultGame.ini, update your PrimaryAssetTypesToScan.
In my case, I added this new rule and removed the Nonshipping path from the previous rule, but also found this holds true if you remove the previous rule and just add this one. (I suspect it originally worked because the original rule PrimaryAssetType matches the AssetBaseClass class name. The new PrimaryAssetType name should not match the class name)
+PrimaryAssetTypesToScan=(PrimaryAssetType=“MissionConfigNonshipping”,AssetBaseClass=“/Script/Project.MissionConfig”,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path=“/Game/Developers”),(Path=“/Game/Nonshipping”)),SpecificAssets=,Rules=(Priority=-1,ChunkId=-1,bApplyRecursively=True,CookRule=Unknown))
Notice your logs
Display: Ignoring PrimaryAssetType MissionConfigNonshipping - Conflicts with MissionConfig - Asset: MissionMapTemplate_Mission_DA
Additional info: the PrimaryAsset is a data asset of some sort
Now, I did some digging.
When launching, there’s an AssetDataGatherer that loads from the AssetRegistry cache / peeks at the serialized data in the asset itself for PrimaryAssetType. Then the results of this get saved back to the cache.
This is where the Igorning PrimaryAssetType message occurs.
This happens because the serialized data has a properly formed PrimaryAssetId, but not one defined for the AssetManager. It evaluates as IsValid() even if it’s not defined for the system. This is a bug imo.
Afterwards, the AssetManager system processes the rules for PrimaryAssetTypes and Broadcasts. This broadcast does not update the cache afaik.
Then, on Saving the data asset, we call GetPrimaryAssetId and UPrimaryDataAsset::GetPrimaryAssetId() doesnt ask the AssetManager what it’s PrimaryAssetId is, it instead
// Data assets use Class and ShortName by default, there’s no inheritance so class works fine
return FPrimaryAssetId(GetClass()->GetFName(), GetFName());
which is what gets serialized into the data asset. This is another bug. (This is the only reason the rule that shares the name with the class works properly)
The combination of both the first bug and second bug means you keep getting errors about not using the correct primary asset type because one system is ignoring the AssetManager and asking the Asset itself and the Asset is also ignoring the AssetManager and just providing it’s own made up rule.
Could you provided us with more detailed repro steps along with the error messages / function names where the errors happened?
Thank you for providing more info and for the detailed repro steps.
“Asset is also ignoring the AssetManager and just providing it’s own made up rule”
This is how the system is meant to work by default, it’s not a bug. bShouldManagerDetermineTypeAndName changes that behavior and makes the Asset Manager try to guess the type if it isn’t saved into the asset.
With the default rules, the asset decides what its type is, and the Asset Manager is subordinate to that and just queries it.
What type is reported by GetPrimaryAssetId?
FPrimaryAssetId(GetClass()->GetFName(), GetFName());
Which is the class name. Sometimes it happens to line up with an existing rule in DefaultGame.ini and sometimes it doesn’t.
My issue is when there is a rule defined in DefaultGame.ini and instead of using the rule I explictly made to handle it, it’s just using itself.
If you say it’s intended, then that’s fine. I’ve already changed the behavior in our code base to behave consistently with our expectations, since setting up rules explicitly feels like it should override default behavior to me.
Understood. Let me know if you encounter any more issues.