The Unreal Engine 4 from Epic Games is a powerful tool to create any type of game or even application, however the implemented automation and build system is barely documented, if at all. This post will show the necessary steps to build, cook and package a game using the Unreal Automation Tool (UAT) and gives a brief overview over the somewhat hidden tools.
Terminology and Engine Types
Before we can start to delve into the automation system we need to define some terminology. The central tool we are going to use is the Unreal Automation Tool (UAT). This tool is the primary entry point for any sort of automation inside the engine aside from building and packaging an application. The UAT provides commandlets, which are usually a set of commands to be run inside the engine’s ecosystem. The UAT is started using the appropriate script for the underlying operating system (*.sh for linux, *.command for mac and *.bat for Windows), which are located in Engine/Build/BatchFiles. For UAT this would be the RunUAT script. Appending -list returns a list of available commands. More information for UAT can be retrieved using the -help switch. The same applies for each commandlet, just write RunUAT <Commandlet> -help. To get more information and possible switches for this command.
It is important to know on which type of engine the UAT is run. There are three different engine types and they require some changes to the command line depending which is used.
The first and most common engine type for smaller projects is the so called Rocket build. The rocket build is what you get, when you install the engine via the Epic Games Launcher. This is a pre-built, ready-to-use version of the engine. Depending on the choices you select in the launcher, it contains all necessary dependencies to package a project for all desktop applications and mobile targets.
The next type of engine is the source build. This build type is what you get when you clone or download the Unreal Engine repository from GitHub (if you have linked your GitHub account to your Epic Games profile).
This is the most versatile type of engine as the source of the engine can be changed and recompiled. Licensees for console development also get access to extra source code to be compiled in for console support. While this engine type is the most versatile it comes with the cost that everything needs to be compiled, an editor build usually takes from 15-60 minutes, depending on the system used and takes up more than 4 times the size of pre-built engines.
To speed up development for your team one can create an installed build from a source engine. The supported platforms can be chosen upon creating this build. This type is supported starting with 4.13 and can be easily created, see this link for more information. This build is very similar to the rocket build, however it can contain own changes and additional target platforms.
One last tool we need for automatic deployment is the Unreal Build Tool (UBT), which, hence the name, is the main tool for building source code inside the engine. It looks like the UAT is currently meant to be run from inside the editor. When trying to package a project just using the UAT it will fail (on a clean version of the project) because of missing editor dlls of the project. To create the missing dlls we need to use the UBT to build the editor target for our project and we are good to go.
Step 1: Building the Editor Target
Before we can launch the UAT we first need to compile the editor targets for our project to get up-to date versions of our editor dlls. To build those dlls we run the UBT for our project editor target for our operating system (e.g. Win64) in the development configuration:
Build/BatchFiles/Build.bat <ProjectName>Editor Win64 Development <PathToProjectFile>.uproject -WaitMutex
For a clean build either the Clean script can be run before or instead of the build script the Rebuild script can be used. The -WaitMutex switch tells the build tool to wait for the global mutex for this UBT instance. Omitting this switch lets the UBT return with an error if it is currently used elsewhere.
Step 2: BuildCookRun
The complete packaging process is available using the BuildCookRun commandlet inside the UAT. As the name of the commandlet suggests this is a three part process.
- Build: Compile the engine, engine plugins, project plugins and the project itself with all necessary runtime modules which usually creates a single executable file at the end
- Cook: Convert all referenced assets to the respective runtime formats for the target platform (e.g. on Windows convert textures to DDS format), compile still missing shaders, compile Blueprints to their binary representation and strip out any editing information.
- Run: The last step can have a multitude of actions to be performed. In the scope of build automation we usually want to package our assets into pak files and archive the complete project into a folder for further processing (e.g. uploading to Steam). Other features include automatic deployment to connected devices via network or for mobile connected via USB and start the game on the device. These are usually not part in a fully automated process and will not be described here much further.
A complete command line for this process could look like this:
call Engine\Build\BatchFiles\RunUAT.bat" BuildCookRun -Project="<ProjectPath>.uproject" -NoP4 -NoCompileEditor -Distribution -TargetPlatform=Win64 -Platform=Win64 -ClientConfig=Shipping -ServerConfig=Shipping -Cook -Map=List+Of+Maps+To+Include -Build -Stage -Pak -Archive -ArchiveDirectory=<ArchivePath> -Rocket -Prereqs -Package
Let’s go through this one by one:
- BuildCookRun: We want to to use the BuildCookRun commandlet
- -Project=”<ProjectPath>/<ProjectName>.uproject”: Required parameter, absolute path to your uproject file
- -NoP4: We do not want to interact with Perforce during this build (opposite would be: -P4)
- -NoCompileEditor: As far as I know this seems to be broken, omitting this flag should build the editor parts we previously built using the UBT, however at least for me this does not work.
- -Distribution: Mark this build for distribution (especially for mobile platforms creates a distribution package, this usually means using distribution certificates)
- -TargetPlatform=<Platform1>+<Platform2>: For which platforms we want to package (separated with a +)
- -ClientConfig=Shipping: Which configuration we want to package, options are Debug, Development, Test and Shipping
- -ServerConfig=Shipping: Target platform for the server to be build against
- -Cook: We want to run the cook step
- -Map=List+Of+Maps+To+Include: Specific list of map names, separated using a +, to include. If omitted it will use the ones specified in the project settings
- -Build: We want to run the build step
- -Stage: Save the cook result in a staging directory
- -Pak: Use pak files instead of plain file system directories
- -Archive: We want to get a archive the complete output in a directory
- -ArchiveDirectory=<ArchivePath>: The path to archive the project
- -Rocket: We are using an installed/Rocket build
- -Prereqs: Include Unreal Engine Prerequisites installer
- -Package: Create a package for the target platform (e.g. an app file on Mac, apk on Android or ipa on iPhone)
Note that all switches are case insensitive (except for paths on case-sensitive platforms of course).
The above collection of switches and parameters are a solid basis for packaging a ready-to-run application and fully suffice. The next list shows a couple more useful switches to consider:
- -Compile: This switch is usually required on source builds. It tells the UAT to compile itself before running any commandlets, however on Installed/Rocket builds this will result in an error as the sources for UAT are not part of those engine distributions.
- -UnversionedCookedContent: Omit versions in assets, all loaded assets are assumed to be the current version.
- -EncryptIniFiles: Encrypt your ini files, which makes it hard to tamper with them
- -CreateReleaseVersion=<VersionName>: Creates information about this version inside you project folder under Releases, this information can be used for patches and dlc
- -BasedOnReleaseVersion=<VersionName>: This build is based on the given version, used for patches and dlc, to only include new or modified files.
- -Compressed: Compress the pak files for smaller disk usage (and increased loading times)
- -Iterate: Only cook not already cooked items (if running on the same directory as a build before), if omitted it will cook all content
- -CookAll: Cook all content, not only referenced assets
- -CookOnTheFly: Does not cook the content, but starts the cook process in servermode, where a game can connect to using the -FileHostIP=<IP> parameter to connect to this server. The server will then cook requested content on the fly.
- -Run: Start the project after deployment
- -Device=<DeviceName1>+<DeviceName2>: Device name to run the game on (separated with +)
- -NullRhi: Run the game without any render hardware interface (e.g. for running unit tests on headless devices)
- -NativizeAssets: Supported since 4.13, allows C++ code generation from Blueprint scripts
Step 3: Profit!
With all this information it should be easy to successfully integrate the engine deployment into your automation process.
If you happen to use buildbot as your CI/CD framework you may want to take a look at my plugin to simplify interfacing with the UAT from buildbot.