Skip to content

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:

  1. confirm Engine/Build/InstalledBuild.txt exists;
  2. launch Engine/Binaries/Win64/UnrealEditor.exe from the Installed Build;
  3. confirm the five expected Marketplace plugin descriptors and Win64 module binaries exist beneath Engine/Plugins/Marketplace;
  4. 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 moby containerd namespace with ctr; 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:

  1. preserve a registry export of the Ubuntu distribution registration;
  2. verify the destination ext4.vhdx exists and the old VHD does not;
  3. repair the distribution BasePath to T:\WSL\Ubuntu;
  4. retain a compatibility junction from the exact old distro folder to the new folder until the WSL service reloads its registration;
  5. verify WSL_OK, the source directory, and df -h before 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.cs uses the UE 5.8 server target shown above.
  • MinimapPlugin.uplugin includes Linux in its PlatformAllowList.
  • Wwise integration 2025.1.10.9233.4458 has matching SDK 2025.1.10.9233 headers and Linux x86-64 libraries.
  • The two Wwise GTE std::is_signed specializations 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:

  1. choose and record the new engine commit;
  2. rebuild engine-wide Marketplace plugins;
  3. rerun focused project-plugin compatibility builds;
  4. run clean full-target, editor, Blueprint, map, cook, and package gates;
  5. update the Installed Build without -clean unless a clean-build condition above applies;
  6. create a new versioned archive and checksum;
  7. publish it beside—not over—the previous known-good artifact;
  8. 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.sh and UnrealServer.target at 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 BuildCookRun for a Linux Development server;
  • the .7z extracts cleanly on a second machine or clean environment;
  • RegisterEngine.bat creates the named engine entry and .uproject actions;
  • the published checksum matches the downloaded archive;
  • artifact inputs and omissions are documented.