Unreal Cloud Docs
Guides

Upload an Unreal Engine build to Steam with steamcmd

Upload a packaged Unreal Engine build to a Steam beta branch with steamcmd: the build script, depots for each platform, Steam Guard on a build machine, and the common errors.

Steam doesn't take a zip. You upload builds with Valve's command-line tool, steamcmd, and a small build script that says which files go into which depot. This guide walks through uploading a packaged Unreal Engine build to a beta branch, by hand first, then from a build machine.

Before you start

You need, from Steamworks:

  • Your game's App ID, and the Depot ID for each platform you ship, for example one depot for Windows and one for Linux.
  • A beta branch to upload to, like beta or qa. Create it under your app's SteamPipe → Builds page.
  • A build account: a separate Steam account, never a personal one, added to your Steamworks organization with only two permissions for your app: Edit App Metadata and Publish App Changes To Steam.

And a packaged build of your game. Package in Shipping with an archive folder, from the editor or with BuildCookRun. The examples below use C:\Builds\MyGame\Windows, the folder that contains MyGame.exe.

Get steamcmd

steamcmd comes in the Steamworks SDK, under tools/ContentBuilder/builder. You can also download it on its own:

New-Item -ItemType Directory -Force C:\steamcmd | Out-Null; cd C:\steamcmd
Invoke-WebRequest -UseBasicParsing https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip -OutFile steamcmd.zip
Expand-Archive steamcmd.zip -DestinationPath . -Force
mkdir -p ~/steamcmd && cd ~/steamcmd
curl -sSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar -xz

On Ubuntu and Debian, steamcmd also needs 32-bit libraries: sudo apt install lib32gcc-s1.

Write the build script

The build script is a small text file in Valve's VDF format. Save it next to steamcmd as app_build_1234560.vdf, with your own App ID, Depot ID, folders and branch:

app_build_1234560.vdf
"AppBuild"
{
	"AppID" "1234560"
	"Desc" "MyGame Windows"
	"BuildOutput" "C:\steamcmd\output\"
	"ContentRoot" "C:\Builds\MyGame\Windows\"
	"SetLive" "beta"

	"Depots"
	{
		"1234561"
		{
			"FileMapping"
			{
				"LocalPath" "*"
				"DepotPath" "."
				"recursive" "1"
			}
			"FileExclusion" "*.pdb"
		}
	}
}
  • ContentRoot is your packaged game. LocalPath "*" with recursive "1" uploads everything in it, keeping the folders as they are.
  • FileExclusion leaves out debug symbols, which players don't need.
  • SetLive points the beta branch at the new build when the upload succeeds. It only works for beta branches: Steam never sets the default branch live from an upload, so nothing reaches your players by accident.
  • BuildOutput is where steamcmd writes its logs and caches. Keep it between uploads, so it only re-uploads what changed.

Several platforms

Add one depot per platform inside Depots, each with its own ContentRoot pointing at that platform's folder, like C:\Builds\MyGame\Linux\. They're all uploaded together as one Steam build.

Upload

Log in once by hand, so Steam Guard can confirm the machine:

steamcmd +login mygame_builder +quit

Enter the password, then the Steam Guard code Steam sends to the build account. steamcmd saves the login in its config folder.

Run the build, logging in without a password this time:

steamcmd +login mygame_builder +run_app_build C:\steamcmd\app_build_1234560.vdf +quit

It uploads the files, then prints the new BuildID.

Open your app's SteamPipe → Builds page in Steamworks. The build is there, live on your beta branch. Testers who've opted into that branch get it within minutes.

To ship it to players, set the same build live on the default branch from that page. That step is always manual.

Want to check the script without uploading? Add "Preview" "1" to AppBuild. steamcmd then lists what it would upload and writes the logs, without sending anything.

On a build machine

The same command works from a script, as long as steamcmd stays logged in:

  • Do the first login by hand on the build machine, with the Steam Guard code.
  • Keep the whole steamcmd folder between builds. Its config/config.vdf holds the login, and Valve notes that it can change after a successful login, so don't restore an old copy over it.
  • Never pass the password in the script. With a saved login, +login mygame_builder is enough, and typing the password again triggers a new Steam Guard check.

A saved login lasts for months, but not forever. It ends when the account's password or Steam Guard settings change. When it does, log in by hand again.

Released games

To set builds live on a game that's already released, the build account needs a phone number or the Steam Mobile Authenticator attached, and Steam blocks setting builds live for 3 days after any security change on the account.

Common errors

"Login Failure: Account Login Denied"

Steam Guard is blocking the login. Find the code in the build account's email, then run steamcmd, enter set_steam_guard_code <code>, and log in again.

"Failed to get application info for app"

ERROR! Failed to get application info for app 1234560 (check login and subscription)

Check the App ID, that your Steamworks settings are published, and that the build account has the two permissions from Before you start.

"Failed 'DepotBuild' - status = 6"

The upload couldn't read your files or doesn't have permission. Check the account's permissions and App ID, and that ContentRoot points at a folder that exists and contains the packaged game.

The game won't launch after installing

If Steam installs the game but it won't start, check the launch options in Steamworks (Installation → General Installation): the executable should be MyGame.exe, at the root of the depot, the same folder that ContentRoot points at. On Linux, it's MyGame.sh.

For anything else, the full log is in BuildOutput, which says more than the console.

Or let every passing build upload itself

Once this works, the next step is running it after every build, so testers always have the latest one.

On this page