RE:NODE
Browse hosting

Guides14 min read

Team Fortress 2 SourceMod plugins and admin setup

Installing Metamod:Source and SourceMod on a TF2 server, admins and flags, the plugins worth running, map votes, sv_pure and fast downloads.

0 readers

Everything people like about a Team Fortress 2 community server is a plugin. Admin commands, map votes, reserved slots, custom modes, stats, the thing that stops one person shouting into voice for an hour - none of it is in the game. It is Metamod:Source loading SourceMod, SourceMod loading a folder of compiled plugins, and about twenty minutes of configuration that most guides skip because they assume you already know it.

Two files decide whether it works: tf/addons/metamod.vdf, which tells the engine to load Metamod at startup, and tf/addons/sourcemod/configs/admins_simple.ini, which decides who you are. Get those right and the rest is choosing plugins. This post covers the install, the admin system in detail, the plugins that ship and the ones worth adding, the TF2 cvars that actually change something, custom content and downloads, and what breaks when Valve updates the game. A Team Fortress 2 server worth joining is the short version of why any of this matters.

What SourceMod is, and what runs it#

SourceMod is a plugin platform for Source 1 games. Plugins are written in SourcePawn, compiled to .smx files, and dropped into a folder; SourceMod loads them, gives them an API for the game, and handles admin identity, translations, menus and database access so that each plugin does not have to. Metamod:Source sits underneath it as the loader that gets SourceMod into the game process in the first place.

TF2 is a Source 1 game, so all of this works properly, which is worth stating because Counter-Strike 2 is Source 2 and none of it works there at all. A SourcePawn plugin you find today will run on TF2 and will not run on CS2.

The server itself is Steam app 232250, installed anonymously:

bash
$ steamcmd +force_install_dir /home/tf2/server +login anonymous \    +app_update 232250 validate +quit$ cd /home/tf2/server$ ./srcds_run -game tf -console -usercon -port 27015 \    +maxplayers 24 +map cp_process_final \    +sv_setsteamaccount YOUR_GSLT_TOKEN
SetupRAMCPUDisk
12 slots, 6v6, a few plugins1-2 GB1 core30 GB
24-32 slot public server, full plugin set2-3 GB1.5-2 cores30-40 GB
Versus Saxton Hale, Freak Fortress, custom modes3-4 GB2+ cores40 GB plus content
MvM with custom missions3-4 GB2+ cores40 GB plus content

TF2 is unusual in that disk, not memory, is what a small plan runs out of first. The dedicated server install is upwards of 15 GB before you add a single custom map, and it grows with every update. Memory is modest: the game is old and well optimised, and a full 24-slot server is comfortable inside 2 GB unless a plugin is holding state for every player.

The -usercon flag enables RCON, and sv_setsteamaccount takes a Game Server Login Token, which is what registers the server with a Steam game server account for the public browser. It costs nothing to create and belongs to a Steam account you own - Steam game server tokens explained covers making one and what gets one banned.

Installing Metamod:Source and SourceMod#

reads addons/loads on map startTF2 serversrcds, Source 1addons/metamod.vdfloaded at startupMetamod:Sourceaddons/metamodSourceModa Metamod pluginYour pluginplugins/*.smx
How a .smx plugin ends up inside TF2
  1. Download Metamod:Source and SourceMod for the same branch. They are versioned together, and mixing a current SourceMod with an old Metamod is the first thing to check when nothing loads.
  2. Unpack both so their addons folders land in tf/. You should end up with tf/addons/metamod/ and tf/addons/sourcemod/.
  3. Make sure tf/addons/metamod.vdf exists. It is a two-line file naming the Metamod binary, relative to the game root:
tf/addons/metamod.vdf
"Plugin"{	"file"	"../tf/addons/metamod/bin/server"}
  1. Restart the server and run meta list, then sm version.

The path in that VDF is the part people get wrong. It is relative to the directory above tf, which is why it starts with ../tf/. Since TF2's move to 64-bit binaries, the server library lives in a linuxsteamrt64 subfolder, so on a current install the path has that extra element and you need the Metamod and SourceMod builds that ship 64-bit binaries. If meta list produces nothing at all, this is almost always why: the right files, the wrong path, or 32-bit builds on a 64-bit server.

code
tf/addons/sourcemod/  configs/    admins_simple.ini    admins, the simple way    admins.cfg           admins, the grouped way    admin_groups.cfg     groups and their flags    admin_levels.cfg     what each flag letter means    databases.cfg        database connections    maplists.cfg         which map list each plugin uses    core.cfg             SourceMod itself  plugins/               .smx files that load  plugins/disabled/      .smx files that do not  extensions/            native extensions  gamedata/              offsets and signatures per game  logs/                  errors_YYYYMMDD.log  scripting/             .sp sources and the compilertf/cfg/sourcemod/        generated per-plugin configs

Two of those folders explain most support questions. plugins/disabled/ is where you move a plugin instead of deleting it, and logs/errors_*.log is where the reason it did not load is written in plain English, which the game console rarely manages.

Admins: the file, the flags, the immunity#

The simple admin file is one line per person: an identity, then immunity and flags.

tf/addons/sourcemod/configs/admins_simple.ini
// "identity"          "immunity:flags""STEAM_0:1:123456"     "99:z""STEAM_0:0:987654"     "50:abcdefgj""STEAM_0:1:555555"     "20:bcj"

The number before the colon is immunity: a higher number cannot be kicked, banned or slain by a lower one. The letters after it are the flags.

FlagGrants
aReserved slot
bGeneric admin. Most plugins check this first
cKick
dBan
eUnban
fSlay and slap
gChange map
hChange cvars
iExec configs
jAdmin chat and messages
kStart votes
lSet the server password
mRCON through SourceMod
nEnable cheats
o to tCustom, defined by individual plugins
zRoot. Everything, including flags that do not exist yet

Give yourself z, give the people who run evenings bcdefgj, and give the person who joined last month bcj. The two flags to think twice about are m and n: m is RCON, which is the whole server, and n enables cheats, which on a public server is the end of the server.

Identities can be a SteamID, an IP address, or a name with a password, and SteamID is the only one that means anything. The format SourceMod wants is the one status prints in the console for a connected player, so paste rather than retype. sm_reloadadmins re-reads the file with no restart.

For a group with more than a handful of staff, admin_groups.cfg plus admins.cfg lets you define a "Moderator" group once and put people in it, which beats editing twelve lines of flags when you change your mind. Anything larger than that, or anything spanning several servers, wants the database-backed admin system instead, configured in configs/databases.cfg:

tf/addons/sourcemod/configs/databases.cfg
"Databases"{	"default"	{		"driver"	"default"		"host"		"your-db-host"		"database"	"sourcemod"		"user"		"generated-user"		"pass"		"generated-password"	}	"storage-local"	{		"driver"	"sqlite"		"database"	"sourcemod-local"	}}

The panel's database slot gives you a host, a database name, a user and a password, and those four values are all this file wants. If you only need bans to survive a restart on one server, the storage-local SQLite entry above needs no database at all and is already there.

CommandEffect
sm_adminOpens the admin menu in game
sm_kick <target> [reason]Kick
sm_ban <target> <minutes> [reason]Ban. 0 is permanent
sm_addban <minutes> <steamid>Ban somebody who is not connected
sm_unban <steamid>Lift a ban
sm_gag / sm_mute / sm_silenceText, voice, or both
sm_slay / sm_slap <target> [damage]Kill, or hurt and shove
sm_map <map> / sm_votemap <map...>Change map, or vote on it
sm_cvar <cvar> [value]Read or set a cvar
sm_whoWho is connected and what access they have
sm_reloadadminsRe-read the admin files
sm plugins listWhat is loaded
sm plugins reload <name>Reload one plugin

Targets accept #userid, a partial name, @all, @blue, @red, @me and @!me, which is worth knowing before you slay the wrong person in front of twenty-four people.

The plugins that ship with SourceMod#

A fresh SourceMod install already includes most of what a public server needs, and people install third-party plugins to replace things they already have. What is in the box:

  • Admin commands, the admin menu, bans and communication controls - basecommands, adminmenu, basebans, basecomm, basechat.
  • Map votes and rotation - mapchooser runs an end-of-map vote, rockthevote lets players call one, nominations lets them nominate, nextmap answers say nextmap, randomcycle picks at random instead.
  • Quality of life - reservedslots, antiflood, basetriggers for say timeleft, funcommands and funvotes for the silly ones, clientprefs so plugins can remember a player's settings.

Every one of those generates a config file in tf/cfg/sourcemod/ the first time it loads, with every cvar it owns, its default and a comment explaining it. That folder is the actual documentation, and reading plugin.mapchooser.cfg beats searching for a forum post from 2013. The vote threshold for rock the vote, how many minutes before the end the map vote starts, whether extending the map is allowed - all of it is there with defaults.

Which maps those plugins offer comes from configs/maplists.cfg, which by default points them at the server's mapcyclefile. Set mapcyclefile "mapcycle.txt" in server.cfg, put one map name per line in tf/cfg/mapcycle.txt, and votes, nominations and the rotation all agree with each other. A short list of maps people like beats a long list where two thirds get skipped.

Plugins worth adding#

PluginWhat it does
TFTrueCompetitive whitelists, tournament features, logs.tf uploading. Loaded with plugin_load, not through SourceMod
F2's stats pluginssupstats2, medicstats and the logs.tf uploader: the standard set behind every match log you have read
SOAP TF2DMDeathmatch spawns and instant respawn for scrim and pug servers
TF2Items and TF2AttributesChange weapon attributes. The base most custom-weapon plugins build on
Versus Saxton Hale / Freak Fortress 2The boss modes that keep 24-slot servers full
UpdaterKeeps plugins that support it up to date automatically

Resist the urge to install thirty. Every plugin is code running in your game server that has to be re-tested after every TF2 update, and a server with six plugins that work is better than a server with thirty where two are quietly throwing errors into a log nobody reads. Install a plugin because a specific thing is wrong, not because it looked interesting.

Plugins are ordinary files, so the file manager or SFTP is all you need - SFTP and the file manager has the connection details. Drop the .smx into addons/sourcemod/plugins/, change map or run sm plugins load <name>, and check sm plugins list. Plugins distributed as .sp source need compiling, either with spcomp in addons/sourcemod/scripting/ or with the web compiler on the SourceMod site. The general hygiene argument is in keeping a modded server clean, and it applies here: a plugin runs with the server's full privileges and no sandbox.

Server cvars TF2 actually cares about#

tf/cfg/server.cfg
hostname "Longship TF2 // No crits // EU"rcon_password "a-long-random-string"sv_password ""sv_lan 0sv_region 3sv_tags "nocrits,vanilla,eu"sv_visiblemaxplayers -1// Roundsmp_timelimit 30mp_winlimit 0mp_maxrounds 0mp_bonusroundtime 8mp_autoteambalance 1mp_teams_unbalance_limit 1mp_disable_respawn_times 0mp_idlemaxtime 5mp_idledealmethod 2// Gameplaytf_weapon_criticals 1tf_damage_disablespread 0tf_use_fixed_weaponspreads 0tf_bot_quota 0// Contentsv_pure 1sv_pure_kick_clients 1sv_allowupload 0sv_allowdownload 1sv_downloadurl ""net_maxfilesize 64// Housekeepingmapcyclefile "mapcycle.txt"sv_hibernate_when_empty 1sv_hibernate_postgame_delay 30// SourceTVtv_enable 1tv_port 27020tv_delay 90tv_name "Longship STV"

Three of those decide what kind of server you are running. tf_weapon_criticals 0 turns off random critical hits, which is the single most divisive setting in the game and belongs in your server name either way. tf_damage_disablespread 1 and tf_use_fixed_weaponspreads 1 are the competitive damage settings, and turning them on quietly on a public server confuses regulars who cannot say why the rocket launcher feels different. mp_disable_respawn_times 1 produces the fast, chaotic server a lot of communities are actually after.

mp_idlemaxtime 5 with mp_idledealmethod 2 kicks players idle for five minutes, which on a 24-slot server is the difference between full and full of nobody. Set method 1 to move them to spectator instead if you would rather be gentle.

sv_hibernate_when_empty 1 drops an empty server to almost no CPU, which matters when a plan buys a share of a core rather than a whole one. SourceTV is a second port and a second process: it lets people spectate live and records demos, and it is the reason the TF2 plans here come with three port allocations rather than one - game, SourceTV, and one spare for whatever you add next. RCON runs over TCP on the game port and needs -usercon; the panel console is the safer way in, for the reasons in using RCON safely.

Bots are tf_bot_quota with tf_bot_quota_mode fill, tf_bot_difficulty from 0 to 3, and tf_bot_add. They need a navigation mesh for the map, which official maps ship and custom maps mostly do not; the server can generate one with nav_generate, which takes a while and produces bots that walk into walls on complicated geometry.

Custom content, sv_pure and fast downloads#

sv_pure 1 makes clients use the server's version of game content instead of their own, with exceptions listed in tf/pure_server_whitelist.txt. It is how you stop people running a flat-white texture pack that makes everyone glow. sv_pure 2 is stricter and breaks a lot of harmless customisation, including HUDs people rely on, so 1 with a sensible whitelist is where most servers land. sv_pure_kick_clients 1 removes clients that refuse rather than trying to reconcile.

Custom maps have to reach the player. The engine's own download works with sv_allowdownload 1 and is slow enough that people disconnect during it. The fix is sv_downloadurl pointing at a web server that mirrors the server's folder structure - maps/, sound/, materials/, models/ - ideally with bzip2-compressed copies of each file. Any static host serves it, including a small web hosting plan; it is a folder of files over HTTP. The mechanism is the same one Garry's Mod uses, and workshop content and FastDL goes through the folder layout in detail.

sv_allowupload 0 is deliberate in that config. Client uploads were how custom spray images arrived, and they were also a long-running source of trouble. Turning uploads off costs sprays and removes a whole category of problem.

Updates, 64-bit, and keeping the thing running#

TF2 updates break SourceMod. Not always, but often enough that it should be a planned event rather than a surprise. The failure is usually gamedata: SourceMod finds functions in the game by signature, an update moves them, and a plugin that depends on one throws an error the moment it is used. The fixes, in order:

  1. Update SourceMod's gamedata. AlliedModders ships gamedata updates separately from full releases, and the updater plugin can fetch them for you.
  2. Update Metamod:Source and SourceMod to the current builds of the branch that matches your server's architecture.
  3. Update the individual plugin, or move it to plugins/disabled/ and live without it until its author returns. Some never do.

The 64-bit transition is the version of this everybody hit at once: TF2 gained 64-bit server binaries and every 32-bit Metamod and SourceMod install stopped working until the builds caught up. If you are installing today, take current builds of both and check they are the ones with 64-bit binaries.

The habit that makes all of this cheap is keeping a copy of the working addons folder somewhere that is not the server, so a restore is a file copy rather than a reinstall. What to do when a mod update breaks is the general procedure. On RE:NODE the update runs when the server starts, so taking an update is a decision you make by restarting, backup slots are included on every TF2 plan, and the Schedules tab will run a daily backup and a nightly restart on a cron expression. If the container hits its memory limit it is stopped and restarted clean rather than left to swap, which is a better outcome than an hour of a server that technically responds.

Troubleshooting#

`meta list` prints nothing. tf/addons/metamod.vdf is missing, or its path is wrong, or the builds are 32-bit on a 64-bit server. Check the file exists, then check the path inside it matches where the binary actually is.

Metamod loads but `sm version` does nothing. SourceMod is unpacked in the wrong place. It belongs in tf/addons/sourcemod, not addons/sourcemod at the root.

A plugin loads but its commands say "unknown command". Admin flags. Run sm_who on yourself, check admins_simple.ini has your SteamID exactly as status shows it, and run sm_reloadadmins.

Everything worked until the update. Gamedata. Update SourceMod, then the plugins, then start disabling.

Map votes offer the wrong maps. configs/maplists.cfg is pointing at a different list than you think. By default it follows mapcyclefile.

The server is empty and the CPU graph is flat at the limit. A plugin is running work on a timer with nobody connected, or hibernation is off. Set sv_hibernate_when_empty 1 and unload plugins one at a time.

Players cannot download a custom map. Either sv_downloadurl is wrong, or the file is not at the mirrored path, or net_maxfilesize is smaller than the file. Try the URL in a browser: it should download the file directly.

FAQ#

Do I need Metamod as well as SourceMod?

Yes. Metamod:Source is the loader that gets SourceMod into the game process; SourceMod is the plugin platform. Neither does the other's job, and they must be matching builds for the same architecture.

Where do I add myself as an admin on a TF2 server?

tf/addons/sourcemod/configs/admins_simple.ini, one line with your SteamID and "99:z" for full access. Run sm_reloadadmins in the console, then type sm_admin in game to open the menu.

Does SourceMod work on Counter-Strike 2?

No. SourceMod supports Source 1 games such as TF2, Counter-Strike: Source and CS:GO. CS2 runs on Source 2 and uses CounterStrikeSharp instead, which is a different platform with different plugins.

How much RAM does a TF2 server need?

Two gigabytes covers a full 24-slot server with a normal plugin set. Custom modes that hold state for every player want three or four. Disk is the tighter constraint: the install alone is upwards of 15 GB.

How do I turn off random crits?

tf_weapon_criticals 0 in server.cfg. No plugin needed. Put it in the server name and in sv_tags as well, because it is the first thing people filter on.

Why do my plugins stop working after a TF2 update?

Because SourceMod locates game functions by signature and an update moves them. Update SourceMod's gamedata first, then Metamod and SourceMod themselves, then the individual plugins.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000