Skip to main content

Steam manifest files explained

What the appmanifest_*.acf file is, what is in it, why SteamTools needs it, and how to read one in a text editor.

Last updated: 2026-07-05

Every SteamTools unlock needs two files. This page explains the first one — the appmanifest_<APPID>.acf file — in enough detail that you can read one in a text editor and understand what every line is doing. The Lua file is the easy half (it is just a short script that tells SteamTools which depots to load); the manifest is the part that confuses people. We also walk through every common error and edge case the manifest can have so that the next time you see one in the wild, you know exactly what to do with it.

What the file is

The manifest is a small text file in Valve's "ACF" (Application Configuration File) format. ACF is a key-value format with section headers, similar to INI. Steam writes one of these for every app you have ever installed, in the steamapps directory. The naming convention is appmanifest_<APPID>.acf, where <APPID> is the App ID of the game.

For SteamTools to work, you need a copy of that file (or one that points at the right depots and build) sitting in a folder SteamTools watches, typically <SteamTools>/depotcache/. The manifest does not need to be the exact file that Steam wrote for your install — it just needs to describe the right build of the right app. SteamTools reads the manifest to know which build of which depot to grab, and reads the Lua file (the second download) to know which decryption key to use.

What is inside a manifest

A real appmanifest_400.acf (Portal) looks like this:

"AppState"
{
    "appid"         "400"
    "name"          "Portal"
    "installdir"    "Portal"
    "StateFlags"    "4"
    "UpdateLocalTime"   "Wed Jan  1 12:34:56 2025"
    "buildid"       "1234567"
    "LastOwner"     "12345678901234567"
    "BytesToDownload"   "0"
    "BytesDownloaded"   "0"
    "AutoUpdateBehavior" "0"
    "UserConfig"
    {
        "language"   "english"
    }
    "MountedDepots"
    {
        "400"    "2345678"
    }
}

Most of these fields are self-explanatory once you know what to look for. The two that matter for SteamTools are:

  • appid — the App ID. Has to match the file name. SteamTools does not even look at the filename, but Steam will refuse to load the manifest if the file name does not start with appmanifest_<appid>.acf. So they need to match.
  • MountedDepots — the mapping from depot ID to the build ID of that depot. SteamTools uses this to know which build of each depot to download. If MountedDepots is empty or wrong, SteamTools cannot find the right build and the game will not launch.

The other fields (UpdateLocalTime, UserConfig, LastOwner, etc.) are Steam's bookkeeping. SteamTools ignores them. The generator does not include them because copying LastOwner from someone else's manifest would point at their Steam install, not yours — a privacy and correctness issue.

What the generator actually gives you

When you request a manifest from this site, you get a small text file with the fields SteamTools needs and nothing else. Specifically:

  • appid
  • name (resolved from appdetails at request time)
  • installdir (Steam's install directory convention, lowercased)
  • buildid (the latest public build, or the build for the branch you asked for)
  • MountedDepots, with one entry per depot on the app

We do not include UpdateLocalTime, UserConfig, or LastOwner because SteamTools does not read them, and copying them from someone else's manifest would point at someone else's Steam install, not yours.

A manifest from the generator is typically 200–600 bytes, depending on the number of depots. Compare that to a full Steam manifest which can be 2–4 KB.

The Lua file in 60 seconds

The Lua file (the second of the two files you download) is a tiny script that tells SteamTools which depots to load for this app. A typical 400_public.lua is roughly:

addappid(400, 1, "abcdef0123456789abcdef0123456789")
setmanifest("2345678", "1234567890abcdef1234567890abcdef")
  • addappid(<appid>, 1, <depot_key>) registers the app and provides the decryption key for its primary depot.
  • setmanifest(<depot_id>, <manifest_id>) points SteamTools at the specific build of that depot.

The generator derives both the depot key and the manifest ID from public Steam data. There is no secret sauce. The depot key is the depot's decryption key, which is a 32-character hex string Steam publishes publicly. The manifest ID is the SHA-1 of the depot's manifest file, which is also public.

Why SteamTools needs both files

The split is intentional:

  • The manifest tells SteamTools which build of the app to load.
  • The Lua file tells SteamTools how to load it (which depots, which decryption key).

If you only have the manifest, SteamTools does not know how to decrypt the depot. If you only have the Lua file, SteamTools does not know which build to grab. Both files are required, and they must agree on the App ID.

  .acf manifest                  .lua script
       │                              │
       │  "I want build 1234567       │  "use depot key X for app 400,
       │   of app 400, with depots    │   and point at manifest Y for
       │   400 → 2345678"             │   depot 2345678"
       │                              │
       └──────────┬───────────────────┘
                  ▼
            SteamTools
            (desktop client)
                  │
                  ▼
         game launches with
         the right decrypted
         build

A note on branches

Some games have a beta or ptb branch in addition to public. The generator exposes a "Branch" field in the UI; if you set it, the returned manifest and Lua target that branch's build instead of the public build. The default is public.

The branch name has to match exactly what Steam shows. Common values are public, beta, beta_1, ptb, and experimental. If you are not sure which branch you want, leave the field blank and you will get the public build.

To discover the available branches for a given app, check SteamDB's branches tab for the App ID. SteamDB is the authoritative source for branch names and the buildid of each.

Common edge cases

These are the cases that are not covered by the basic "drop the file in depotcache" flow.

Apps with no public depots

Some apps exist in Steam's catalogue but have no published builds. They show up in search, they have an App ID, but appdetails returns an empty depot list. The generator will return a 0-byte manifest or one with only the AppState header. The how-it-works page has a dedicated error for this.

Encrypted vs unencrypted depots

Every depot on Steam is encrypted, regardless of whether the game is "DRM-free" or not. The encryption is applied to the depot chunks, not to the game files themselves — the game files come out decrypted once SteamTools has the depot key. The Lua file is what gives SteamTools that key.

This is why the Lua file is mandatory even for games that are advertised as "no DRM". The DRM is at the Steam-workshop level (no Steam account owns the game), not at the depot level (the depot chunks are still AES-encrypted on the wire).

Soundtracks and DLC

DLC and soundtracks are normal Steam apps. They have their own App ID, their own manifest, and their own Lua file. To unlock a DLC or soundtrack, generate the manifest + Lua for the DLC's App ID, not the base game's. Common DLCs are things like "Original Soundtrack" (App ID in the high 200,000s) and "Season Pass" (App ID varies).

If you have a base game + DLC combo you want to unlock, you need two manifest/Lua pairs: one for the base game's App ID and one for the DLC's App ID. Both go in the same depotcache and scripts folders.

Cross-region depots

Some games publish separate depots for different regions (CN, EU, US, ASIA). The generator picks the depots that match your Steam client's region. If you change regions, regenerate the manifest — the MountedDepots mapping will be different.

Tools (Proton, Steamworks, Source SDK)

Tools like Proton, the Source SDK, and Steamworks Common Redistributables are normal Steam apps. They can be unlocked the same way. The App IDs are well known (Proton is 858280; Steamworks is 243750).

A note on delisted apps

If a game has been delisted from Steam, the manifest and Lua may still exist in this generator, but they will not work. SteamTools upstream also cannot get a working build for a delisted app, and neither can SteamDB. There is no workaround — the only way to keep using a delisted app is to keep a copy of it installed before it was delisted, and never uninstall it.

Some delisted apps remain technically accessible through Steam's appdetails endpoint for a few weeks after delisting. During that window, the generator will return a working manifest. After the window closes, it will return a 404 and there is nothing we can do.

Verifying a manifest is correct

Before you drop a manifest into depotcache, run through this checklist:

  1. Filename matches appid. The file should be appmanifest_<APPID>.acf and the appid field inside should match. If they do not match, SteamTools will refuse it.
  2. name matches the game you expect. If the name is wrong, you have the wrong App ID.
  3. MountedDepots is non-empty. An empty MountedDepots block means the app has no public builds.
  4. The buildid looks reasonable. Steam build IDs are integers, typically 7–8 digits, and they grow over time. A buildid of 1 or 0 is wrong.

If all four pass, the manifest is good. Drop it in depotcache, drop the Lua in scripts, restart SteamTools.

Troubleshooting: "I dropped the files in but SteamTools still shows the game as locked"

Nine times out of ten, one of these is the cause:

  1. You put the manifest in the wrong folder. It must be in the depotcache folder at the root of your SteamTools install, not in a sub-folder.
  2. You put the Lua in the wrong folder. It must be in the scripts folder at the root of your SteamTools install, not in depotcache.
  3. You did not restart SteamTools. The files are read at SteamTools launch. If you copy them in while SteamTools is running, nothing happens.
  4. The build in the manifest is older than the build Steam is offering. Regenerate the manifest — the buildid in the new one will be the latest public.
  5. The branch in the Lua does not match the branch in the manifest. If you set the Branch field to beta but the Lua was generated for public, they will not agree. Regenerate with the same branch in both places (the generator does this by default).
  6. The depot key in the Lua is wrong. This is rare — it means the depot has been re-keyed. The generator picks up the new key on the next request.

SteamTools.games manifest vs raw Steam manifest vs GreenLuma manifest

The format is the same, but the contents differ.

SourceHas appidHas correct MountedDepotsHas LastOwnerWorks with SteamTools
This generatorYesYes (latest public build)No (omitted)Yes
Raw Steam manifest (from your own install)YesYes (your installed build)Yes (your Steam ID)Yes, but LastOwner is your own ID, which is fine
A manifest shared by a friendYesYes (their installed build)Yes (their Steam ID)Yes, SteamTools ignores LastOwner
A GreenLuma manifestYesSometimesNoSometimes — GreenLuma's manifest format is a subset and may not include MountedDepots

In short: a manifest from any source works with SteamTools as long as appid and MountedDepots are correct. The other fields are noise for SteamTools' purposes.

Further reading

See also