I make a plugin called Asset Downgrader | Fab and while all my customers are super happy and say it’s a lifesaver plugin I also want to talk about how assets work in unreal.
All assets have an internal list of “custom versions” (epic put this name, not me). These are used to determine how the serialization of data from the binary .uasset files works. To give you an extremely simple example, let’s say we have a StaticMesh “custom version” called SMCV at Version=40 which corresponds to UE4.27, then in UE5.0 this SMCV is incremented to 41 as it added the nanite feature but let’s go a little deeper. You imported a FBX mesh into UE4.27 and it got saved with SMCV Version=40. You then upgrade your project to UE5.0. UE5.0 is backwards compatible, as in it can read files that were saved with SMCV Version <= 41 but, as long as you don’t manually save the mesh with UE5.0, the actual uasset binary data will remain with SMCV Version=40. This may seem counterintuitive as you have the ability to turn nanite on in 5.0. What actually happens is that in memory, in UE5.0 the asset is in an upgraded form and has all the new properties and features of UE5.0. You can even package a project and the mesh will contain the new data, but in that case it will actually save a new cooked uasset that will be put in a .pak file, and this uasset won’t have any version codes at all because it is assumed that they’re all at the same version as the version you packaged with.
Do all new unreal versions increase SMCV ?
Not necessarily. It is only increased (It and all the 80+ custom versions that exist) when something at the serialization level changes, either by being adding or removing data, or some feature changed. So it is possible that 2 unreal versions’ uassets may be compatible with each other but it’s rare.
What happens when you go back to UE4.27 ? Well, if you didn’t manually save the mesh with UE5.0, the SMCV Version didn’t increase, and since UE4.27 can read SMCV Version<=40, the file will be opened without issues. But, what happens if you did manually save the mesh in UE5.0 ? then SMCV Version is 41 and UE4.27 only reads up until 40, so if it sees any custom version (out of the 80+) that is newer than what the engine defines for its current version, it will deny opening the uasset. But Why ? Because it will most certainly crash.
Why the crash ?
If you’re a programmer it’s self explanatory but for anyone else here’s a simplified version : data is read byte after byte, so let’s say my data is 212, the first position meaning length=2 and the rest, the contents, but at version 41 I increased the length to 3 so its 3123. The UE4.27 logic at Version=40 is something like
if Version==39 read one byte->1
if Version==40 read one byte->2
and in UE5.0 the code is
if Version==39 read one byte->1
if Version==40 read one byte->2
if Version==41 read one byte->3
hence, in UE4.27 even though the length is 3 it will stop reading data after 2 bytes instead of 3, and usually after this another set of length/contents follows, and instead of reading the length for the next set it finds the value 3 which is incorrect and then all the data gets scrambled resulting in a crash.
So what really happens when an asset can’t be opened ?
Nothing really, it just won’t show up in the content browser as if the file doesn’t even exist but you’ll get this in the output log
Package is unloadable: %s. Reason: Custom version is too new; the package has newer custom version of %s: Package: %d, HeadCode: %d.
This literally tells you the offending custom version that’s ahead of the current engine version. Unfortunately what it won’t tell you is what unreal version that asset was saved with because unreal won’t write unreal versions in uassets, just the custom versions’ name and value.
Can I find out which custom version belongs to which engine version ?
You can but you need to read engine code for that and even so it’s not obvious because it’s a big enumeration that they keep adding to, so the number is just the count of the enumeration values.
Do custom versions change between patch revisions of the engine ? Like from 5.5.2 to 5.5.3 ?
Usually no, which is why assets between these patch versions are compatible, you can theoretically open with 5.5.2 an asset saved with 5.5.3. There are versions though where there’s like a single change for say ControlRigs, in which case it only affects those asset types so you can’t go back to using the old editor version to open that ControlRig asset.
One time I migrated some assets from a newer engine version to an old engine version and it worked, why ?
That probably happened because of what I described above. You probably had assets created with an older unreal version in the first place, say 4.27, you upgrade to 5.0, then to 5.1 and then when you migrated back to 4.27 or 5.0 they were still openable. Once saved with the newer binary format you can’t migrate to older unreal versions… unless!
I want to be able to migrate assets to older unreal versions, is it possible ?
With my plugin Asset Downgrader, it is. But how ? Well I have a custom engine build of the latest unreal version where I have over 100+ engine modifications in order to write data in that specific old version format. In the case from above where the length of the data gets enlarged in UE5.0, I basically revert that, as is to be expected by UE4.27, so the serialization works and the editor can open the file successfully.