Addons
An addon is the unit of custom content in Source 2. It replaces the Source 1 habit of dropping loose compiled files into the game directory, custom content lives in a named folder and the game mounts that folder on request.
Every addon is two directories with the same name:
content/csgo_addons/my_addon/ => source files being edited
game/csgo_addons/my_addon/ => compiled output the game loads
The parent folder comes from the AddonRoot entry in gameinfo.gi, for example it is
csgo_addonsfor
Counter-Strike 2dota_addonsfor
Dota 2hlvr_addonsfor
Half-Life: Alyx
See Content mounting.
Creating an addon
The Addon Launcher, the resource compiler and the content/ tree all arrive with the Workshop Tools which is a separate Steam download for each game, see Installing the Workshop Tools.
You should almost always create new addons from the launcher instead of doing it manually, the launcher will setup default content as well as the game/ folder.
- Counter-Strike 2
- Half-Life: Alyx
- Dota 2
- Steam VR
The Addon Launcher is reached from the game's startup menu:
- Launch
Counter-Strike 2 from Steam. - In the startup menu, select Counter-Strike 2 Workshop Tools.
The Addon Launcher can also be started directly from the installation directory:
game/bin/win64/csgocfg.exe

In the launcher:
- Click on Create New Addon.
- Give your addon a name and click Create.
- Click on Launch Tools to open the Workshop tools.
Make sure to press on Launch Tools and NOT Edit Addon Map, the latter is broken and should not be used!


The Addon Launcher is reached from the game's startup menu:
- Launch
Half-Life: Alyx from Steam. - In the startup menu, select Tools.
The Addon Launcher can also be started directly from the installation directory:
game/bin/win64/hlvrcfg.exe

In the launcher, create a new addon, then open the tools with Launch Tools.


The Addon Launcher is reached from the game's startup menu:
- Launch
Dota 2 from Steam. - In the startup menu, select Tools.
The Addon Launcher can also be started directly from the installation directory:
game/bin/win64/dota2cfg.exe

In the launcher, create a new addon, then open the tools with Launch Tools.



The Addon Launcher is an executable in the SteamVR install rather than a startup menu entry:
SteamVR\tools\steamvr_environments\game\bin\win64\steamtourscfg.exe
It creates and launches addons the same way the other games do.

What the launcher produces on each side, folder by folder, is in Directory layout.
addoninfo.txt is a small metadata file on the game/ side. Depending on the game and its age it is either KeyValues or KV3, and it holds flags such as whether the addon is a playable map or a template.
Loading an addon
You can simply relaunch the respective addon manager for you game, as explained above, otherwise for manually launching into an addon you can use the following command line argument on the game's executable:
-addon my_addon
Only content under a mounted addon is visible to the game, which is why a map that loads in Hammer can still fail to load in the game if the addon was not mounted. How the name resolves is covered in Content mounting.
When loading an addon, the game doesn't actually search for content/ folders but rather game/ folders!, if you just downloaded an addon and put it in your AddonRoot
folder but can't find it in the launcher, go to the game/ folder and create a folder with the name of the addon.
Publishing
The Workshop Manager handles packaging and uploading. What gets published is ONLY the game/ side, since that is the compiled content, the content/ folder always stays local.
In some games like
Counter-Strike 2 which directories end up in the uploaded VPK is defined in gameinfo.gi: see Workshop packing.
Unless you defined a map for the addon to load in addoninfo.txt, the map that the game decides to load when loading into the addon is whichever one it comes across
first alphabetically, and two things follow from that:
-
A map's 3D skybox is a second map sitting in the same folder, so it has to sort after the main one or it is what loads. Naming it after the main map with a
_skyboxsuffix guarantees that, which is where the convention comes from:game/csgo_addons/my_addon/maps/├── de_my_map.vpk loads└── de_my_map_skybox.vpk the 3D skybox, sorts after it -
Compiling never deletes anything. Rename a map and the old compiled
.vpkstays behind ingame/, gets packed into the upload, and is still a map as far as the game is concerned. If the stale name sorts before the new one it will still load in the workshop and your update won't be seen. If it sorts after, it is harmless but bloats the published items file size. Delete old compiled maps from thegame/! The same applies to other file types!
Technical details
addoninfo
The metadata file is small and its format has drifted. Older addons use KeyValues:
"AddonInfo"
{
"IsTemplate" "1"
"IsPlayable" "0"
}
while newer ones written by current tools use KV3, sometimes an empty document:
<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
}
The two forms are one key space, not two dialects: the loader detects KV3 and reads it directly, otherwise it converts the KeyValues text into the same KV3 document
and throws the AddonInfo root name away. An empty document is normal, and it is what most published addons carry.
Valve ships the schema for this file as FGD files that the addon tools read, game/core/tools/workshop_addoninfo_base.fgd for the shared keys and
game/<mod>/tools/workshop_addoninfo.fgd for each game's own. Every key below comes from those.
| Key | Type | Default | Meaning |
|---|---|---|---|
maps | array of strings | Maps the addon offers the player, named as the map command takes them, so my_map for maps/my_map.vmap. The engine reads this one, and falls back to scanning the addon's maps/ directory if it is missing | |
IsPlayable | bool | 1 | Whether the addon shows up as playable |
IsTemplate | bool | 0 | Marks the addon as a template rather than content |
HideInTools | bool | 0 | Hides the addon from the launcher's list |
The three bools are marked hidden in the schema, so the tools do not show them, and outside Half-Life: Alyx and SteamVR Home they are read by the launcher and the Workshop Manager rather than by the game.
Each game adds its own keys:
Half-Life: Alyx has map_extensions, which overlays a map onto another map; see Addons over existing maps.
Dota 2 has by far the most, covering player counts, team counts, per-map overrides, the hero picker background and several rule toggles, because Dota custom games are configured here rather than in code.
Counter-Strike 2 adds gamemodesandcustom_cfg.
Both forms are read from the game/ side of the addon. Source2Viewer looks for addoninfo.txt when it opens an addon VPK for the same reason the engine does: it identifies the directory as an addon.
What the compiler produces
Compiling an addon does not produce one archive. Assets land as loose _c files at the mirrored path, and only maps are packed; see content/ and game/. The -novpk option of the resource compiler exists because that packing is a compile step, not a property of the file type.
Mounting
-addon my_addon resolves against the AddonRoot directories from gameinfo.gi and mounts that one subdirectory ahead of the game's own content, which is what lets an addon override a shipped asset. The full mechanics, including official addon priority, the packed-addon requirement for retail clients and the tools-mode single-addon lock, are on Content mounting.