the cutting room mirror

Game Modes

This article has a talk page!
view on tcrf.net

This is a sub-page of Development:Team Fortress 2/April 21st, 2020 Codebase Leak.

To do:
Add source code references for Raid Mode

Raid Mode#

Raid Mode (once called 'Squad Co-op Mode' in the code) was a PvE spin of TF2's Capture The Flag gamemode, where BLU Team were the human attackers (or 'invaders' as code comments suggest) fighting RED's AI- controlled defenders. This mode was in development from mid 2009 to early 2011, before being abandoned in favour of Creep Mode, and finally Mann vs. Machine.

In Raid Mode, 5 human controlled players on BLU team would capture control points on the map guarded by AI-controlled RED team defenders. The defenders spawned in groups, and more frequently if BLU was currently capturing a control point. Maps, models and some textures for Raid Mode were found as part of the 2023 Source Developer Asset Repository Leak.

Types of bot groups are:

Defenders: up to 18 bots. They can't spawn in regions under the attacker's control.

Wanderers: Up to 10 bots at one time are designated to be 'wanderers' who do nothing special and are scattered around the map. The behaviour file shows that wanderers were supposed to be restricted to their melee, however conditions for Demoman wanderers restrict them to the Stickybomb Launcher instead (tf2\server\tf\bot\tf_bot.cpp, line 2942).

If a BLU player kills a RED team bot near a wanderer's aggro range, the wanderer will get aggressive towards the player, with their reaction being dependant on how far away the wanderer is. Between 0 and 500 hammer units the wanderer would react immediately, between 501 and 1000 hammer units the wanderer would take up to one second to react, and the wanderer will not react at all over 1000 hammer units away. The variable "tf_raid_wanderer_reaction_factor" would multiply a wanderer's reaction time to a RED team death by the inputted value.
Wanderers are supposed to play sounds from their classes' respective "Jeers" sound bank periodically, defaulted to between 20-30 seconds. Interestingly, Scout wanderers are coded to play unique sounds, described as "Scout.WanderJabber".

Squads; Squads are spawned one at a time, and includes four specific classes: Heavy, Soldier, Pyro and Demoman. The slowest member of the squad is the designated leader, with all teammates following them. If BLU manages to reach half of the 'Maximum Incursion' distance (likely when capturing half of the control points on a raid mode map) Medic will be added to the squads, and always be picked, limiting the squads to three of the aforementioned classes, but cannot be picked to be the leader. The code used for squads in Raid Mode are used as a base for the way groups of bots are spawned in Mann vs. Machine.

Snipers: Snipers are spawned dynamically, like how spies are spawned in MvM, though are teleported into position instead of being spawned in directly. Their spawn points are invisible and follow players' incursion progress, and are hard coded to be at most 6000 hammer units from the furthest incursion progress point.

Sentry Guns Listed as a standalone category, though otherwise are functionally identical to Engineer's brand of sentry.

Mini-bosses#

(tf2\server\tf\bot_npc\bot_npc_mini.cpp, tf2\server\tf\bot_npc\bot_npc_mini.h)

A small code file dated March 2011 contains leftover code from mini-bosses for Raid Mode. Only two bosses are present called "Rockets" and "Nuker". Both have 5000 health and use the "knight_mini" model. An additional Header file contains a bit more information on the bosses. They had a movement speed of 150 hammer units per second (For reference, Pyro moves at 300 hu/s) and could be stunned after dealing 300 damage to them. The 'Rockets' boss would shoot 25 damage rockets with a .5 second firing interval. The 'Nuker' boss has definitions for 2 second firing interval grenades. Notably, MvM giants are internally referred to as Mini-bosses.

BOSS_ALPHA#

To do:
include more information from bot_npc.cpp file

BOSS_ALPHA is the internal name of a boss in Raid Mode. All the files which contain information about this boss are dated late 2010, however some are dated early 2011.


This boss is internally called BOSS_SENTRY in game files. Its attributes can be seen in boss_alpha.cpp file.

  • Invulnerable unless stunned;
  • 30000 HP;
  • 30% damage received from miniguns, sentries and grenades;
  • 50% damage received from rockets;
  • 1000% damage received when stunned (effectively turns it's HP into 3000);
  • 300 HU\s speed (default, likely placeholder);
  • 300 HU explosion radius for rockets and stickybombs.

Behavior sequences:

  • Shoots barrage of 5 rockets, interval 0.3 seconds, 25 damage, rockets are guaranteed critical when ENRAGED;
  • Taunts, then shoots sticky bombs in two ways - "rings" and "spokes", in both stickies explode in 3 seconds after launch and deal 25 damage;
  • 1. Hurls an unknown amount of stickies around itself; spins around itself when shooting, makes two spins, the first one - 10 degrees aim angle elevation, the second - 30 degrees.
  • 2. Shoots 15 stickybombs in a particular direction, but with various launch speeds, forming a "stickies beam" (yes, that's how it named in the code).
  • Reacts on player's taunt and chooses him as its target, 10 seconds refresh.
  • Makes a "FireOutput" or "FireEvent" event every 10% health lost from 90% onwards.
  • Releases "bot_minion"s;
  • Produces "nuke": revenge attack after end of stun duration, it deals direct damage and applies 5 seconds of afterburn on victims; direct damage is equal player's HP minus 60.

Another attack variation from bot.cpp file1 is "railgun", which fires a 4000 HU\s projectile arrow that isn't affected by gravity, and aims where the target is heading. Its base damage is 200 and arrows are always critical. There's also a commented out section with an alternate damage calculation, which is the current target's maximum health plus 5.

// set damage to 5 points more than our target's max health so a Medic can save us
// arrow->SetDamage( ( target->GetMaxHealth() + 5.0f ) / TF_DAMAGE_CRIT_MULTIPLIER );

skill_shot#

The only way to make boss vulnerable. There are three types of skill shots, which the team must perform in a row to successfully stun the boss, within a 10 second interval, otherwise the combo resets. The boss drops three medium ammo boxes after this event.

Skill shot types:

  • 1. Precision: hitting 3 spots within 6 seconds, every spot has its unique hit sound;
  • 2. Hard_hit: deal 40 damage to boss while being above its hitbox ~150 HU;
  • 3. Damage_sponge: deal 500 damage to boss: damage counter periodically decreases by 100.

bot_minion#

Entities that help boss_alpha fight the mercenaries. Internal name: bug_zapper;

Attributes:

  • 60 HP;
  • 50% damage vulnerability to Sentry guns;
  • 200% damage vulnerability to Sniper's primaries minus the Huntsman;
  • 300% damage vulnerability to the Huntsman;
  • 250 HU\s speed;
  • 500 HU\s acceleration;
  • 3 second uber after bot launch;
  • Vulnerable to airblast, can be pushed;
  • Drops medium ammo box after death.

Attack attributes:

These bots were supposed to paralyze mercenaries and eventually kill them. BOSS_ALPHA has logic to send minions to paralyzed victims and attack them. When an ubered player is attacked, an "energy feedback" event occurs and the bot would die with the "energy_beam" animation, which in the final game is used when robots are killed with the Projectile Shield upgrade.

  • 100HU attack range.
  • attacks players within its attack range after 1.5 seconds.
  • inflicts TF_COND_STUNNED when attacking an enemy, akin to the Supernova powerup in Mannpower.
  • 1000 damage is dealt 7 seconds after the bot has stunned an enemy.

Creep Mode#

Another abandoned MvM predecessor that takes cues form DotA 2, like how Raid Mode takes cues from Left for Dead 2. This mode is formed of "creep waves" from both teams rushing to control points in order to capture them. The human players' goal is to defend their teams' creeps while destroying enemy creeps. Killing enemy creeps gives experience and eventually levels up players. The mode was developed from mid 2010 to early 2011 and dropped in favour of Mann vs. Machine.

Bounty Mode#

Bounty Mode appears to be the halfway point between Creep Mode and Mann vs. Machine, combined with standard TF2 gamemodes such as CTF and CP. Like with Creep Mode, Bounty was scrapped early on, and information is scarce. As seen in the 2023 Source Developer Asset Repository Leaks, only one test map was made for this mode.

Players would kill both enemy players and bots to gain currency and spend on upgrades, the UI for which was tied to the spawn room's Resupply Cabinet. Players would also gain experience and level up after completing certain actions, though the use for such levels is not certain. Players lose currency on death unlike MvM, which is calculated as a percentage of unspent cash2. The coefficient for this feature however is set to zero3, rendering this code unused. A test map for Bounty was leaked as part of the 2023 Source Developer Asset Repository leaks.


ConVar tf_bountymode_currency_penalty_ondeath( "tf_bountymode_currency_penalty_ondeath", "0", FCVAR_ARCHIVE, "The percentage of unspent money players lose when they die in Bounty Mode.\n" ); 

Sappers could be attached to other players. Players could also refund both currency and experience.

Some code reveals that the game would supposed to reward players for various actions, such as capturing point or assisting players. 4

Action

Credit reward

Notes

KILLED_PLAYER

40

KILLED_OBJECT

40

Either refers to Engineer Buildings or AI controlled bots.

ASSISTED_PLAYER

20

BONUS_POINTS

1

CAPTURED_OBJECTIVE

100

ESCORT_REWARD

10

Likely refers to the Payload cart.

PACK_SMALL

5

Small MvM currency pile, possibly carried into MvM.

PACK_MEDIUM

10

Medium MvM currency pile, possibly carried into MvM.

PACK_LARGE

25

Large MvM currency pile, possibly carried into MvM.

WAVE_COLLECTION_BONUS

100

Extremely similar to the end of wave bonus in Mann vs. Machine, and was likely taken from this mode.

Some bots would spawn as giants with corresponding 'Mini-Boss' attributes5. There was supposed to be two types of bots - raiders and defenders.

Attribute\multiplier

Raider

Defender

Scale

1.75

1.75

Maximum health

5000

3300

Speed

0.5

0.5

Damage bonus

1.5

-

Reload rate

-

0.6

Fire rate

-

0 .75

Damage force reduction

0.3

0.5

Airblast vulnerability

0.3

0.5

A chunk of code lays out the experience system 6. The system scales given experience by the difference in level between the killer and victim, with the intent of rewarding low levelled players for killing high levelled ones, and handicapping high levelled players farming off of low levelled players. 400 experience is needed to level up for every level, with the cap being level 20.

Level difference between killed and killer

From -19 to -5

-4

-3

-2

-1

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Experience reward

0

8

10

13 or 14

20

40

80

120

160

200

240

280

320

360

400

440

480

520

560

600

640

680

720

760

800

Birthday Tag Mode#

There is a fair bit of code related to a Birthday Tag gamemode although the "Birthday Tag" name is unofficial, made up for the purpose of this article. The way this mode would have worked is that one player would be picked to be the "Birthday Player" and would be given particle effects to denote them as such. If the Birthday Player kills another player, the victim becomes the Birthday Player. None of this code is in staging blocks, and so would be functional in-game if the majority of the code for it was not commented out. However, since the code for this mode is quite simple, it should not be very hard to recreate with a SourceMod plugin for community servers. According to the various logic checks in this, this gamemode was seemingly meant to become active during the kHoliday_TFBirthday holiday (when the Birthday mode gets enabled ingame). The code for this mode seems to have been based off of the "It!" code for the Horseless Headless Horsemann boss.

The particle effects that would have been used to denote the Birthday Player, as seen in the C_TFPlayer:ShowBirthdayEffect function, were:

  • birthday_player_circling, attached to the player's head and set to follow the player.
  • bday_confetti. It is unclear where this effect was meant to display on the player. The function used to create this effect, DispatchParticleEffect, indicates the attachment point to be GetAbsOrigin() + Vector(0,0,32) which is the player's current standing position, with an adjustment on the Z axis of 32 units. The next parameter however is vec3_angle which is not defined anywhere. According to the actual parameters of the DispatchParticleEffect function, the 3rd parameter should be CBaseEntity *pEntity and not a vector.

Relevant Code:

References#


  1. game/server/tf/bot_npc/bot_npc.cpp, line 2363↩︎
  2. game/server/tf/tf_player.cpp, line 11814↩︎
  3. game/shared/tf_gamerules.cpp, line 581↩︎
  4. game/shared/tf/tf_gamerules.cpp, line 14410↩︎
  5. game/tf2/server/tf/bot/behavior/tf_bot_tactical_monitor.cpp, line 486↩︎
  6. game/server/tf/tf_player.cpp, line 21138-21208↩︎