How to correctly version the engine for asset saving

Hey, I’m looking for guidance on versioning distributed engine versions

We’re currently using an installed engine build using the BuildGraph instructions here: https://dev.epicgames.com/documentation/en\-us/unreal\-engine/installed\-build\-reference\-guide\-for\-unreal\-engine

But this installed engine build doesn’t have a valid CL (0), which causes all of our assets to save with empty version, and then our builds get flooded with “Asset [X] has been saved with empty engine version” warnings

There’s an Update Version Files step in the BuildGraph, but it seems to be excluded for installed engine builds (Unless I’m misunderstanding the BuildGraph flow)

<Aggregate Name=“HostPlatforms_Win64” Label=“Builds/Win64” Requires=“Make Installed Build Win64” Exclude=“Update Version Files”/>

We build the installed engine build using:

“/Engine/Build/BatchFiles/RunUAT.bat BuildGraph -target=`“Make Installed Build Win64`” -script=`“Engine/Build/InstalledEngineBuild.xml`””

Is there something we’re missing in the build graph set up which would allow us to set an engine version? Additionally, should we be marking the engine as a licensee version when building our own distributed engine version?

There’s documentation here that talks about an UpdateLocalVersion commandlet, is the idea that we run that before running the Make Installed Build BuildGraph command?

[Attachment Removed]

Hi!

The exclude for the HostPlatforms_Win64 aggregate in InstalledEngineBuild.xml has been there since UE4 times, so I’m not quite sure why it was introduced.

I don’t think the aggregate should be used by default when building the “Make Installed Build Win64” node directly.

The regular Update Version Files node only runs if run on a build machine (e.g. if -BuildMachine is specified) and would retrive the CL from the perforce repository.

You can try running the BuildGraph command with the -ListOnly parameter to see if it is included in the graph (although it might show up and just be a no-op on a non-buildmachine).

As for the intended way to set the version:

In development we usually set the version names after syncing a repository from perforce through external tools.

For example, UnrealGameSync will write to Build.version after syncing a changelist and the InstalledEngineBuild will also grab the CL from perforce if run on a build machine.

For distribution builds the relevant changelists are set manually before building the installed build.

You can use the UpdateLocalVersion UAT command to write this file with information you manually specify or the changelist will be read from perforce, if available. This is specifically a UAT command and does not require an editor build to run like a commandlet would.

These are the parameters for the UpdateLocalVersion call:

[Help("Updates your local versions based on your P4 sync")]
[Help("CL", "Overrides the automatically disovered changelist number with the specified one")]
[Help("CompatibleCL", "Overrides the changelist that the engine is API-compatible with")]
[Help("Promoted", "Value for whether this is a promoted build (defaults to 1).")]
[Help("Branch", "Overrides the branch string.")]
[Help("Licensee", "When updating version files, store the changelist number in licensee format")]

You would use the licensee flag if you have your own perforce server where the changelist numbers differ from what Epic uses (usually they would be smaller than ours and without that flag the Engine would assume any assets saved with such a small number are from an older version.

If your engine changes don’t break compatibility it is usually a good idea to set CompatibleCL to the engine CL you are based on, to keep the assets compatible with vanilla engine builds.

Kind Regards,

Sebastian

[Attachment Removed]

> Given that the Github release branch ships with CL 0, how do we find what the matching Perforce CL is to set it to match?

> Is it a matter of setting the Changelist to the CompatibleCL which ships in Build/Build.version?

What I meant was that CompatibleChangelist should be set, especially if you set the regular Changelist to 0 or to a custom number from your Perforce.

So the Changelist itself can be 0, but the CompatibleChangelist should be set to the corresponding Perforce CL.

This is how we have it set up in the Build.version of our release branches on Github.

It is however set to 0 for the ue5-main branch, I think we wanted to avoid having to change the Build.version file with every single CL.

[Attachment Removed]

Hi,

I will start by mentioning that the zero version warning can be turned of. You need to add the following in DefaultEngine.ini of the project:

[Core.System] 
ZeroEngineVersionWarning=False

Now, the fact that you are not using Perforce is adding a bit of friction but should not prevent from using the system. Change lists in Perforce in this case can be summarized as an integer that keeps growing. You can to “fake” versioning using the structure that you proposed in your last post.

  • Changelist -> Using a build number for that field is fine as long as it always grow
  • CompatibleChangelist -> Is is used to validate the editor\plugin saved content and is not required in a licensee build
  • IsLicenseeVersion -> tells the engine that you want to use yours custom Changelist number. This CL number doesn’t have to be greater than the version we used to save the editor and plugin assets

The usual goal of having the “engine version” check is to detect that a user is running an old build that might be missing some new code to load some assets. The editor will refuse to load data saved by a more recent editor which is a signal for users to update their Installed Builds.

Regards,

Martin

[Attachment Removed]

Hey Sebastian

> If your engine changes don’t break compatibility it is usually a good idea to set CompatibleCL to the engine CL you are based on

Given that the Github release branch ships with CL 0, how do we find what the matching Perforce CL is to set it to match?

Is it a matter of setting the Changelist to the CompatibleCL which ships in Build/Build.version?

Also, if that’s usually a good idea, why does github not ship with that CL?

[Attachment Removed]

I’m taking over this issue from Darcy and have some follow up questions.

Firstly, I want to make sure it’s clear that we are not using Perforce which might be making this slightly more difficult than you’re expecting.

I looked at the UAT UpdateLocalVersion task but it is essentially a no-op if p4 isn’t enabled (which we of course disable with -nop4). I looked at the functionality, and it seems that after gathering all of the values (either passed to the task or pulled from P4) it will write the build.version file. (Side note: It seems strange that this task requires P4 since it supports most/all options as parameters and the logic is guarded to not access p4 if it doesn’t need, but then it just doesn’t write if p4 isn’t enabled).

Because build.version is a json file I tried to load, modify, and save the file in our CI before calling “Make Installed Build Win64”, but even after confirming that the file is updated correctly, the build.version from the produced install build does NOT contain the modifications that I made. It’s currently unclear why to me. Do you have an idea why, or if there is an alternate approach we should be using to update this file as part of the build graph?

For clarity, this is format of build.version and the changes we’re trying to make and the reasoning behind them. Does it look correct?

{

“MajorVersion”: 5, -> Unchanged

“MinorVersion”: 6, -> Unchanged

“PatchVersion”: 1, -> Unchanged

“Changelist”: 0, -> “build number” from our source control server

“CompatibleChangelist”: 43139311, -> Set to 0 as this is a Licensee version. Following the comment in StaticUpdateVersionFiles -> if(bIsLicenseeVersion != Version.IsLicenseeVersion) Version.CompatibleChangelist = 0; // Clear out the compatible changelist number; it corresponds to a different P4 server.

“IsLicenseeVersion”: 0, -> Set to 1

“IsPromotedBuild”: 1, -> Unchanged

“BranchName”: “Unknown” -> Give sensible name

}

And finally, I’m looking to clarify the setting of Changelist vs CompatibleChangelist. The primary goal we’re looking to solve with “fixing” how we build the engine is to resolve warning logs in our builds saying “Asset has been saved with empty engine version. The asset will be loaded but may be incompatible”. Looking at the code, it seems this happens when the engine has the Changelist set to 0, so based on my understanding it seems like we would want to set Changelist to a non-0 value so it will get written out into the assets and not trigger this warning?

[Attachment Removed]