Link Search Menu Expand

Unreal Engine Build Setup Guide

Configure automated Unreal Engine builds with full pipeline visibility.

Table of contents

  1. Overview
  2. Prerequisites
  3. Build Script Example
  4. UAT BuildCookRun Parameters
  5. Jenkins Integration
    1. Jenkinsfile for Unreal Builds
  6. Steam Upload
    1. app_build.vdf Template
    2. Upload Script
  7. Complete Pipeline
  8. Troubleshooting
    1. Build Fails Immediately
    2. Cooking Takes Too Long
    3. PAK Files Too Large
    4. Steam Upload Fails
  9. Best Practices

Overview

This guide walks you through setting up automated Unreal Engine builds that integrate with ButterStack’s 5-stage pipeline. You’ll learn how to:

  1. Configure build scripts for Windows and Linux
  2. Send build events to ButterStack
  3. Package for Steam deployment
  4. Track the complete asset lineage

Prerequisites

  • Unreal Engine 5.x installed
  • Jenkins or other CI system (optional)
  • ButterStack project with integrations configured
  • Perforce or Git for source control

Build Script Example

Here’s a complete PowerShell script for building an Unreal project for Steam:

# Unreal Engine Steam Build Script
# This script builds, cooks, and packages your UE project for Steam distribution

param(
    [string]$ProjectPath = "C:\Projects\MyGame\MyGame.uproject",
    [string]$UE5Root = "C:\Program Files\Epic Games\UE_5.4",
    [string]$OutputDir = "C:\Projects\MyGame\SteamBuild",
    [string]$Platform = "Win64",
    [string]$Configuration = "Shipping"
)

# ButterStack configuration (set via environment or parameters)
$ButterStackUrl = $env:BUTTERSTACK_URL
$ButterStackToken = $env:BUTTERSTACK_TOKEN
$ProjectId = $env:BUTTERSTACK_PROJECT_ID
$BuildNumber = $env:BUILD_NUMBER

$UAT = Join-Path $UE5Root "Engine\Build\BatchFiles\RunUAT.bat"

# Helper function to send ButterStack notifications
function Send-ButterStackEvent {
    param(
        [string]$Endpoint,
        [hashtable]$Body
    )

    if ($ButterStackUrl -and $ButterStackToken) {
        try {
            $json = $Body | ConvertTo-Json -Depth 10
            Invoke-RestMethod -Uri "$ButterStackUrl/webhooks/game_engine/$Endpoint" `
                -Method Post -Body $json -ContentType "application/json" `
                -Headers @{ Authorization = "Bearer $ButterStackToken" }
            Write-Host "Sent event: $Endpoint" -ForegroundColor Gray
        } catch {
            Write-Warning "Failed to send ButterStack event: $_"
        }
    }
}

# Check if Unreal Editor is running (will cause build failures)
$unrealProcesses = Get-Process -Name "UnrealEditor*" -ErrorAction SilentlyContinue
if ($unrealProcesses) {
    Write-Host "Unreal Editor is running. Close it before building." -ForegroundColor Red
    $response = Read-Host "Close it now? (y/n)"
    if ($response -eq 'y') {
        $unrealProcesses | Stop-Process -Force
        Start-Sleep -Seconds 3
    } else {
        Write-Host "Build cancelled."
        exit 1
    }
}

# Validate project exists
if (-not (Test-Path $ProjectPath)) {
    Write-Error "Project not found: $ProjectPath"
    exit 1
}

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Unreal Engine Build for Steam" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Project: $ProjectPath"
Write-Host "Platform: $Platform"
Write-Host "Configuration: $Configuration"
Write-Host "Output: $OutputDir"
Write-Host ""

# Notify ButterStack - Cooking Started
Send-ButterStackEvent -Endpoint "cooking_started" -Body @{
    project_id = $ProjectId
    build_number = [int]$BuildNumber
    engine_version = "5.4"
    platform = $Platform
    configuration = $Configuration
}

$startTime = Get-Date

# Run the build
& $UAT BuildCookRun `
    -project="$ProjectPath" `
    -noP4 `
    -platform=$Platform `
    -clientconfig=$Configuration `
    -cook `
    -build `
    -stage `
    -pak `
    -compressed `
    -prereqs `
    -distribution `
    -nodebuginfo `
    -archive `
    -archivedirectory="$OutputDir"

$exitCode = $LASTEXITCODE
$endTime = Get-Date
$duration = ($endTime - $startTime).TotalMilliseconds

if ($exitCode -eq 0) {
    Write-Host ""
    Write-Host "========================================" -ForegroundColor Green
    Write-Host "Build Completed Successfully" -ForegroundColor Green
    Write-Host "========================================" -ForegroundColor Green
    Write-Host "Duration: $([math]::Round($duration / 1000 / 60, 2)) minutes"
    Write-Host "Output: $OutputDir\Windows"
    Write-Host ""

    # Calculate PAK size
    $pakPath = Join-Path $OutputDir "Windows\MyGame\Content\Paks"
    $pakSize = 0
    if (Test-Path $pakPath) {
        $pakSize = (Get-ChildItem $pakPath -Recurse | Measure-Object -Property Length -Sum).Sum
    }

    # Notify ButterStack - Build Completed
    Send-ButterStackEvent -Endpoint "build_completed" -Body @{
        project_id = $ProjectId
        build_number = [int]$BuildNumber
        pak_size = $pakSize
        total_cook_time_ms = [int]$duration
    }

    # Open output folder
    explorer.exe "$OutputDir"
} else {
    Write-Host ""
    Write-Host "========================================" -ForegroundColor Red
    Write-Host "Build Failed" -ForegroundColor Red
    Write-Host "========================================" -ForegroundColor Red
    Write-Host "Exit code: $exitCode"

    # Notify ButterStack - Build Failed
    Send-ButterStackEvent -Endpoint "build_failed" -Body @{
        project_id = $ProjectId
        build_number = [int]$BuildNumber
        phase = "packaging"
        error = "Build failed with exit code $exitCode"
    }

    exit $exitCode
}

UAT BuildCookRun Parameters

Understanding the build parameters:

ParameterDescription
-projectPath to .uproject file
-noP4Don’t use Perforce (use Git or skip VCS)
-platformTarget platform (Win64, Linux, Android, etc.)
-clientconfigBuild configuration (Development, Shipping, Debug)
-cookCook content for the target platform
-buildCompile game code
-stageStage files to intermediate directory
-pakPackage content into PAK files
-compressedCompress PAK files
-prereqsInclude prerequisites installer
-distributionBuild for distribution (removes development features)
-nodebuginfoExclude debug symbols (smaller build)
-archiveCopy final build to archive directory
-archivedirectoryWhere to put the final build

Jenkins Integration

Jenkinsfile for Unreal Builds

pipeline {
    agent {
        label 'windows-ue5'
    }

    environment {
        UE_ROOT = 'C:\\Program Files\\Epic Games\\UE_5.4'
        PROJECT_PATH = 'C:\\Projects\\MyGame\\MyGame.uproject'
        BUTTERSTACK_URL = 'https://your-butterstack.com'
        BUTTERSTACK_TOKEN = credentials('butterstack-token')
        BUTTERSTACK_PROJECT_ID = 'your-project-id'
    }

    parameters {
        choice(name: 'PLATFORM', choices: ['Win64', 'Linux'], description: 'Target platform')
        choice(name: 'CONFIG', choices: ['Shipping', 'Development'], description: 'Build configuration')
    }

    stages {
        stage('Notify Start') {
            steps {
                script {
                    httpRequest(
                        url: "${BUTTERSTACK_URL}/webhooks/game_engine/cooking_started",
                        httpMode: 'POST',
                        contentType: 'APPLICATION_JSON',
                        customHeaders: [[name: 'Authorization', value: "Bearer ${BUTTERSTACK_TOKEN}"]],
                        requestBody: """
                            {
                                "project_id": "${BUTTERSTACK_PROJECT_ID}",
                                "build_number": ${BUILD_NUMBER},
                                "engine_version": "5.4",
                                "platform": "${params.PLATFORM}",
                                "configuration": "${params.CONFIG}"
                            }
                        """
                    )
                }
            }
        }

        stage('Build') {
            steps {
                bat """
                    "%UE_ROOT%\\Engine\\Build\\BatchFiles\\RunUAT.bat" BuildCookRun ^
                        -project="%PROJECT_PATH%" ^
                        -noP4 ^
                        -platform=%PLATFORM% ^
                        -clientconfig=%CONFIG% ^
                        -cook -build -stage -pak ^
                        -compressed -prereqs -distribution ^
                        -archive -archivedirectory="%WORKSPACE%\\Build"
                """
            }
        }

        stage('Notify Complete') {
            steps {
                script {
                    httpRequest(
                        url: "${BUTTERSTACK_URL}/webhooks/game_engine/build_completed",
                        httpMode: 'POST',
                        contentType: 'APPLICATION_JSON',
                        customHeaders: [[name: 'Authorization', value: "Bearer ${BUTTERSTACK_TOKEN}"]],
                        requestBody: """
                            {
                                "project_id": "${BUTTERSTACK_PROJECT_ID}",
                                "build_number": ${BUILD_NUMBER}
                            }
                        """
                    )
                }
            }
        }

        stage('Archive') {
            steps {
                archiveArtifacts artifacts: 'Build/**/*', fingerprint: true
            }
        }
    }

    post {
        failure {
            script {
                httpRequest(
                    url: "${BUTTERSTACK_URL}/webhooks/game_engine/build_failed",
                    httpMode: 'POST',
                    contentType: 'APPLICATION_JSON',
                    customHeaders: [[name: 'Authorization', value: "Bearer ${BUTTERSTACK_TOKEN}"]],
                    requestBody: """
                        {
                            "project_id": "${BUTTERSTACK_PROJECT_ID}",
                            "build_number": ${BUILD_NUMBER},
                            "error": "Jenkins build failed"
                        }
                    """
                )
            }
        }
    }
}

Steam Upload

After building, upload to Steam using SteamCMD:

app_build.vdf Template

"AppBuild"
{
    "AppID" "YOUR_APP_ID"
    "Desc" "Build ${BUILD_NUMBER} - ${GIT_COMMIT_MESSAGE}"
    "ContentRoot" "./Build/Windows"
    "BuildOutput" "./SteamOutput"
    "Depots"
    {
        "YOUR_DEPOT_ID"
        {
            "FileMapping"
            {
                "LocalPath" "*"
                "DepotPath" "."
                "recursive" "1"
            }
            "FileExclusion" "*.pdb"
        }
    }
}

Upload Script

# Upload to Steam
$SteamCmd = "C:\SteamCMD\steamcmd.exe"
$SteamUser = $env:STEAM_USER
$SteamPass = $env:STEAM_PASS

& $SteamCmd +login $SteamUser $SteamPass +run_app_build app_build.vdf +quit

if ($LASTEXITCODE -eq 0) {
    # Notify ButterStack of deployment
    Send-ButterStackEvent -Endpoint "../deployment" -Body @{
        project_id = $ProjectId
        platform = "steam"
        event = "uploaded"
        build_number = [int]$BuildNumber
    }
}

Complete Pipeline

With everything configured, your pipeline looks like:

1. Developer commits to Perforce with "PROJ-123: Added new level #ci"
   └─▶ ButterStack receives webhook, creates Change record
   └─▶ Perforce triggers Jenkins build

2. Jenkins starts build
   └─▶ ButterStack receives build_started webhook
   └─▶ Build appears in ButterStack with "In Progress" status

3. UAT BuildCookRun executes
   └─▶ ButterStack receives cooking_started webhook
   └─▶ Game Engine Build record created

4. Build completes successfully
   └─▶ ButterStack receives build_completed webhook
   └─▶ Build status updated to "Completed"

5. SteamCMD uploads to Steam
   └─▶ ButterStack receives deployment webhook
   └─▶ Deployment record created

6. ButterStack polls Steam API
   └─▶ Detects build is live
   └─▶ Deployment status updated to "Live"

Complete lineage: Task → Commit → Build → Engine Build → Deployment

Troubleshooting

Build Fails Immediately

  • Check Unreal Editor isn’t running
  • Verify project path is correct
  • Ensure UAT.bat exists at expected location

Cooking Takes Too Long

  • Enable Derived Data Cache (DDC)
  • Use shared DDC on network drive
  • Consider incremental cooking

PAK Files Too Large

  • Enable -compressed flag
  • Review what’s being packaged
  • Use pak chunking for DLC

Steam Upload Fails

  • Verify SteamCMD credentials
  • Check depot configuration
  • Ensure build output exists

Best Practices

  1. Use dedicated build machines - Don’t build on development workstations
  2. Enable DDC - Dramatically speeds up cooking
  3. Version your build scripts - Keep scripts in source control
  4. Tag builds consistently - Use BUILD_NUMBER for traceability
  5. Archive build logs - Keep logs for debugging
  6. Test locally first - Run build script manually before CI

Back to top

Copyright © 2026 ButterStack. All rights reserved.