Download
depot / guides / tf2-hlds

TF2 & the servers that started it all

Before "dedicated server" meant a Docker image, it meant a folder of SRCDS files someone kept alive for fifteen years. TF2 and the classic Source and GoldSrc servers are the oldest anonymous-download tradition on Steam — and the place where DepotDownloader quietly fixes a SteamCMD annoyance that's older than some of the admins running these servers. I've stood up most of these servers myself to check the commands on this page, and app 90 is the one that always reminded me why I reach for this tool.

01The family tree

Two engines, two patterns. SRCDS — the Source engine server — got split into standalone free apps in the SteamPipe migration, all clustered in the same AppID range. HLDS — GoldSrc, the engine of Half-Life and CS 1.6 — predates all of that and works differently: one shared app, 90, hosting every GoldSrc mod's server. All of them download anonymously, for the usual reason.

ServerAppIDEngineNotes
Team Fortress 2232250SourceThe flagship — worked example below.
Counter-Strike: Source232330SourceSame recipe as TF2.
Day of Defeat: Source232290SourceSame recipe.
Half-Life 2: Deathmatch232370SourceSame recipe.
HLDS (CS 1.6, HL, DoD, TFC…)90GoldSrcOne app, many mods — see §04.

(Garry's Mod and L4D2 are SRCDS cousins too — they're in the hub's AppID table.)

02TF2: the worked example

$ ./DepotDownloader -app 232250 -os linux -dir /srv/tf2

That's the whole install: no account, no Steam Guard, scriptable from anywhere. Re-run it after Valve ships an update and only the changed chunks transfer. From there it's standard TF2 server admin territory — srcds_run, a GSLT token for public listing, and most likely SourceMod/MetaMod, which brings the one warning this site repeats for every modded server: don't put -validate in your scheduled update job, because validation restores stock files and will strip your mod framework's patched binaries every run. Validate deliberately (after disk trouble, before a season), not habitually — the same cuts-both-ways behaviour documented for Rust.

03The rest of the Source family

CS:S, DoD:S and HL2:DM are the same command with a different number — that's the genuinely nice property of the 232xxx generation, and why a multi-game host can provision everything with one templated script. The only per-game decisions are which OS build (-os) and where it lands (-dir). These games update rarely now, which makes them ideal cron candidates: a nightly check costs seconds on the years-long gaps between patches, and your server is current within a day when one finally ships.

04HLDS and the app-90 quirk

GoldSrc servers are the one place the standard recipe earns an asterisk. All of HLDS lives in app 90 — Counter-Strike 1.6, vanilla Half-Life, Day of Defeat, TFC, all of it — and SteamCMD users know it for an infamous bug: app_update 90 routinely has to be run multiple times, with mod-config incantations between attempts, before all files actually land. There's a whole community repo of appmanifest workarounds for it, which tells you how long it's been annoying people.

DepotDownloader doesn't run that update logic at all — it resolves the app's depots and downloads them in one pass, which makes it a genuinely cleaner way to fetch HLDS files. The last time I fetched app 90 this way it landed complete on the first run, which is more than I can say for the SteamCMD route that bit me years ago:

$ ./DepotDownloader -app 90 -os linux -dir /srv/hlds

One honest caveat: app 90's depot layout is a museum piece — mods ship as separate depots inside the app, and what the run gives you is the engine plus mod content as Steam currently packages it. Have a look at app 90 on SteamDB if you want to cherry-pick a single mod's depot with -depot instead of taking the lot. For a CS 1.6 server specifically, the result still wants the classic post-install pass: your server.cfg, your maps, and the awareness that half the GoldSrc hosting wisdom on the internet predates Steam itself.

05Updates, and the honest SteamCMD question

Scheduled updates are identical to every other server — the hub's cron recipe applies verbatim, TF2 being the rare member of this family that still gets regular patches worth automating around. And because this corner of Steam is SteamCMD's historical home turf, the honest version of "which tool": if your host or panel already runs these servers via SteamCMD and it works, there's no prize for migrating — I wouldn't bother switching a setup that's already happy. The cases where DepotDownloader earns the switch are the ones above — the app-90 single-pass download, cross-OS pulls from your desktop, one uniform recipe across every game you run, and cron jobs with no +runscript ceremony. The full argument, both directions, lives in the comparison.