The dodgeball gamemode for TF2 SourceMod servers. Pyros airblast homing rockets at each other. Last team alive wins. Built on years of community work and packaged for modern servers.
Quick install · What's in the box · Subplugins · For plugin developers
One required core plugin plus 13 optional modules. Install only what you want.
| Plugin | What it does |
|---|---|
Core (dodgeball.smx) |
The game itself — rockets, airblast, deflection, bouncing. Required. |
| Guardian | One player becomes a boss with extra HP and special abilities. Everyone else fights them. Beta — framework solid, design not fully fleshed out. |
| PlayerVsBot | An AI bot that learns as it plays. You can fight it 1-vs-1 or watch bots train each other. |
| DeathMatch | Keeps small servers alive — when a team would lose, swap a player or respawn a soloer. |
| AntiCheat | Catches obvious public-tier cheats. Beta — read the warning before enabling. (Needs more testing) |
| FFA | Free-for-all mode. Friendly fire on. Coexists with DeathMatch. |
| Votes | Players can vote to toggle bouncing rockets, change rocket class, etc. |
| Menu | In-game admin menu for tuning rockets without editing files. |
| Speedometer | Shows current rocket speed in MPH on the HUD. |
| Trails | Visual particle and sprite trails on rockets. |
| Pretty chat formatting for kill events. | |
| ExtraEvents | Adds on destroyed event for rockets that explode without killing. |
| AntiSnipe | Stops players from interfering with rockets at long range. |
Anything you don't want? Just don't install its .smx file — or move it to plugins/disabled/.
- 4 new modes: Guardian, PlayerVsBot, DeathMatch and a beta cheat detector.
- Rockets feel more consistent across server tickrates (66 / 100 / 128).
- Bouncing simplified — pure physics reflection plus an optional height clamp.
- Crit glow customization — stack 1-10 fake-crit particles per class. Override the particle name per team.
- Modes don't fight each other — Guardian / PvB / DeathMatch refuse to run together (they all play with team layout). FFA pairs with DeathMatch only.
- Three old plugins built into the core (Airblast Prevention, Anti-Switch, NoBlock). Same settings, just live in
general.cfgnow.
- SourceMod 1.12+ with MetaMod:Source
- Plus dependencies if you use specific modules:
- Guardian needs TF2Attributes
- AntiSnipe needs CollisionHook
- Download the latest release from the Releases page
- Extract the
TF2Dodgeball/folder into your server'stf/directory (merge with existing folders) - If you're using Guardian or AntiSnipe, install the matching extension from the links above
- Restart the server or change to a map prefixed
tfdb_,db_ordbs_
The gamemode activates automatically on dodgeball-prefixed maps. Workshop maps are supported.
Move its .smx file to addons/sourcemod/plugins/disabled/. Nothing else needs to change.
Most servers don't need to touch the configs — defaults are reasonable. If you want to customize:
Defines rocket classes (speed, damage, turn rate, bouncing). Has built-in features for push prevention, target lock and noblock. The shipped file is commented and organized top-down by how often you'd change a setting.
For the full reference with every field explained plus rocket-design recipes (sniper, boulder, nuke, Damizean classic, competitive default), see configs/dodgeball/guide.md.
Want a different setup on tfdb_stadium_b3? Create configs/dodgeball/tfdb_stadium_b3.cfg and override only the values you want changed. Everything else inherits from general.cfg.
Use sm_tfdb (admin only) to adjust speed / turn rate / drag / damage etc. without editing files. Changes apply on the next rocket spawn.
Click a section to expand details.
Guardian — 1-vs-all boss mode
One player per round becomes the Guardian. They get extra HP, a boss health bar, a glow effect and two special abilities you pick from a list. Everyone else fights them.
The Guardian gets picked at random each round, weighted by class. Players can opt out of being chosen with sm_guardian. Guardian rounds skip when bots are on the server, when FFA is active or when fewer than 2 players qualify.
⚠️ Beta — working but not finished.The framework is solid (selection, abilities, opt-out, mutex with other modes) but the design isn't fully fleshed out. Class balance is rough, the ability set is short (5 types) and there's no late-round catch-up logic if the Guardian falls behind. Plays well as a "occasional change of pace" round but isn't tuned for competitive league use yet. Expect class tuning and ability additions in future releases.
Commands
| Command | Permission | What it does |
|---|---|---|
sm_forceguardian <player> [class] |
CONFIG | Force a specific player to be Guardian next round |
sm_guardianclass <class> |
CONFIG | Set the class for next round's Guardian |
sm_removeguardian |
CONFIG | End the current Guardian round early |
sm_guardian |
Public | Toggle whether you can be picked |
Configured via configs/dodgeball/guardian.cfg. You define classes (HP, weight, abilities) and the plugin picks one each round.
Available abilities: rage (airblast boost), sprint (speed), charge (faster speed), pounce (jump forward), slow (slow nearby enemies in a ring).
Available buttons: TAUNT (G), RELOAD (R), ATTACK3 (middle mouse), USE (H).
Example class config
"berserker"
{
"name" "Berserker"
"health" "5000"
"weight" "100" // higher = more likely to be picked
"ability_1"
{
"type" "pounce"
"button" "ATTACK3"
"cooldown" "10.0"
"duration" "5.0"
"arg1" "1200.0" // forward force
"arg2" "600.0" // upward force
"particle" "utaunt_multicurse_teamcolor_blue"
}
"ability_2"
{
"type" "slow"
"button" "RELOAD"
"cooldown" "15.0"
"duration" "10.0"
"arg1" "500.0" // radius
"arg2" "50.0" // 50% slow
"particle" "utaunt_hands_teamcolor_blue"
}
}
PlayerVsBot (PvB) — AI bot that learns as it plays
A Pyro dodgeball bot. It actually gets better the more it plays — remembers your tricks, adapts its reactions, learns where it tends to die on each map.
Ships with 4 default classes: Universal, Statue, Midrange, Aggressive. Players can vote which one they want to fight via sm_votepvb. Solo players get an instant pick menu when they're alone with the bot.
The bot stores everything it learns in a SQLite database — you can reset it with sm_resetbrain whenever. Server crashes don't lose much because the bot saves what it learned every round.
Commands
| Command | Permission | What it does |
|---|---|---|
sm_votepvb / sm_votebot / sm_botvote |
Public | Vote for a bot type or vote to disable the bot |
sm_botmenu |
Public | Open info menu — stats and current bot |
sm_botstats |
Public | Print current bot stats in chat |
sm_pvb / sm_spawnpvb |
KICK | Admin force-toggle (skips the vote) |
sm_setbottype <index> |
KICK | Force a specific bot class |
sm_reloadbotcfg |
CONFIG | Reload pvb.cfg without changing maps |
sm_trainbots |
ROOT | Spawn training bots (bots fight each other; humans can join any team or watch) |
sm_stoptraining |
ROOT | End training mode and remove the bots |
sm_resetbrain |
ROOT | Wipe everything the bot has learned |
Brain inspection (all ROOT) — peek at what the bot has learned:
| Command | What it does |
|---|---|
sm_brainstats |
Quick summary of how much the bot has learned so far |
sm_brainshow <key> |
Show the bot's preferences for one specific situation |
sm_brainopponent <player> |
Dump everything the bot has learned about one player |
sm_brainheatmap [class] |
Save a danger map to a log file — see where bots tend to die |
sm_botdebug [rate] / sm_stopdebug |
Detailed bot decision logging (very verbose). Saves to logs/tfdb_pvb/. |
Bot configuration trick (capability-by-presence)
You can disable a bot's behavior just by removing the relevant key from pvb.cfg. The bot literally loses that ability — not "0% chance", actually gone.
| Remove these keys | Result |
|---|---|
orbit_time, orbit_max_loops, orbit_chance |
Bot never orbits |
evade_chance |
Bot never jumps or crouches to evade |
All four cqc_*_dist keys |
Bot ignores close-quarters distances |
idle_chance |
Bot never stands still |
idle_chance "100" (set to 100) |
Bot stands still permanently (statue mode) |
AntiCheat — server-side cheat detection (beta)
Catches obvious public-tier cheats by watching for impossible aim angles, robotic timing patterns and silent-aim signatures. Three modes: log only, kick or ban. Default is log only.
⚠️ Honest warning — this plugin is beta.It hasn't been tested at scale. We tuned it on a small group of skilled testers and three detectors (SnapAim, ConsistentTiming, PerfectStreak) had to be zeroed because they kept flagging legit competitive players. The remaining detectors carry varying false-positive risk against high-skill players.
Until your server has weeks of log-only data covering your actual playerbase, do not enable kick or ban actions. Run
tfdb_ac_action 0, review the logs inaddons/sourcemod/logs/tfdb_ac/, see which detections fire on your trusted regulars, raise thresholds or zero weights for any detector that flags them, then move to kick. Ban only after kick has been clean for weeks.Set
tfdb_ac_immunity_flagto a flag your trusted players hold so they don't trip detection while you're collecting data.This catches obvious cheats. It is not a polished anti-cheat product. Expect to tune it.
Detection categories:
| Detection | Catches | Default weight |
|---|---|---|
AntiAim |
Pitch outside ±89° (engine-impossible) | 5 |
ReactTimeFloor |
Deflect below 80ms reaction (with 3-streak gate) | 5 |
OneTickM2 |
Airblast held for exactly 1 tick × 3 in a row | 6 |
DragSnapback |
Snap-airblast-snap-back pattern | 4 |
AirblastFacing |
3 deflects in a row while not facing the rocket | 4 |
SnapAim |
(zero weight, logs only — too FP-prone) | 0 |
Cvars — auto-created in cfg/sourcemod/tfdb_anticheat.cfg.
| Cvar | Default | What it does |
|---|---|---|
tfdb_ac_enabled |
1 |
Master toggle |
tfdb_ac_action |
1 |
0 log only, 1 kick, 2 ban |
tfdb_ac_action_threshold |
60 |
Score needed before action fires |
tfdb_ac_react_floor_ms |
80 |
Reaction-time floor in milliseconds |
tfdb_ac_ban_duration |
1440 |
Ban length in minutes (0 = permanent) |
tfdb_ac_immunity_flag |
b |
Admin flag granting immunity |
tfdb_ac_admin_hud |
1 |
Show live scores to admins |
tfdb_ac_log_level |
1 |
0 silent, 1 detections, 2 verbose, 3 debug |
Commands
| Command | Permission | What it does |
|---|---|---|
sm_ac_status |
BAN | Show live suspicion scores for all players |
sm_ac_reset <player> |
ROOT | Reset detection counters for one player |
sm_ac_debug_player <player> |
ROOT | Toggle detailed CSV logging for one player |
Companion plugin tfdb_ac_debug.smx provides per-client logging for triage.
FFA — free-for-all mode
Friendly fire on. Rockets target everyone regardless of team. Toggled via vote (sm_voteffa) or admin command.
Coexists with DeathMatch. Mutually exclusive with Guardian and PvB — those modes assume normal RED/BLU team layout that FFA's neutral mode breaks.
DeathMatch — Never-Ending Rounds + Solo queue
Solves the "small server with empty rounds" problem two ways. Based on Mikah's NER/SOLO Standalone plugin, rewritten for 2.2.0.
- Never-Ending Rounds (NER) — when a team would lose, a player from the winning team gets swapped over so the round keeps going.
- Solo queue — players can opt out with
sm_solo. They die immediately and respawn whenever a team needs someone.
After any DeathMatch respawn, players get a brief damage-immunity window. A horn plays to signal it.
Coexists with FFA. Mutually exclusive with Guardian and PvB.
Commands
| Command | Permission | What it does |
|---|---|---|
sm_solo |
Public | Toggle solo (join or leave the queue) |
sm_votedm |
Public | Vote to toggle DeathMatch |
sm_dm |
CONFIG | Admin toggle (skips vote) |
Cvars
Auto-created in cfg/sourcemod/tfdb_deathmatch.cfg.
| Cvar | Default | What it does |
|---|---|---|
tfdb_dm_ner_enabled |
1 |
Enable NER feature |
tfdb_dm_ner_force |
0 |
Force NER on (cannot be disabled by vote or admin) |
tfdb_dm_ner_force_start |
0 |
Turn NER on at map start |
tfdb_dm_ner_vote_timeout |
120 |
NER vote cooldown in seconds |
tfdb_dm_solo_enabled |
1 |
Enable solo queue |
tfdb_dm_solo_priority |
1 |
Respawn soloers before swapping alive players |
tfdb_dm_horn_volume |
0.5 |
Volume of the respawn horn (0–1) |
tfdb_dm_respawn_protection |
2.0 |
Damage immunity duration after respawn (seconds) |
Votes — let players vote on rocket settings
Players can vote to toggle features mid-match. Each vote command has a 10-second per-player cooldown so spammers can't chain votes.
Commands (all Public)
| Command | Aliases | What it does |
|---|---|---|
sm_vrb |
sm_votebounce |
Vote to toggle bouncing rockets |
sm_vrc |
sm_voteclass |
Vote to change the rocket class |
sm_vrcount |
sm_votecount |
Vote to change how many rockets spawn at once |
sm_vrp |
sm_votepreset |
Vote for a preset from presets.cfg |
Speedometer — rocket speed HUD
Shows current rocket speed in MPH. Players can toggle it for themselves with a cookie that sticks across sessions.
Commands (Public)
| Command | Aliases | What it does |
|---|---|---|
sm_speedhud |
sm_shud |
Toggle the speed HUD on/off |
Trails — visual rocket trails
Particle and sprite trails on rockets. Configured per rocket class in general.cfg (look for the trail fields — commented out by default; see guide.md for enabling).
Commands (Public, per-player toggle)
| Command | Aliases | What it does |
|---|---|---|
sm_rockettrails |
sm_hidetrails, sm_toggletrails |
Toggle particle trails for yourself |
sm_rocketsprites |
sm_hidesprites, sm_togglesprites |
Toggle sprite trails for yourself |
AntiSnipe — block long-range rocket interference
Stops players from hitting rockets at very long distance. Requires the CollisionHook extension. If the extension is missing, the plugin warns at load time and falls back to damage-based mode.
Menu — in-game admin tuning
In-game menu for adjusting dodgeball settings without editing config files. Live reload picks up changes you make to general.cfg on disk. Per-class feel knobs (speed, turn rate, damage, drag, bounce) are tunable live and apply on the next rocket spawn.
| Command | Permission | What it does |
|---|---|---|
sm_tfdb |
CONFIG | Open the admin menu |
ExtraEvents — additional rocket events
Adds the on destroyed event for rockets that explode without killing a player. Required if your rocket class configs use that event in general.cfg.
Print — pretty chat formatting
Provides server commands used by rocket event strings (on kill, on spawn kill) for colored chat messages with player-name substitution. See guide.md for the color tag list and the ##@owner## substitution syntax.
Plugin not loading or activating
Dodgeball not activating — The gamemode only activates on maps prefixed tfdb_, db_ or dbs_. Check dodgeball.smx is loaded with sm plugins list in server console.
A subplugin not loading — Make sure its .smx is in addons/sourcemod/plugins/ (not the Subplugins/ source folder). Check sm plugins list and the SourceMod error log.
TF2Attributes errors — You need both tf2attributes.smx (the extension) AND gamedata/tf2.attributes.txt. Guardian needs both. Download from FlaminSarge/tf2attributes.
Rockets misbehaving
Rockets not homing — Check general.cfg has "behaviour" "homing" on your rocket class. Make sure dodgeball_enable.cfg is being executed.
Rockets feel sticky after deflect — Lower "steering control" (defaults around 0.045 seconds). Set "control delay" to 0 for immediate homing after deflect.
Nuke rocket shows as ERROR / red cube — Your server has sv_pure 1 blocking the custom model. Either add models/custom/dodgeball/ to your pure whitelist, or remove the "model" field from the nuke class so it uses the default rocket model.
Guardian not triggering
Guardian is automatically blocked when:
- Bots are on the server (kick them first with
kickall botor via PvB if running) - FFA is active
- PvB is active
- Fewer than 2 eligible players are present
Check logs/tfdb_guardian/select.log for detailed reasons.
Abilities not working — They unlock after arena_round_start fires (when players can move). Check your guardian.cfg has valid ability types and buttons.
PvB issues
Bot replaced by a dumb vanilla bot after map change — Your server has tf_bot_quota_mode fill or match. PvB sets it to normal automatically but some map configs override it. Add sm_cvar tf_bot_quota_mode normal to cfg/sourcemod/dodgeball_enable.cfg.
Players spawning on the bot's team briefly — Should be fixed in 2.2.0. If it happens, confirm tfdb_pvb.smx loaded successfully (check sm plugins list).
AntiCheat false positives
Run with tfdb_ac_action 0 (log only) for a few weeks before enabling kick or ban. Review per-player score distributions in logs/tfdb_ac/. Raise tfdb_ac_action_threshold if pros trip the threshold legitimately. Read the AntiCheat section above for the full deploy guide — this plugin is beta.
DeathMatch issues
sm_dm says "cannot activate" — DeathMatch refuses when Guardian or PvB is active. Disable those first or wait for the round to end.
Cosmetics wrong color after team swap — Should be fixed in 2.2.0. If you still see it, a manual respawn resolves it.
NER feels different in FFA — By design. FFA neutralizes teams, so NER respawns players in place rather than swapping sides.
The rest of this README is for people writing SourceMod plugins on top of TFDB. If you're just running a server, you can stop reading here.
Include the relevant header in your plugin:
| Include | What it gives you |
|---|---|
<tfdb> |
Core API: 130+ natives for rocket manipulation, 11 forwards for events |
<tfdb_guardian> |
State-query natives for Guardian |
<tfdb_pvb> |
State-query natives for PlayerVsBot |
<tfdb_deathmatch> |
State-query natives for DeathMatch |
<tfdb_ffa> |
State-query natives for FFA |
<tfdbtrails> |
API for the Trails subplugin |
<tfdb_clientcheck> |
Six client-state predicate stocks (real human, playing, alive, spectator, bot, etc.) |
Core API quick reference
#include <tfdb>
// Game state
TFDB_IsDodgeballEnabled()
TFDB_GetRoundStarted()
TFDB_GetRocketCount()
// Rocket manipulation
TFDB_GetRocketSpeed(int iIndex)
TFDB_SetRocketSpeed(int iIndex, float fSpeed)
TFDB_SetRocketTarget(int iIndex, int iTarget)
TFDB_GetRocketTarget(int iIndex)
TFDB_CreateRocket(int spawner, int spawnerClass, int team)
TFDB_DestroyRocket(int iIndex)Forwards
TFDB_OnRocketCreated(int iIndex, int iEntity)
TFDB_OnRocketDeflect(int iIndex, int iEntity, int iOwner)
TFDB_OnRocketDeflectPre(int iIndex, int iEntity, int iOwner, int &iNewTarget)
TFDB_OnRocketSteal(int iIndex, int iOwner, int iTarget, int iStealCount)
TFDB_OnRocketsConfigExecuted(const char[] configFile)Full reference: tfdb.inc.
Guardian, PvB, DeathMatch, FFA all expose state-query natives so other subplugins can refuse to activate when they would conflict. Your plugin compiles cleanly whether the partner is installed or not.
if (LibraryExists("tfdb_pvb") &&
GetFeatureStatus(FeatureType_Native, "TFDB_IsPvBActive") == FeatureStatus_Available &&
TFDB_IsPvBActive())
{
// PvB is running — defer or refuse to activate your mode.
}Register your own library with RegPluginLibrary("your_name") so partners can check for you the same way.
If you're building from source: compile dodgeball.sp first (it generates the natives in tfdb.inc). Then compile subplugins in any order. Subplugin source lives in Subplugins/<name>/scripting/.
Click to expand
tf/
├── cfg/sourcemod/
│ ├── dodgeball_enable.cfg ← runs when a dodgeball map loads
│ ├── dodgeball_disable.cfg ← runs when leaving a dodgeball map
│ ├── dodgeball_ffa_enable.cfg ← runs when FFA activates
│ └── dodgeball_ffa_disable.cfg ← runs when FFA turns off
└── addons/sourcemod/
├── plugins/
│ ├── dodgeball.smx ← required (core)
│ ├── tfdb_guardian.smx ← optional
│ ├── tfdb_pvb.smx ← optional
│ ├── tfdb_deathmatch.smx ← optional
│ ├── tfdb_anti_cheat.smx ← optional
│ ├── tfdb_ac_debug.smx ← optional companion to AntiCheat
│ ├── tfdb_ffa.smx ← optional
│ ├── tfdb_votes.smx ← optional
│ ├── tfdb_menu.smx ← optional
│ ├── tfdb_speedhud.smx ← optional
│ ├── tfdb_trails.smx ← optional
│ ├── tfdb_print.smx ← optional
│ ├── tfdb_extra_events.smx ← optional
│ └── tfdb_anti_snipe.smx ← optional
├── configs/dodgeball/
│ ├── general.cfg ← main rocket and game config
│ ├── guide.md ← full field reference and recipes
│ ├── guardian.cfg ← Guardian classes and abilities
│ ├── pvb.cfg ← PvB classes and tuning
│ ├── presets.cfg ← rocket class presets
│ └── tfdb_<mapname>.cfg ← per-map overrides (create as needed)
├── data/sqlite/
│ └── tfdb_pvb.sq3 ← PvB persistent learning (auto-created)
├── logs/
│ ├── tfdb_ac/ ← AntiCheat detection logs
│ ├── tfdb_guardian/ ← Guardian round + selection logs
│ └── tfdb_pvb/ ← PvB heatmap dumps and decision traces
├── gamedata/
│ └── tf2.attributes.txt ← needed for Guardian
├── translations/
│ └── tfdb.phrases.txt ← all chat strings, edit for translations
└── scripting/
├── include/ ← .inc headers (public API)
└── dodgeball.sp ← core source
| Damizean | Original YADP |
| bloody & lizzy | YADP maintenance |
| ClassicGuzzi | Dodgeball Redux |
| Oracle team | DB_Reborn (bounce reflection formula) |
| BloodyNightmare & Mitchell | Airblast Prevention (now built into core) |
| x07x08 | Major advancements (Unified branch, 2.1.0 baseline) |
| Mikah | NER/SOLO Standalone plugin (basis of DeathMatch) |
| Silorak | Current maintainer (2.2.0+) |
And the entire SourceMod community for keeping TF2 modding alive.
GPL v3.0 — see LICENSE.