Skip to content
Browse the docs

Workshop docsCampaigns & mods

Creating a campaign

A small JSON file is what puts your maps in the main menu, gives them artwork, and sets their loading screens. Even a single map needs one.

Without a campaign file, your map still works, but only for players who know to open the console and type map yourmapname. It won't appear anywhere in the menu.

With one, it's listed on the Campaigns tab of the main menu's Add-ons section, with your title and artwork. Players click it and choose a chapter, or go straight in if there's only one. The same file also sets the loading screen for each of your maps.

1. Name the file

Campaign files live in the campaigns/ folder. The game reads every .json file in that folder, so pick a name nobody else will use, such as your project's prefix:

campaigns/ap_accesspoint.json

2. Write it

Here's a complete campaign with two chapters. Copy it and change the values:

JSON
{
    "title": "Access Point",
    "author": "Your Name",
    "url": "https://steamcommunity.com/sharedfiles/filedetails/?id=YOUR_ITEM_ID",
    "description": "A break-in at a high-security storage facility.",
    "imageSource": "image://game/ui/ap_accesspoint/logo.png",
    "chapters": [
        {
            "title": "Lobby",
            "description": "",
            "imageSource": "image://game/ui/ap_accesspoint/chapter1.png",
            "levelName": "ap_01_lobby"
        },
        {
            "title": "The Vault",
            "description": "",
            "imageSource": "image://game/ui/ap_accesspoint/chapter2.png",
            "levelName": "ap_03_vault"
        }
    ]
}
FieldWhat it does
titleThe campaign's name on its card.
imageSourceThe card's artwork.
chaptersThe list of chapters, in order. A chapter is a point the player can start from. You don't list every map, only the one each chapter begins with.
chapters[].titleThe chapter's name, shown on its card and on the loading screen.
chapters[].imageSourceThe chapter's artwork. It's also the loading screen for every map in the chapter.
chapters[].levelNameThe map the chapter starts on: the .bsp file name, without maps/ or .bsp.
author, url, descriptionNot shown in the menu, but fill them in. They tell anyone opening the file whose campaign it is and where it came from.

A single map is a campaign with one chapter. In that case the menu skips the chapter list, and Start Game loads your map directly.

3. Add the images

Images are loaded through the game's file system, so they can be inside your VPK. Write each path as image://game/ followed by the file's path in your mod folder:

File in your mod folderValue in the JSON
ui/ap_accesspoint/logo.pngimage://game/ui/ap_accesspoint/logo.png
ui/ap_accesspoint/chapter1.pngimage://game/ui/ap_accesspoint/chapter1.png
  • PNG or JPG, 16:9. The official chapter images are 1280×720. Since chapter images double as full-screen loading screens, 1920×1080 is even better.
  • Keep them in your own folder (ui/<yourtag>/). The game's own art lives in ui/campaign/images/, and a file there with the same name as one of yours would replace it.
  • A good chapter image is a striking, recognisable shot from early in that chapter. Many mappers take a screenshot with the HUD hidden (cl_drawhud 0), then color-grade it.

4. Check the JSON is valid

If the file isn't valid JSON, the campaign won't appear, and the game won't tell you why. Before you test, paste the file into any online JSON validator. The usual culprits:

  • A comma after the last item in a list or object, e.g. "levelName": "ap_01_lobby", before a closing }.
  • Comments. // lines are fine in Source's text files but not in JSON.
  • Curly "smart" quotes pasted from a word processor or web page. Use straight " quotes.
  • Doubled braces. An older template on the Valve Developer Community wraps the whole file in an extra { … }, which isn't valid JSON. The file must start with { and its first line inside must be a field like "title".

Titles: plain text, not #tokens

The official campaign's file uses titles like #BMS_Chapter1_Title. Those are localization tokens, looked up in the game's translation files. A Workshop item can't add entries to those files, so a token in your campaign shows up on screen as the raw text #MYMOD_Chapter1_Title.

Write titles as plain text. Tokens only make sense in a standalone mod, which ships its own translation files.

Connecting maps together

Moving from one map to the next in a campaign uses a trigger_changelevel in the first map and an info_landmark with the same name in both maps, exactly as in Half-Life 2. The VDC article on level transitions covers the details. The official map sources are full of working examples.

Chapters and transitions are separate things: transitions decide how the player moves through your maps, and chapters only decide where the player can start from in the menu.

How maps are matched to chapters

The campaign file only names each chapter's first map. When the player loads a save in a later map, the game has to work out which chapter that map belongs to, so it can show the right loading screen. It does this by name:

  1. If a chapter starts on this exact map, that's its chapter.
  2. Otherwise, it takes the chapter starts that share the map's first four letters and sort alphabetically before it, and picks the latest of them.

With the example above (chapters start at ap_01_lobby and ap_03_vault):

MapChapterWhy
ap_01_lobbyLobbyA chapter starts here.
ap_02_officesLobbyStarts with ap_0; the latest chapter start before it is ap_01_lobby.
ap_03_vaultThe VaultA chapter starts here.
ap_04_roofThe VaultThe latest chapter start before it is ap_03_vault.

Now the same campaign with careless names:

MapChapterWhy
lobbyLobbyA chapter starts here.
officesnoneNo chapter start begins with offi. The loading screen has no image.
vaultThe VaultA chapter starts here.
roofnoneNo chapter start begins with roof.

So: give all your maps the same prefix, and number them in play order. That also protects you from other people's campaigns, since a map named bm_c… would be compared against the official campaign's chapters.

Don't ship a chapter_manifest.txt

Older guides tell you to create scripts/chapter_manifest.txt. Workshop campaigns don't need it, and the game ignores one shipped in a Workshop item, so leave it out. Only standalone mods use their own.

Don't put one in bms/custom/ either, and that includes a test VPK. From there it does replace the official campaign's file, which changes which official chapters unlock and which background the main menu shows.

Test it

  1. Put your files where the game can see them (testing locations) and restart the game. The campaign list is read at startup.
  2. Choose Add-ons in the main menu. Your campaign should be listed on the Campaigns tab with its artwork.
  3. Click it. Check that every chapter shows the right title and image, then start each one.
  4. Play into a later map, save, quit to the menu, and load that save. The loading screen should show that chapter's image.

If your campaign is missing, or a title or image is wrong, go to Troubleshooting.