Unreal Engine AngelScript build and distribution¶
Purpose¶
This page turns the successful local UE AngelScript 5.8 bring-up into a
repeatable internal toolchain pipeline. The desired deliverable is an Unreal
Installed Build archived as a portable .7z, plus a registration script
and checksum. It also records the separate Linux Installed Build used to make
the build-only container for Jenkins dedicated-server jobs. A normal source
checkout with compiled binaries is useful for engine development but is not
the distribution artifact.
Upgrade-specific source and plugin findings are in the UE AngelScript 5.8 upgrade. Project release gates remain in the release checklist.
Pinned inputs¶
Record these inputs in every engine artifact manifest:
| Input | Current verified value |
|---|---|
| Engine repository | Hazelight UnrealEngine-Angelscript |
| Engine branch | angelscript-master |
| Engine commit | f347f57f05e992976b6c2be6612303b7e8099502 |
| Reported engine version | 5.8.2 |
| Host platforms | Win64; Linux x86-64 in local WSL 2 |
| Wwise integration | 2025.1.10.9233.4458, project-level |
| Wwise SDK | 2025.1.10.9233, project-level |
Do not publish an artifact identified only as “latest.” The commit and plugin versions are needed to reproduce crashes, ABI mismatches, and project build results.
Stage 1: source checkout and dependencies¶
Use a fresh directory on a volume with ample free space. Authenticate GitHub for the Epic and Hazelight repositories before starting; never put a token in a script or document.
$EngineRoot = "T:\UnrealEngine-Angelscript"
git clone https://github.com/Hazelight/UnrealEngine-Angelscript.git $EngineRoot
git -C $EngineRoot switch angelscript-master
git -C $EngineRoot rev-parse HEAD
& "$EngineRoot\Setup.bat"
& "$EngineRoot\GenerateProjectFiles.bat"
& "$EngineRoot\Engine\Build\BatchFiles\BuildUBT.bat" quiet
Setup.bat downloads a large dependency payload. Redirect it to a log and
probe the tail sparsely rather than streaming progress into automation output.
Treat a completed dependency update, Git-hook registration, and prerequisite
installation as the expected end state.
The Git checkout does not contain generated UnrealBuildTool host binaries.
BuildUBT.bat must publish both UnrealBuildTool.dll, used by normal batch
files through dotnet, and UnrealBuildTool.exe, used directly by the
Installed Build graph on Windows. The local bootstrap has a Win64 self-healing
check for both files because upstream UE 5.8 checks only the DLL and can report
"up-to-date" after the EXE has been removed.
Before starting BuildGraph, also confirm that the Windows SDK's Debugging
Tools for Windows component is installed. The graph uses
Windows Kits\10\Debuggers\x64\pdbcopy.exe to strip private symbols.
Stage 2: build the development engine¶
Build the editor and shader worker explicitly:
& "$EngineRoot\Engine\Build\BatchFiles\Build.bat" `
UnrealEditor Win64 Development `
-WaitMutex -NoHotReloadFromIDE -Progress
& "$EngineRoot\Engine\Build\BatchFiles\Build.bat" `
ShaderCompileWorker Win64 Development `
-WaitMutex -Progress
The current baseline completed both commands successfully. Launch
UnrealEditor.exe once as a smoke test and confirm normal module loading and
asset-registry initialization. A deliberately terminated smoke launch may not
write a UBT-style Result: Succeeded line, so retain the process exit decision
and log tail together.
Stage 3: install engine-wide Marketplace tools¶
Copy only editor-wide plugins that are intended to be available to every
project into Engine/Plugins/Marketplace. The current set is:
- Auto Size Comments
- Blockout Tools
- Blueprint Assist
- Electronic Nodes
- Tab Restore
Use the canonical UE 5.8 Marketplace copies as source. Exclude stale
Binaries, Intermediate, and Saved directories when source is available,
then compile the plugins against the AngelScript editor. A temporary plugin-host
project that explicitly enables the set is a practical way to force their
modules into one editor build.
Do not move maintained project plugins into the engine merely to satisfy a build. Their authoritative location is described in the upgrade record.
Engine plugins present beneath Engine/Plugins, including the maintained
Engine/Plugins/Marketplace set, are discovered by the Installed Build graph.
The editor's -precompile -allmodules pass compiles their eligible Win64
modules, and the graph copies their descriptors, content, resources, and build
products into the Installed Build. The current build log confirms discovery of
Auto Size Comments, Blockout Tools, Blueprint Assist, Electronic Nodes, and Tab
Restore.
Project plugins are intentionally different: plugins beneath Tank Game
5.8/Plugins are not embedded in the engine archive. They remain part of the
project checkout and compile against the distributed engine.
Stage 4: validate the project against the source engine¶
Create or regenerate a local .uproject association for the custom engine,
then build focused plugin modules while resolving migration errors. After the
focused builds succeed, run clean full-target validation.
The current focused build evidence covers:
- the 19-module initial project-plugin selection;
- Journeyman's Minimap after the final local-patch merge;
- the four matching Lyra plugins;
- all requested Wwise integration modules;
- Nakama after the editor teardown fix.
This stage proves compatibility of the touched modules. It does not replace a clean project build and cook.
Stage 5: create the Installed Build¶
Epic's BuildGraph script at Engine/Build/InstalledEngineBuild.xml creates the
launcher-like binary engine distribution. The repository wrapper performs the
UBT and PDBCopy preflight, builds and stages UnrealVersionSelector, and pins
the artifact to Development-only Win64, without a prebuilt DDC or full debug
symbols. The local graph also defines WithPDBs; the wrapper pins it to false
so native editor, game, plugin, and tool PDBs are excluded from the staged
Installed Build:
$EngineRoot = "T:\UnrealEngine-Angelscript"
$InstalledOutput = "T:\UE-AS-5.8-Installed"
& "$EngineRoot\Engine\Build\BatchFiles\BuildInstalledASWin64.bat" `
$InstalledOutput
The wrapper sets GameConfigurations=Development. Do not remove that setting
for the internal developer artifact: BuildGraph otherwise also precompiles
Shipping and DebugGame game targets.
WithFullDebugInfo=false is not sufficient to produce the small artifact.
Epic's UE 5.8 filter deliberately exempts UnrealEditor*.pdb from stripping,
which retained approximately 131 GiB of native editor symbols in the first
Installed Build. When WithPDBs=false, the local graph adds recursive PDB
patterns to CopyInstalledExceptions. BuildGraph then omits those native PDBs
and sanitizes their build-product entries from the staged target receipts.
The C# tools are staged through a separate CsTools copy path. Their portable
.NET PDBs remain intentionally: they are small and do not contain the native
engine symbols that dominated the distribution. Call this output
symbol-light, rather than claiming that it contains no files with a .pdb
extension.
With the explicit BuiltDirectory, the distributable root is expected beneath:
T:\UE-AS-5.8-Installed\Windows
Without that override, this engine's graph defaults to
LocalBuilds/Engine/Windows beneath the source checkout.
Set WithServer=true or WithClient=true only when the distributed engine must
contain those precompiled target types. Add DDC and full debug information only
when their download-size and storage cost are justified.
Incremental-build policy¶
The normal distribution command must not include BuildGraph's -clean
argument. Preserve the source tree's Engine/Binaries and
Engine/Intermediate so UnrealBuildTool can reuse unchanged outputs and
compile only affected engine or plugin modules.
BuildGraph completion markers are a separate cache beneath
Engine/Saved/BuildGraph. A normal invocation starts a new graph evaluation.
When retrying an interrupted or failed run with the same engine revision,
plugins, wrapper, output directory, and graph settings, resume it explicitly:
& "$EngineRoot\Engine\Build\BatchFiles\BuildInstalledASWin64.bat" `
$InstalledOutput -Resume
-Resume retains completed BuildGraph nodes and continues from the failed
node. Do not use it after changing the engine revision, plugin set, target
configurations, or graph arguments; stale completion markers can otherwise
skip work belonging to the new artifact.
Use the same Installed Build staging directory for routine updates. BuildGraph
may still recopy or strip files into that directory, and producing a normal
.7z recompresses the complete archive, but those publication steps do not
require recompiling the whole engine.
Use -clean only when one of these conditions is explicit:
- build outputs are corrupt or incompatible;
- a toolchain or SDK change invalidates the existing intermediates;
- a deliberately clean release-candidate build is required;
- incremental behavior is itself under investigation.
Warn developers before a clean Installed Build. Its cleanup nodes remove the
source checkout's compiled editor binaries, including UnrealEditor.exe, before
rebuilding them. Interrupting after cleanup can therefore leave the source
editor unavailable until compilation and linking complete.
The first Installed Build can still be substantially larger than a normal
incremental editor build because the graph precompiles all eligible modules and
its required editor/tool targets. Game targets are limited to Development by
the wrapper. Once that baseline has completed, subsequent distribution builds
should remain incremental unless -clean is supplied or build inputs
invalidate the cache.
Stage 6: validate the Installed Build¶
Do not archive immediately after BuildGraph returns. Validate the output as if it were on a developer machine with no source-tree fallback:
- confirm
Engine/Build/InstalledBuild.txtexists; - launch
Engine/Binaries/Win64/UnrealEditor.exefrom the Installed Build; - confirm the five expected Marketplace plugin descriptors and Win64 module
binaries exist beneath
Engine/Plugins/Marketplace; - confirm the editor remains alive through normal module and asset-registry initialization.
The initial engine-distribution smoke test intentionally does not open or build Tank Game. Project compilation, Blueprint validation, maps, Game Features, cook, and packaging are separate project release gates.
The Development-only Installed Build completed successfully on 2026-09-12. Its
editor-only smoke launch reported Installed Engine Build: 1, reached the end
of engine initialization, completed the initial asset-registry scan, and
remained alive until the test process was deliberately stopped. All five
Marketplace plugin descriptors and their Win64 module DLLs were present.
A fresh-output symbol-light pipeline test also completed successfully on
2026-09-12 at T:\UE-AS-5.8-Installed-NoPDB-Test\Windows. AutomationTool
reported 17 minutes 56 seconds. This is a warm-cache incremental pipeline
measurement after the engine had already been built, not a clean-clone build
time. The run still relinked the complete 2,327-action editor module set before
staging 250,998 files.
The resulting tree was 36.86 GiB. It contained no native PDBs and no .pdb
references in staged .target receipts. The only remaining PDB files were 405
managed symbols beneath Engine/Binaries/DotNET/AutomationTool and
Engine/Binaries/DotNET/UnrealBuildTool, totaling 73.43 MiB. This result is
accepted as the internal symbol-light baseline.
Do not pass -NoShaderCompile to this smoke test. In UE 5.8 it leaves the
shader-compilation manager unavailable while editor analytics queries shader
statistics during FUnrealEdMisc::OnInit, producing a TNotNull fatal after
the engine-init milestone. That failure is caused by the test flag, not by a
missing Installed Build file. -NullRHI -Unattended -NoSplash -NoSound is the
verified headless smoke-test argument set.
Temporarily rename or disconnect the source-engine directory during the final smoke test if necessary to prove that no path silently falls back to it.
Stage 7: create the portable artifact¶
Archive the entire Installed Build root, not selected binary folders:
$Version = "5.8.2-AS-f347f57f"
$InstalledRoot = "T:\UE-AS-5.8-Installed\Windows"
$Artifact = "T:\Distributions\UE-$Version-Win64.7z"
7z a -t7z -mx=7 $Artifact "$InstalledRoot\*"
Get-FileHash $Artifact -Algorithm SHA256 |
Format-List Algorithm, Hash, Path
Publish beside the archive:
- a SHA-256 checksum;
- an artifact manifest containing the pinned inputs above;
- concise extraction and registration instructions;
- known limitations, such as omitted symbols, DDC, or target platforms.
The .7z is portable filesystem content. It intentionally does not carry
Windows registry state.
Stage 8: register the portable engine on Windows¶
Each developer registers the extracted absolute path once. The version selector stores custom installations under:
HKCU\Software\Epic Games\Unreal Engine\Builds
Use a stable identifier beginning with a digit so the selector displays it as a
release label. A RegisterEngine.bat placed at the archive root can contain:
@echo off
setlocal
set "ENGINE_ROOT=%~dp0"
if "%ENGINE_ROOT:~-1%"=="\" set "ENGINE_ROOT=%ENGINE_ROOT:~0,-1%"
reg add "HKCU\Software\Epic Games\Unreal Engine\Builds" ^
/v "5.8-AS" /t REG_SZ /d "%ENGINE_ROOT%" /f
"%ENGINE_ROOT%\Engine\Binaries\Win64\UnrealVersionSelector-Win64-Shipping.exe" ^
-register -unattended
endlocal
Registration provides the .uproject shell integration used by Switch Unreal
Engine version, project-file generation, and editor launch. The registry value
contains an absolute path; rerun the script after moving the extracted engine.
After selection, a project associated with the named build uses:
"EngineAssociation": "5.8-AS"
Avoid committing a machine-specific GUID from a local custom-engine registration
when the team has adopted the stable 5.8-AS identifier.
Linux build-only container pipeline¶
Portable producer/consumer contract¶
The container pipeline deliberately separates artifact production from runtime acceptance. These are portable roles; they are not tied to a particular workstation, CI controller, registry, or transfer mechanism:
| Role | Responsibilities | Required evidence |
|---|---|---|
| Producer host | Build the pinned Linux Installed Build, assemble the build-only image, export or push an immutable artifact, and record its identity and checksum or digest. | Successful BuildGraph log; structurally valid Docker/OCI artifact; image tag plus checksum or digest; documented inputs and omissions. |
| Execution host | Import or pull the artifact, run it with the required mounts/resources, and perform the real project build under CI. | Successful image import/pull; engine-contract check inside the container; successful project BuildCookRun; archived output and CI log. |
The producer does not need to load or run the finished image locally, and a local project build is not a publication gate. Conversely, structural archive validation on the producer does not prove that the image runs or that project plugins compile. Runtime and real-project acceptance belong to the execution host.
The transferable handoff may be any archive format that the execution host can
import directly, or a registry reference. For the current livingpc deployment
the selected handoff is:
- an OCI v1 archive plus a cryptographic checksum, imported into Docker's
mobycontainerd namespace withctr; or - a Docker-compatible archive plus a cryptographic checksum; or
- an immutable registry reference pinned by digest.
Do not introduce a registry solely for this pipeline when an authenticated, checksummed archive transfer is simpler. Regardless of transport, never select a new image for production CI until the execution-host acceptance gate passes.
Required container and CI contract¶
The Tank Game Jenkins deployment on livingpc was initially inspected as a
reference implementation. Jenkins TankGame build #508 later verified the UE 5.8
image and server pipeline, with temporary project-source compatibility patches
described in the Linux server build. livingpc is not
a required destination. Any compatible CI deployment must select the engine
through a versioned image reference and launch it with two writable/accessible
mounts:
- the checked-out project at
/project; - the archived server output at
/out.
The engine image must therefore contain a complete build-capable Linux Unreal
tree at /home/ue4/UnrealEngine. The current UE 5.6.1 reference image runs as
the non-root ue4 user, uses /home/ue4/UnrealEngine as its working directory,
and is based on Ubuntu 22.04. The effective build command is:
/home/ue4/UnrealEngine/Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \
-project=/project/Metal_terra.uproject \
-platform=Linux \
-server \
-serverconfig=Development \
-noclient \
-build \
-cook \
-stage \
-pak \
-archive \
-archivedirectory=/out
Do not bake the project checkout, output, Git credentials, CI credentials, or deployment-specific secrets into the image. The execution host supplies the project and output as mounts, and the engine image remains an independently versioned, transferable toolchain.
For the project-facing Jenkins procedure, repository boundaries, compatibility gates, and later production verification, see the Linux server build. This page remains authoritative for creating and transporting the engine artifact itself.
Tank Game requires this UE 5.8 server target at
Source/Metal_terraServer.Target.cs:
using UnrealBuildTool;
public class Metal_terraServerTarget : TargetRules
{
public Metal_terraServerTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Server;
DefaultBuildSettings = BuildSettingsVersion.V7;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_8;
ExtraModuleNames.AddRange(new[] { "Metal_terra" });
}
}
This target compiled successfully in the isolated Linux proof of concept.
Put Linux source and compilation on the WSL filesystem¶
Run the Linux build inside WSL's native ext4 filesystem, not directly beneath
/mnt/t. A shallow local clone pins the Linux worktree to the same committed
engine revision without transferring full Git history:
git clone --no-hardlinks --depth 1 \
file:///mnt/t/UnrealEngine-Angelscript \
/home/cha/ue-as-5.8-linux-src
cd /home/cha/ue-as-5.8-linux-src
git rev-parse HEAD
./Setup.sh --force
./GenerateProjectFiles.sh
This method clones committed content only. Uncommitted Windows graph changes,
generated binaries, and Engine/Plugins/Marketplace copies are not silently
carried into the Linux tree. That is desirable for the current Jenkins image:
Tank Game's maintained runtime plugins remain in the project checkout, and its
.uproject does not explicitly require the five editor-only Marketplace
plugins. Copy any future engine-level Linux plugin dependency explicitly and
record it in the image manifest.
Setup.sh downloads a large dependency payload. Redirect its output and probe
only a short tail. If a prior dependency download was interrupted, rerun with
--force; without it, GitDependencies may stop for overwrite confirmation.
The successful setup ended with No third party libs needed to be built
locally and Setup successful. Project-file generation then completed in
57.71 seconds.
WSL storage failure and recovery finding¶
Move the WSL distro to T: before downloading or compiling if the default
C: volume lacks substantial headroom. During the first attempt, the Ubuntu
VHD grew until C: had only 2.35 GiB free. GitDependencies then exited with a
bus error and subsequent WSL operations reported filesystem I/O failures. This
was a storage failure, not an Unreal dependency failure.
The normal relocation command is:
wsl.exe --terminate Ubuntu
wsl.exe --shutdown
wsl.exe --manage Ubuntu --move T:\WSL\Ubuntu
Run it from an appropriately privileged shell and do not interrupt it while the
destination VHD timestamp is advancing. On this machine the copy completed but
the final registration step returned Wsl/Service/MoveDistro/E_ACCESSDENIED.
The VHD was already on T:, while WSL still cached its old path. Recovery
required all of the following safeguards:
- preserve a registry export of the Ubuntu distribution registration;
- verify the destination
ext4.vhdxexists and the old VHD does not; - repair the distribution
BasePathtoT:\WSL\Ubuntu; - retain a compatibility junction from the exact old distro folder to the new folder until the WSL service reloads its registration;
- verify
WSL_OK, the source directory, anddf -hbefore resuming setup.
That recovery is machine-specific. Prefer a successful supported wsl
--manage --move or export/import workflow on other hosts; never unregister a
distro until a verified export or VHD copy exists.
Create the Linux Installed Build¶
Validate graph selection first by appending -ListOnly to the command below.
HostPlatformOnly=true did not suppress Linux ARM64 in this UE 5.8 graph,
so WithLinuxArm64=false is required for an x86-64-only build:
cd /home/cha/ue-as-5.8-linux-src
./Engine/Build/BatchFiles/RunUAT.sh BuildGraph \
-script=Engine/Build/InstalledEngineBuild.xml \
-target="Make Installed Build Linux" \
-set:HostPlatformOnly=true \
-set:WithLinux=true \
-set:WithLinuxArm64=false \
-set:WithServer=true \
-set:WithClient=false \
-set:WithDDC=false \
-set:WithFullDebugInfo=false \
-set:GameConfigurations=Development \
-set:BuiltDirectory=/home/cha/ue-as-5.8-linux-installed
The verified output root is:
/home/cha/ue-as-5.8-linux-installed/Linux
The clean Linux BuildGraph run completed successfully on 2026-09-12 in 3
hours 55 minutes 7 seconds. WSL exposed 24 logical CPUs and 31 GiB of RAM;
Unreal selected 12 parallel compiler actions, retained roughly 19-23 GiB of
available memory during observed probes, and used effectively no swap. The
result contained 276,600 files, Engine/Build/InstalledBuild.txt, executable
RunUAT.sh, and Engine/Binaries/Linux/UnrealServer.target.
GameConfigurations=Development limits packaged game/server configurations,
but the graph still builds its required editor configurations and tools. The
largest phases observed were the 5,743-action editor/LiveLinkHub pass, the
combined UnrealGame/UnrealServer pass, and the Linux tools pass. The build log
is retained at:
T:\UnrealEngine-Angelscript\Engine\Saved\Logs\LinuxContainer\04-BuildGraph-Linux-Installed.log
Linux symbol and image-size findings¶
WithFullDebugInfo=false does not create a symbol-light Linux Installed Build.
The verified 59 GiB tree still contained:
| Suffix | Count | Size |
|---|---|---|
.debug |
2,797 | 10.53 GiB |
.sym |
2,797 | 3.41 GiB |
.pdb |
408 | 0.07 GiB |
The .debug and .sym companions are not required to compile or cook a
project. The 408 PDBs are managed-tool symbols. For the build-only image, place
this .dockerignore at the Linux Installed Build root:
**/*.debug
**/*.sym
**/*.pdb
That reduced the Docker engine context to 47.15 GiB. Keep the complete Installed Build outside the image if crash-symbol retention is required; call the image symbol-light, not symbol-free.
The container recipe is maintained at:
T:\UE-AS-5.8-Linux-Container\Dockerfile
T:\UE-AS-5.8-Linux-Container\build-image.sh
It mirrors Epic's Ubuntu 22.04 Linux dev-image build and headless-cook
prerequisites, creates UID/GID 1000 user ue4, copies the Installed Build to
/home/ue4/UnrealEngine, and runs an UnrealEditor -SkipBuild pass to prime
per-user UBT state. After that prime, the Dockerfile must delete
/home/ue4/.epic/UnrealBuildAccelerator/uba_filemap. Baking this temporary UBA
map into the final layer caused a 300-plus-GiB unpack on the execution host.
UBT reported that Docker's default 64 MiB /dev/shm is below UBA's 1 GiB floor
and fell back to a disk file map. The accepted project build uses
--shm-size=8g; this keeps UBA in shared memory and avoids the disk-backed map.
Do not add CAP_SYS_PTRACE merely for this optimization.
Producer-host Docker 29 snapshotter finding¶
The Dockerfile stages and its internal UBT initialization succeeded. An optional local load/run attempt on the producer then exposed a Docker Engine 29.6.1 containerd-snapshotter failure during final unpack:
failed call to UtimesNanoAt .../snapshots/494/fs/etc: no such file or directory
The image manifest was registered at about 22.3 GB compressed, but the local
docker run remained in snapshot extraction. WSL disk use grew from roughly
394 to 761 GiB and the orphan snapshot reached 322 GiB. The optional test was
stopped before the distro filled. After confirming there were no containers
and removing the exact image tag, only the orphan snapshot created by this test
was deleted; free space recovered from 195 to 517 GiB. No unrelated images or
BuildKit cache were intentionally removed.
This incident does not make local runtime validation a producer requirement. If local runtime debugging is explicitly needed on an affected Docker host, classic overlay2 can be selected with:
{
"features": {
"containerd-snapshotter": false
}
}
Place that content in /etc/docker/daemon.json, restart Docker, and confirm
docker info reports overlay2 with normal backing-filesystem status rather
than driver-type=io.containerd.snapshotter.v1. This troubleshooting change
is optional and is not part of the normal producer pipeline.
BuildKit can export without asking the faulty snapshotter to unpack locally.
An OCI archive export succeeded in 685.2 seconds and produced the selected 21
GiB handoff artifact. docker load correctly rejected this format because an
OCI layout does not contain Docker archive manifest.json; that is not a defect
in the artifact. livingpc uses Docker's containerd snapshotter and has ctr,
which accepts OCI v1 directly. Skopeo conversion to Docker archive and direct
Docker-archive exports were rejected as practical routes because their
temporary layer rewrites expanded pathologically and threatened to exhaust the
producer's WSL filesystem.
The first OCI artifact retained the UBA file map and is superseded. The producer exports the corrected OCI directly without loading or running the image in its local image store:
docker buildx build \
--build-context engine=/home/cha/ue-as-5.8-linux-installed/Linux \
--tag tankgame/ue-as-build:5.8.2-f347f57-nouba \
--provenance=false \
--output type=oci,dest=/home/cha/ue-as-build-5.8.2-f347f57-nouba.oci.tar \
/mnt/t/UE-AS-5.8-Linux-Container
The accepted archive is
ue-as-build-5.8.2-f347f57-nouba.oci.tar, exactly 21,217,692,160 bytes, with
SHA-256
bafcce1745576af2590c96e906048eb0f849b99ad0816530083801a30633649c.
On import, Docker reports image tag
tankgame/ue-as-build:5.8.2-f347f57-nouba, image ID beginning
sha256:463f9d6, and size 21,217,681,248 bytes.
Producer artifact gate¶
The producer validates the artifact without importing or running it locally. The maintained validator verifies every declared OCI blob size and SHA-256, streams the engine layer, checks the image user and working directory, checks the required engine files, and rejects excluded symbol suffixes:
python3 /mnt/t/UE-AS-5.8-Linux-Container/validate-oci.py \
/home/cha/ue-as-build-5.8.2-f347f57-nouba.oci.tar
sha256sum /home/cha/ue-as-build-5.8.2-f347f57-nouba.oci.tar \
> /home/cha/ue-as-build-5.8.2-f347f57-nouba.oci.tar.sha256
This gate passed. It found Engine/Build/InstalledBuild.txt, executable
Engine/Build/BatchFiles/RunUAT.sh, and
Engine/Binaries/Linux/UnrealServer.target; confirmed user ue4 and working
directory /home/ue4/UnrealEngine; and found no .debug, .sym, or .pdb
files in the engine layer.
Also record the engine revision, Dockerfile revision, image tag, artifact size, symbol exclusions, and checksum in the build manifest. A registry publication uses the immutable pushed digest in place of the archive checksum.
Tank Game Linux compatibility requirements¶
The project checkout used by Jenkins must satisfy all of these requirements:
Metal_terraServer.Target.csuses the UE 5.8 server target shown above.MinimapPlugin.upluginincludesLinuxin itsPlatformAllowList.- Wwise integration
2025.1.10.9233.4458has matching SDK2025.1.10.9233headers and Linux x86-64 libraries. - The two Wwise GTE
std::is_signedspecializations have the narrowly scoped Clang 20 diagnostic suppression described in the upgrade guide. - Every plugin enabled for the server has Linux-compatible source and rules.
The proof of concept excluded GitSourceControl, Hermes, and RedTalaria because they are unrelated to the dedicated-server path. Production must either keep them disabled for the target or validate their Linux builds; their exclusion is not evidence of compatibility.
Two OFPA external-actor packages reference the Win64-only GPU Lightmass plugin and must be moved out of the checkout during Linux cook, then restored even if UAT fails:
Content/__ExternalActors__/Levels/Battle_Level/5/T2/AQOHDB9U15TZCMVLH6OI4F.uasset
Content/__ExternalActors__/Levels/Character_Selection_Level/C/IK/8823VKZEHC9FRWC4F570VM.uasset
Use a shell trap in Jenkins so both files are always restored. The durable
fix is to remove the GPU Lightmass settings actors in the Windows editor and
save both levels; removing those settings actors does not remove baked
lightmaps.
The host-side exclusion can use this pattern before the Docker invocation:
project=/path/to/checked-out-project
actor_stash=$(mktemp -d)
gpu_actors=(
Content/__ExternalActors__/Levels/Battle_Level/5/T2/AQOHDB9U15TZCMVLH6OI4F.uasset
Content/__ExternalActors__/Levels/Character_Selection_Level/C/IK/8823VKZEHC9FRWC4F570VM.uasset
)
restore_gpu_actors() {
for relative_path in "${gpu_actors[@]}"; do
if [[ -e "$actor_stash/$relative_path" ]]; then
mkdir -p "$project/$(dirname "$relative_path")"
mv "$actor_stash/$relative_path" "$project/$relative_path"
fi
done
}
trap restore_gpu_actors EXIT
for relative_path in "${gpu_actors[@]}"; do
if [[ -e "$project/$relative_path" ]]; then
mkdir -p "$actor_stash/$(dirname "$relative_path")"
mv "$project/$relative_path" "$actor_stash/$relative_path"
fi
done
Execution-host acceptance gate¶
On livingpc, verify the checksum, import the OCI archive directly into
Docker's containerd namespace, and check the engine contract from inside the
container:
sha256sum --check ue-as-build-5.8.2-f347f57-nouba.oci.tar.sha256
sudo ctr --namespace moby images import \
--base-name docker.io/tankgame/ue-as-build \
--platform linux/amd64 \
ue-as-build-5.8.2-f347f57-nouba.oci.tar
docker image inspect tankgame/ue-as-build:5.8.2-f347f57-nouba
docker run --rm --shm-size=8g \
--entrypoint /bin/bash \
tankgame/ue-as-build:5.8.2-f347f57-nouba \
-lc 'test -x Engine/Build/BatchFiles/RunUAT.sh && \
test -f Engine/Binaries/Linux/UnrealServer.target'
The CI deployment then creates a fresh output location and runs the Jenkins-equivalent project build. Host paths below are placeholders and must be adapted by the deployment:
docker run --rm --shm-size=8g \
-v "/path/to/checked-out-project:/project" \
-v "/path/to/fresh-server-output:/out" \
tankgame/ue-as-build:5.8.2-f347f57-nouba \
/home/ue4/UnrealEngine/Engine/Build/BatchFiles/RunUAT.sh BuildCookRun \
-project=/project/Metal_terra.uproject \
-platform=Linux -server -serverconfig=Development -noclient \
-build -cook -stage -pak -archive -archivedirectory=/out
This execution-host gate must compile the project-level plugins from the
mounted checkout, including Wwise, Nakama, JourneymanMiniMap, and the maintained
runtime/Game Feature plugins. Image startup by itself does not prove those
Linux modules or the server target are compatible. The current livingpc
Jenkins deployment is one consumer of this contract, not part of the artifact
definition.
The isolated acceptance run completed on 2026-09-13 with UAT BUILD
SUCCESSFUL, exit code 0, and cook result Success - 0 error(s), 86 warning(s).
On warm caches it took approximately 67 seconds and produced a 1.1-GB
LinuxServer archive. The packaged server executable was 302,884,312 bytes,
had SHA-256
8dca925d7f6fb59482981a97dd6c21cf9728ca9746efd82f97f25421d8380b73,
and had no missing ldd dependencies. Script/Binds.Cache and
Script/Binds.Cache.Headers in the archive prove that the AngelScript bind
data was packaged. Missing inventory-icon and similar asset references remained
warnings, not cook errors, and should be repaired independently.
The initial acceptance used isolated branch UE5.8-AS at project commit
9be5c5c24d6e2f3111428d523a1e4b1bc3887b21 and did not modify the production
Jenkins job. Jenkins TankGame build #508 subsequently selected
tankgame/ue-as-build:5.8.2-f347f57-nouba and completed successfully while
applying temporary Wwise and Minimap patches in its workspace. The remaining
promotion gate is to commit those changes to their owning server/plugin source,
tag that source, remove the Jenkins mutations, and pass from a clean workspace.
Update and rollback policy¶
Treat every engine update as a new immutable artifact:
- choose and record the new engine commit;
- rebuild engine-wide Marketplace plugins;
- rerun focused project-plugin compatibility builds;
- run clean full-target, editor, Blueprint, map, cook, and package gates;
- update the Installed Build without
-cleanunless a clean-build condition above applies; - create a new versioned archive and checksum;
- publish it beside—not over—the previous known-good artifact;
- update the shared registration label only after acceptance.
Retaining the previous archive makes rollback a registry-value change rather than an engine rebuild.
Distribution boundary¶
This pipeline is intended for internal collaborators who are separately licensed to use the corresponding Unreal Engine code. Public distribution of Engine Tools and distribution of a non-C++ language integration have additional Unreal Engine license requirements. Review the current Epic license before publishing the editor or engine outside the authorized team.
Primary external references:
Acceptance criteria¶
The distribution pipeline is complete only when:
- BuildGraph succeeds from the pinned source revision and recorded local plugin state;
- the Installed Build works without the source checkout;
- engine-wide Marketplace plugins are present and load;
- Linux BuildGraph produces
RunUAT.shandUnrealServer.targetat the pinned revision; - the producer emits a structurally valid, checksummed OCI/Docker archive or an immutable registry digest without requiring a local image load;
- a separate execution host imports or pulls the symbol-light Linux image and exposes the required engine path;
- CI on the execution host completes Tank Game
BuildCookRunfor a Linux Development server; - the
.7zextracts cleanly on a second machine or clean environment; RegisterEngine.batcreates the named engine entry and.uprojectactions;- the published checksum matches the downloaded archive;
- artifact inputs and omissions are documented.