Difference between revisions of "User:Zoolooman/Scripting"

From Team Fortress Wiki
Jump to: navigation, search
m (Syntax)
m (Removing user page from categories.)
 
(16 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''Scripting''' is the use of configuration files to create new keybinds and aliases automating complex behaviors and console commands.
+
<nowiki>{{rewrite}}</nowiki>
 +
Note that the word "scripts" as it is used on this page should not be confused with the .scr files that modify server behavior.
  
*Keybinds connect a key to a certain console command, such as choosing a weapon slot or saying prewritten text in chat.
+
For common scripting questions, please visit the [[Scripting Faq]] page.
  
*Aliases build new commands by executing a series of console commands whenever they are usedAn alias might define jumping and crouching as a single jump-crouch command, which can then be bound to a key.
+
==A Brief Overview of Scripts==
 +
===What are binds?===
 +
Scripts in TF2 are known by several names, including "binds," "keybinds," and "bindings." Binds are a way to attach (or ''bind'') game commands to a key.
  
==Basic Scripting Files==
+
===Aren't binds cheating?===
 +
Not in many people's opinion. Think of it this way: binds allow you to do things you could have done easily, but faster. Everyone has easy access to binds, so they don't give you any advantage over other people. Also, the developers of the game put this feature in deliberately and allow it to happen (and they really don't like cheating because it is a multiplayer game) so it is seen as a legitimate use of the game.
  
Team Fortress 2 automatically reads several game files and executes whatever keybinds and aliases are presentHere is the list of those files:
+
===Where are binds located?===
 +
The game itself stores binds in the file:
 +
<pre><Steam Folder>\SteamApps\<account_name>\team fortress 2\tf\cfg\config.cfg</pre>
 +
The commands in this file are executed every time the game starts.  Even though the user can modify this file in any text editor, it's often a good idea to add custom binds elsewhere.  To this end, there is another file where users can add their own binds:
 +
<pre><Steam Folder>\SteamApps\<account_name>\team fortress 2\tf\cfg\autoexec.cfg</pre>
 +
This file does not exist by default, but can be created by the user.  As with config.cfg, the autoexec.cfg is just a simple text file that can be edited by the userAnd just like config.cfg, the autoexec.cfg file is executed whenever the game starts.
  
*config.cfg - This is the default config file, which the game edits whenever you use the in-game menus to bind keys or change video settings. While editing the file is safe, it's simpler to leave it alone.
+
When you create your autoexec.cfg file in your favorite text editor, be sure your text editor isn't tacking on a ".txt" to the end of the filename as is default with notepad (i.e. autoexec.cfg.txt), as that will not be auto-executed. It might not even be accessible from the console!
  
*autoexec.cfg - This is the default config file for executing custom keybinds and aliases. You may put your keybinds directly into this file, but it is often easier to create separate .cfg files for different scripts, which you then execute inside this file.
+
A good way to make sure that your autoexec.cfg file is not named incorrectly is to have your operating system show all file extensions of known filetypes. Googling found this page [http://www.granneman.com/techinfo/windows/showextensions/] which gives good graphical instructions on exactly how to do that.
  
*<class>.cfg - Each class has a config file which automatically runs whenever you switch to that class. You may put your keybinds directly into this file, but it is often easier to create separate .cfg files for different scripts, which you then execute inside these files.
+
===Using Scripts===
 +
Putting a script in autoexec.cfg will apply that script to every class, so if there's a class you don't want to use the script, you have to counter it in the specific <class>.cfg file.
 +
Also, putting a script in <class>.cfg will also apply it to every class, so you have to counter it in the other classes too. For example, if you bind 'mouse2" to "reload" in 'Engineer.cfg', but you want it to be bound to something else in the other classes, you have to re-bind "mouse2" to "something else" in all the other '(class).cfg' files.
  
==Syntax==
+
===Syntax===
 +
For any key binding or alias binding script within the Source engine developer console, the following format must be followed:
 +
COMMAND <argument1> <argument2>
  
Here is a list of syntactic rules:
+
Quotation marks are NOT necessary for binds and aliases with singular arguments, such as '''bind 1 slot1'''.
 +
However, if you wish to create a bind whose arguments may have multiple commands or parameters, you must enclose the plural arguments with quotation marks and separate the individual components with semicolons, such as '''alias melee1 "slot3; +attack"''' (creates a new "command," the alias "melee1," to automatically switch to your melee weapon and start attacking).
  
*For any keybind or alias to work, you need to follow this format:
+
Examples:
 +
<pre>
 +
COMMAND  <argument1>    <argument2>
 +
alias   qBetween1and2  "slot2; wait 10; slot1"
 +
bind    1              qBetween1and2
 +
</pre>
 +
Note: I spaced the arguments out so you could see what applies to what, don't do this when you script.
  
:'''command <argument1> <argument2>'''
+
===How are simple binds written?===
 +
A simple bind takes the form of ''bind <key> <command>''. For example, if we wanted to activate our primary weapon whenever we press the '''1''' key, then we could write a bind that looks like this:
 +
<pre>bind 1 slot1</pre>
 +
:("slot1" is the command to activate your primary weapon)
 +
Each bind must be written to a separate line in the autoexec.cfg file.  For an example of basic keybinds, look at your config.cfg file in any text editor.  For a list of useful commands, see the "Console Commands" section of this page.
  
:*command is the type of script you're makingYou have three choices:
+
===How are complex binds written?===
 +
Complex binds take the same form as simple binds, except that they execute multiple commands when you press the key.  Each command must be separated by a semicolon (''';''').  For example, let's take a look at this complex bind for an Engineer (swiped from Patty on the TF2 boards):
 +
<pre>bind "q" "build 0; wait 50; +attack; wait; -attack; slot1"</pre>
 +
:This bind attaches a series of commands to the '''q''' keyWhen the user presses the '''q''' key, the following series of commands is executed in order:
 +
:*'''build 0''' tells the game to enter the build mode for a Dispenser
 +
:*'''wait 50''' tells the game to wait 50 frames before executing the next command
 +
:*'''+attack''' tells the game to start and continue the primary attack (we will learn more about plus and minus commands a little later)
 +
:*'''wait''' tells the game to wait a moment before executing the next command
 +
:*'''-attack''' tells the game to end the primary attack
 +
:*'''slot1''' tells the game to activate the primary weapon (in the case of the Engineer, this is the Shotgun)
  
::*bind - Used to bind commands to a particular key.
+
===How do plus(+) and minus(-) commands work?===
::*alias - Used to execute commands when the alias is executed.
+
Plus and minus commands are two-state commands.  The plus state is executed (and continues to execute) while the key is pressed. The minus state executes when the key is released.  For example:
::*exec - Used to execute commands automatically when a configuration file is loaded.
+
<pre>bind "c" "+duck"</pre>
 +
:This bind causes the player to duck and remain crouched as long as the '''c''' key is pressed.  When the '''c''' key is released, the player stands again.
 +
It is important to note that, although the '''-duck''' command is never explicitly mentioned in the bind, it will still be executed upon release of the key.
  
:*<argument1> is either the key being bound or the name of the alias being created.
+
===What are aliases and how are they written?===
 +
Aliases are similar to binds except that, instead of binding a series of commands to a key, they allow the user to name a series of commands.  That name can later be used in place of the series of commands.  Using the Engineer example above, for example:
 +
<pre>
 +
alias "buildDispenser" "build 0; wait 50; +attack; wait; -attack; slot1"
 +
bind "q" "buildDispenser"
 +
</pre>
 +
:This alias followed by a keybind begins to show the power of the scripting system for TF2.  We have created an alias called '''"buildDispenser"''' (although we could just as easily have called it "Fred" or "Snuffalupagus" or whatever we chose).  Whenever we call the name of this alias, it executes the commands to which it's bound.  Then we bind the '''q''' key to the alias name.  Whenever we press the '''q''' key, that alias is executed.
 +
Why are aliases more useful than binds?  We'll get into that a little more deeply later, but imagine if you wanted to bind that same series of commands to multiple keys.  Instead of typing the series again for each key, you can now just bind the alias name to each key.  This way, if you want to change something in that series of commands, you only have to change it in one place.
  
:*<argument2> is either the command being bound or the commands executed by the alias.
+
===How do plus(+) and minus(-) aliases work?===
 +
As with plus and minus commands, plus and minus aliases are two-state aliases.  The plus state is executed (and continues to execute) while the key is pressed.  The minus state executes when the key is released.  For example, let's take a look at this plus/minus alias for an Engineer (swiped from Patty on the TF2 boards):
 +
<pre>
 +
alias "+upgradeBuilding" "slot3; +attack"
 +
alias "-upgradeBuilding" "-attack; wait; slot1"
 +
bind "mouse3" "+upgradeBuilding"
 +
</pre>
 +
:*'''+upgradeBuilding''' switches to the Wrench and begins to swing it.
 +
:*'''-upgradeBuilding''' stops swinging the Wrench, waits a moment, then switches back to the Shotgun.
 +
:*Then we bind the middle mouse button to the plus-state of the alias we just created.  As long as the button is held down, the Wrench will continue to swing.  As soon as the button is released, the minus-state will be executed.
 +
Note that, even though the minus state is never explicitly mentioned in the keybind, the minus-state is executed upon release of the button.  This is an automatic function of plus/minus aliases.
 +
<nowiki>{{Cleanup}}</nowiki>
  
*To run multiple commands, you must put the entire argument in quotation marks and separate the commands with semicolons, like so:
+
===How are cyclical or complex aliases written?===
 +
Cyclical or complex aliases are aliases that reference or even create other aliases.  Since it's difficult to explain on a general level, let's take a look at an example:
 +
<pre>
 +
alias "duckToggle" "duck1"
 +
alias "duck1" "+duck; alias duckToggle duck2"
 +
alias "duck2" "-duck; alias duckToggle duck1"
 +
</pre>
 +
:*First, we create an alias called '''duckToggle''' and assign it to another alias called '''duck1'''.
 +
:*Second, we create the '''duck1''' alias, which begins and continues the '''duck''' command.  Then it reassigns '''duckToggle''' to a third alias called '''duck2'''.
 +
:*Third, we create the '''duck2''' alias, which ends the '''duck''' command (i.e. causes the player to stand up).  Then it reassigns '''duckToggle''' back to '''duck1'''.
 +
Now, the first time we execute the '''duckToggle''' alias, it will perform the '''duck1''' alias.  But the next time we execute '''duckToggle''', it will perform the '''duck2''' alias.  Now all that's left to do is to bind a key to the '''duckToggle''' alias:
 +
<pre>bind "c" "duckToggle"</pre>
 +
The next time we press the '''c''' key, the player will crouch.  When we press '''c''' again, the player will stand up.
  
:'''alias "spraynpray" "+attack; wait 500; -attack"'''
+
===Key Combinations===
:'''bind "mouse3" "spraynpray"
+
I've used the word key combinations by lack of another word. What it actually does is this: by pressing a key, you temporary bind one or more keys to a different command then default. This makes it look just like you are using a key combination. An example to change class:
 +
<pre>
 +
// Quick Class Joiner Script. It has been tested and works.
 +
//Press shift and a key from 1-9 to change class.
 +
//
 +
alias +joinclass "bind 1 scout; bind 2 soldier; bind 3 pyro; bind 4 demoman; bind 5 heavy; bind 6 engineer; bind 7 medic; bind 8 sniper; bind 9 spy"
 +
alias "-joinclass" "bind 1 slot1; bind 2 slot2; bind 3 slot3; bind 4 slot4; bind 5 slot5; bind 6 slot6; bind 7 slot7; bind 8 slot8; bind 9 slot9"
 +
//
 +
alias scout "join_class scout"
 +
alias soldier "join_class soldier"
 +
alias pyro "join_class pyro"
 +
alias demoman "join_class demoman"
 +
alias heavy "join_class heavyweapons"
 +
alias engineer "join_class engineer"
 +
alias medic "join_class medic"
 +
alias sniper "join_class sniper"
 +
alias spy "join_class spy"
 +
//
 +
bind "shift" "+joinclass"
 +
</pre>
 +
By CupOfTea
  
:*When executed, the alias starts firing the player's weapon, continues for 500 physics frames or roughly five seconds, and then stops firingThe alias is keybound to execute when you press the middle mouse button.
+
==Additional Scripting Tips==
 +
===Why shouldn't I bind keys within aliases?===
 +
There are several reasons why you generally shouldn't bind keys inside of aliases.
 +
# It makes it difficult for the user to find and change those keybinds.
 +
# If you have several keybinds within the alias and the user wants to change keys, missing one of the binds could break the alias.
 +
# It makes that alias specific to only that key, and prevents the user from binding multiple keys to a single alias.
 +
Let's look at the '''duckToggle''' alias as an exampleIf we were to bind keys within that alias, it might look like this:
 +
<pre>
 +
//This is an example of how NOT to write an alias!
 +
alias "duck1" "+duck; bind c duck2"
 +
alias "duck2" "-duck; bind c duck1"
 +
bind "c" "duck1"
 +
</pre>
 +
As you can see, when the alias is written this way, the '''c''' key is bound ''three times!''  In order for users to change that key, they must find every place where the '''c''' key has been bound. If they miss even one instance, that alias will break.  Now let's replace those binds with alias reassignments:
 +
<pre>
 +
//This is a much better approach
 +
alias "duckToggle" "duck1"
 +
alias "duck1" "+duck; alias duckToggle duck2"
 +
alias "duck2" "-duck; alias duckToggle duck1"
  
*If you want a command to be continuously applied, you place a + in front of it, such as '''+duck'''.  If you want it to end, you place a - in front of it, such as '''-duck'''.
+
bind "c" "duckToggle"
 +
</pre>
 +
Now why is this better?  Well, first, the user only needs to look in one place for the keybind, so it's much easier to changeBut it also allows the user to bind multiple keys or buttons without changing the alias at all!
 +
<pre>
 +
bind "c" "duckToggle"
 +
bind "v" "duckToggle"
 +
bind "b" "duckToggle"
 +
bind "MOUSE3" "duckToggle"
 +
//And so on, and on, and on
 +
</pre>
 +
If we were binding our keys inside our aliases, then we'd have to write the aliases multiple times: once for each key we want to bind.  But when we move the keybinding outside the aliases, we only have to write the alias once and can bind as many keys as we want to it.
  
*If a command or alias is bound to a key, a + tells the game to run the command as long as the key is heldSimilarly, if a command or alias is bound to a key, a - tells the game to run the command when the key is released.
+
When you're writing scripts for everyone to use, try to keep this principle in mindNot only is it easier for users to customize, but it's also easier for you to write and maintain.
  
*If you want the game to delay for a period of time during an alias, or if you want avoid client crashes by executing commands too quickly, use the '''wait''' command.  It tells the game to wait one physics frame, something like a full turn in the TF2 rules, before continuing to execute an alias or command.  It accepts values such as "wait 50" which tells the game to wait fifty frames before the alias continues.  "wait 100" is roughly a second on a 100 FPS server.
+
===How to display text onscreen===
 +
First is the example of how, followed by the explanation.
  
*Some servers disable the wait command.  Many scripts will not function under these conditions.
+
You will need a file called ''con_filter_text_clear.cfg'' that contains:
 +
  con_filter_text ""
  
*Other commands accept values as wellFor example, if you want to turn alltalk on and off, the sv_alltalk command accepts 1 or 0 respectively.
+
Then in your ''autoexec.cfg''
 +
  // aliases to execute the 2 scripts we made
 +
alias "cft_clear" "exec con_filter_text_clear.cfg"
 +
alias "cft_script" "con_filter_text |}"
 +
// aliases to toggle console filtering
 +
alias "cf1" "con_filter_enable 1"
 +
alias "cf0" "con_filter_enable 0"
 +
// to echo a newline
 +
alias "cfnl" "cf0;echo;cf1"
 +
 +
// if you turn this off all text disapears!  it is left always on
 +
developer 1
 +
// start with filtering enabled so we don't see all the console garbage on our screen
 +
cf1
 +
 +
// you can play with the following settings
 +
con_notifytime 8 // How long to display recent console text to the upper part of the game window
 +
con_nprint_bgalpha 50 // Con_NPrint background alpha.
 +
con_nprint_bgborder 5 // Con_NPrint border size.
 +
contimes 8 // Number of console lines to overlay for debugging.
 +
 +
// our simple screen print test... which you can expand to do menus or whatever
 +
echo "|} Isn't ofb's screen printing cool?"
 +
cfnl
  
==Common scripts==
+
Okay, that's it!  Remember that when building menus you can use the ''clear'' console command to clear away your menu after it's done so it doesn't stay on the screen!  Please don't clutter people's screen with "my script loaded v1.2.3 by alphaguy", we don't need spam, TF2 is pretty; leave it that way.
  
There are several notable scripts that have affected gameplaySome of these are patched out. Others remain functional.
+
To understand how it works, we set up a .cfg because you can't nest quotes in an alias, alias "myalias" "echo "hi okay?"" for example doesn't workIf you've found a way to escape them properly, just edit this article and update it! We set developer to 1 which spams our users a lot, and they wouldn't know when to look for the menu, so we turn on console filtering which only prints messages that contain |}, we want something unique that wont' come up often but that doesn't look like ass on the screen because we'll always need to put it there.
  
===Pistol Script===
+
Then when we used ''cfnl'' to echo a newline after our filtered text.  This is because filtered echo's don't add a newline, and if we didn't all our later echos would just put all the text on the same line.  Give it a try to see what I mean.  So we turn filtering off, echo a newline, then turn it back on so we don't spam our users.
  
Originally, the [[Pistol]] could be fired almost as fast as the human hand could press a key.  Realizing this, some people created script sthat made the Pistol fire as rapidly as possible as long as you held down the fire button.  This not only allowed the [[Scout]] and [[Engineer]] to fire faster than most people could manage, but it was easier to aim because you weren't mashing any keys.
+
'''Warning: console filtering means that you will not get any console text that isn't from your scripts!  To see console output again just type ''cft_clear''.'''
  
Valve eventually leveled the playing field. They patched the Pistol to have a lower max firing rate, which was reached by default whenever a player held down the attack keyThe Pistol script was no longer necessary.
+
==Console Commands==
 +
A note on syntax... if an item is surrounded in square brackets ([ or ]) it is optional; if an item is enclosed in angle brackets (< or >) then it is required for that command to work.   
  
===Targe Turn Script===
+
===ALIAS===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:Alias is simply a means of reducing a long list of commands into a small package.  For instance, take that example from the 'wait' command.  If that were aliased, you could simply use that alias rather than try to remember the whole thing.  Much easier.  Plus it makes it easier to make things like communications scripts and such.
 +
*Syntax
 +
*:alias "<name_of_alias>" "<command; list>"
 +
*Arguments
 +
**None
  
Originally, the keyboard commands to turn your viewpoint left and right were not treated the same as the mouse commands.  The [[Chargin' Targe]] was the first weapon to create a restriction on how fast you could turn your viewpoint, so Valve put limits on mouse turnspeed but forgot to apply the same restrictions to the rarely used keyboard turns.
 
  
Players made scripts that rebound keys whenever a player charged, allowing them to turn at full speed.  The most sophisticated examples temporarily rebound the mouse x-axis inputs to the keyboard turn commands, then unbound them when the player attacked at the end of the charge.
 
  
Valve eventually capped the keyboard turn commands like the mouse commandsThe Turn scripts were made useless.
+
===BUILD===
 +
*Class Restrictions
 +
*:Engineer, Spy
 +
*Description
 +
*:If the Engineer who used this command has enough metal, it will put him into build mode for the item specifiedIf a Spy uses this command, he will arm the Electro Sapper, ready to use on any hostile gadgets targeted.
 +
*Old syntax
 +
*:build <gadget_number>
 +
*Old arguments
 +
**<gadget_number>
 +
**:0: [[Dispenser]] (Engineer)
 +
**:1: [[Teleporter]] entrance (Engineer)
 +
**:2: Teleporter exit (Engineer)
 +
**:3: [[Sentry Gun]] (Engineer)
 +
**:4: [[Electro Sapper]] (Spy)
 +
*New syntax
 +
*:build <group_number> <gadget_number>
 +
*New arguments
 +
**<group_number>
 +
**:0: [[Dispenser]] (only Engineer)
 +
**:1: [[Teleporter]] (only Engineer)
 +
**:2: [[Sentry Gun]] (only Engineer)
 +
**:3: [[Electro Sapper]] (only Spy)
 +
**<gadget_number>
 +
**:0: for Sentry Gun, Dispenser, teleporter entry or Electro Sapper
 +
**:1: for teleporter exit
 +
*Example
 +
*:> build 2 0 (build a Sentry Gun)
 +
*:> build 1 1 (build a tele exit)
  
===Weapon Hiding Scripts===
+
''NOTE: Currently you cannot call build a second time with an Engineer when you are already in build mode, you need to swap to any of your weapon before being able to call build again (bug or feature?)''
  
There are a large number of scripts which toggle the weapon display option depending on which weapon slot is selected for a class.  Players often make their guns invisible to clear up the screen, but make items like melee weapons, PDAs, watches and so forth visible because these models indicate important information.  For example, the [[Spy]] relies heavily on his visible model to determine when he is cloaked, when his cloak is disturbed, and when the [[Dead Ringer]] activates.  Other classes use the melee animations to judge when their attacks will hit.
+
''NOTE: This issue is fixed, the build command can now be called repeately without problems.''
  
===Sentry Jumping Scripts===
+
''NOTE: After the 01 may 2010 update, old syntax still works the same.
  
Since the [[Engineer]] update, Engineers have been able to pack up and carry their [[Sentry Guns]].  Simultaneously, the [[Wrangler]] allowed Engineers to [[Sentry jump]] with their Sentry rockets.  With extremely fast inputs, it was discovered that a player could Sentry jump and successfully pack up their Sentry before they were launched away.
+
===DESTROY===
 +
*Class Restrictions
 +
*:Engineer, Spy
 +
*Description
 +
*:If you have built the gadget represented by the number, congratulations, you are the prowd owner of newly minted scrap metal. Useful for Engineers who want to relocate their buildings, but largely useless for Spies (who would be very unlikely to actually want to destroy their own Sappers).
 +
*Old syntax
 +
*:destroy <gadget_number>
 +
*Old arguments
 +
**<gadget_number>
 +
**:0: Dispenser (Engineer)
 +
**:1: Teleport Entrance (Engineer)
 +
**:2: Teleport Exit (Engineer)
 +
**:3: Sentry (Engineer)
 +
**:4: Electro Sapper (Spy)
 +
*New syntax
 +
*:destroy <group_number> <gadget_number>
 +
*New arguments
 +
**<group_number>
 +
**:0: [[Dispenser]] (only Engineer)
 +
**:1: [[Teleporter]] (only Engineer)
 +
**:2: [[Sentry Gun]] (only Engineer)
 +
**<gadget_number>
 +
**:0: for Sentry Gun, Dispenser or teleporter entry
 +
**:1: for teleporter exit
 +
*Example
 +
*:> destroy 2 0 (destroy Sentry Gun)
 +
*:> destroy 1 1 (destroy tele exit)
  
While a human can repeat this feat, it's difficult and sometimes inconsistentSome players made scripts which could reliably execute the commands in the right order at the right speedThey can make a Sentry jump while carrying their Sentry every time.
+
===DISGUISE===
 +
*Class Restrictions
 +
*:Spy
 +
*Description
 +
*:This, as is fairly easy to tell from the command itself, will disguise you as someone.  Who, however, depends on the numbersThe first number represents the class you wish to be, while the second represents the teamWhen I was testing this out, team numbers above two still worked, so I imagine that it's forward-thinking support in case someone wants to remake a murderball map or something. Also, using negative numers allows you to disguise as either your team or the enemy team without setting up a team loader.
 +
*Syntax
 +
*:disguise <class_number> <team_number>
 +
*Arguments
 +
**<class_number>
 +
**:1: Scout
 +
**:2: Sniper
 +
**:3: Soldier
 +
**:4: Demoman
 +
**:5: Medic
 +
**:6: Heavy Weapons Guy
 +
**:7: Pyro
 +
**:8: Spy
 +
**:9: Engineer
 +
**<team_number>
 +
**:1: BLU
 +
**:2: Red
 +
**:-1: The Enemy Team
 +
**:-2: My Team
  
===Sensitivity and Control Scripts===
+
===LASTDISGUISE===
 +
*Class Restrictions
 +
*:Spy
 +
*Description
 +
*:As one might imagine, this command changes your disguise to the last one you had.  It will remember disguises after a death.  This is bound to 'b' by default.  Lastdisguise random will chooses a random disguise that's neither Spy nor Scout. Using the command whilst already disguised as your last disguise will switch the weapon of the disguise to the corresponding weapon armed.
 +
*Syntax
 +
*:lastdisguise [random]
 +
*Arguments
 +
**[random]
 +
**:Chooses a random disguise that's neither Spy nor Scout
  
Some players prefer different mouse sensitivities and control schemes for some classesThese scripts alter their control schemes and mouse settings on a per class or even per weapon basis.
+
===LASTINV===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:This one's real easyAll it does is switch you back to your previously used weapon. (And I'm sure some of you probably realize that this is exactly the command that 'q' is bound to by default.)
 +
*Syntax
 +
*:lastinv
 +
*Arguments
 +
**None
  
==Resources==
 
  
Here are some links that review Team Fortress 2 scripting in greater detail:
 
  
*http://forums.steampowered.com/forums/showthread.php?t=709568 - AciD's guide.  Covers basics.
+
===MENUSELECT===
*http://warriornation.net/Forum/showthread.php?t=568008 - shatteredsword's guideCovers some of the more advanced scripting tricks.
+
*Class Restrictions
*http://www.fpsbanana.com/scripts/games/297 - The scripting section with hundreds of TF2 script examples.
+
*:None
*[[Bindable keys]] - A List of the keys that are bindable and their scripting names.
+
*Description
 +
*:Menuselect does ONLY the menu portion of slotX, so refer to that entry for the detailed explanationAlso, it ONLY works on VGUI menus, such as the voice command menus, not the visual menus like those that are used to choose class, or select which building to construct as an Engineer, etc.
 +
*Syntax
 +
*:menuselect <item_number>
 +
*Arguments
 +
**<item_number>
 +
**:Any valid menu choice.
 +
*Note:  Use '''cancelselect''' to leave a menu.
  
[[Category:Scripts]]
+
 
 +
 
 +
 
 +
===PLAY===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:Plays a selected .wav file locally (which is to say, only the user will hear it through their client). To find a .wav file to play, you will need to have a GCF explorer such as GCFScape [http://developer.valvesoftware.com/wiki/GCFScape]. With this you can find the path and the sound file you wish to play, and reference it via the console (or scripting).
 +
:You can also add your own .wav files to '''C:\Program Files\Steam\steamapps\USERNAME\team fortress 2\tf\sound\'''. (See '''Custom .wav files''' below.)
 +
*Syntax
 +
*:play <path><sound_file_name.wav>
 +
*Example
 +
*:play vo/demoman_specialcompleted11.wav
 +
*Arguments
 +
**None
 +
 
 +
====Custom .wav files====
 +
Adding your own .wav files is as simple as dropping them in your '''C:\Program Files\Steam\steamapps\USERNAME\team fortress 2\tf\sound\''' folder.  This folder represents the root of the .wav file's path.  For example, if you drop a single .wav file called '''soldier.wav''' into that folder, then you can play it by using the following command:
 +
<pre>
 +
play soldier.wav
 +
</pre>
 +
If you drop a .wav file into a subdirectory of that folder, then you need to preface the filename with the name of that subdirectory.  For example, if you drop '''Soldier.wav''' into '''C:\Program Files\Steam\steamapps\USERNAME\team fortress 2\tf\sound\classes\''' then you can play it using the following command:
 +
<pre>
 +
classes/soldier.wav
 +
</pre>
 +
 
 +
===SLOT<X>===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:This command has a little more depth to it than first appears.  While it is mainly used to choose a weapon, it can also be used as feedback to the default voice menus at 'z', 'x', and 'c'.  For instance, if you have 'f' bound to 'slot1' and activate voice_menu_1 ('z'), pressing 'f' would cause you to call for a Medic.  With regard to choosing a weapon, this command can act one of two ways.  If you have fast weapon switching turned on, this command will immediately switch to that weapon.  If you do not, this command will only highlight whatever weapon slot it represents and it remains up to you to do the final selection.  Or you can use this to do it for you: "slot1; wait 50; +attack; wait; -attack".
 +
*Syntax
 +
*:slot<slot_number>
 +
*Arguments
 +
**<slot_number>
 +
**:Needs to be a number between 0 and 10.  '''slot10''' exits a menu.
 +
 
 +
 
 +
 
 +
===USE===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:The "use" command is used to literally use the specified weapon.  No muss, no fuss, you just pull out that weapon if you have it.
 +
*Syntax
 +
*:use <weapon_name>
 +
*Arguments
 +
**<weapon_name>
 +
***Scout
 +
**:tf_weapon_scattergun
 +
**:tf_weapon_handgun_scout_primary
 +
**:tf_weapon_pistol_scout
 +
**:tf_weapon_lunchbox_drink
 +
**:tf_weapon_jar_milk
 +
**:tf_weapon_bat
 +
**:tf_weapon_bat_wood
 +
**:tf_weapon_bat_fish
 +
***Soldier
 +
**:tf_weapon_rocketlauncher
 +
**:tf_weapon_rocketlauncher_directhit
 +
**:tf_weapon_shotgun_soldier
 +
**:tf_weapon_buff_item
 +
**:tf_weapon_shovel
 +
**:tf_weapon_sword
 +
***Pyro
 +
**:tf_weapon_flamethrower
 +
**:tf_weapon_shotgun_pyro
 +
**:tf_weapon_flaregun
 +
**:tf_weapon_fireaxe
 +
***Demoman
 +
**:tf_weapon_grenadelauncher
 +
**:tf_weapon_grenade_demoman
 +
**:tf_weapon_pipebomblauncher
 +
**:tf_weapon_pumpkin_bomb
 +
**:tf_weapon_bottle
 +
**:tf_weapon_base
 +
**:tf_weapon_sword
 +
***Heavy Weapons Guy
 +
**:tf_weapon_minigun
 +
**:tf_weapon_shotgun_hwg
 +
**:tf_weapon_lunchbox
 +
**:tf_weapon_fists
 +
***Engineer
 +
**:tf_weapon_shotgun_primary
 +
**:tf_weapon_sentry_revenge
 +
**:tf_weapon_pistol
 +
**:tf_weapon_laser_pointer
 +
**:tf_weapon_wrench
 +
**:tf_weapon_robot_arm
 +
**:tf_weapon_pda_engineer_destroy
 +
**:tf_weapon_pda_engineer_build
 +
***Medic
 +
**:tf_weapon_syringegun_medic
 +
**:tf_weapon_medigun
 +
**:tf_weapon_bonesaw
 +
***Sniper
 +
**:tf_weapon_sniperrifle
 +
**:tf_weapon_compound_bow
 +
**:tf_weapon_smg
 +
**:tf_weapon_jar
 +
**:tf_weapon_club
 +
***Spy
 +
**:tf_weapon_revolver
 +
**:tf_weapon_knife
 +
**:tf_weapon_pda_spy
 +
**:''see the [[Scripting#BUILD|Build]] section for how to equip sapper''
 +
 
 +
===VOICEMENU===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:This command is basically a direct method of using the 'z', 'x', and 'c' keys to send voice messages.  Basically this allows you to bind a voice message directly to a key in the same fashion as how 'e' is by default bound to call in a Medic.
 +
*Syntax
 +
*:voicemenu <menu_number> <phrase_number>
 +
*Arguments
 +
**<menu_number>
 +
***0 <phrase_number>
 +
***:0: Medic
 +
***:1: Thanks
 +
***:2: Go
 +
***:3: Move Up
 +
***:4: Flank Left
 +
***:5: Flank Right
 +
***:6: Yes
 +
***:7: No
 +
***1 <phrase_number>
 +
***:0: Incoming
 +
***:1: Cloaked Spy
 +
***:2: Sentry Ahead
 +
***:3: Teleporter Here
 +
***:4: Dispenser Here
 +
***:5: Sentry Here
 +
***:6: Activate ÜberCharge
 +
***:7: (Medic Only) ÜberCharge Ready
 +
***2 <phrase_number>
 +
***:0: Help
 +
***:1: Battlecry
 +
***:2: Cheers
 +
***:3: Jeers
 +
***:4: Positive
 +
***:5: Negative
 +
***:6: Nice Shot
 +
***:7: Good Job
 +
 
 +
 
 +
 
 +
===WAIT===
 +
*Class Restrictions
 +
*:None
 +
*Description
 +
*:This command is very useful when running multiple commands on the same line.  Basically, what this command does is halts the execution of that line for X frames based on its parameter.  If you don't use a parameter, it defaults to 1.  For me, a value of 100 equals roughly a second, but I haven't had time to check whether this is server or client dependant or not, so you may have to adjust your own times accordingly.  An example might be as follows for an Engineer upgrading his SG:
 +
"use tf_weapon_wrench; wait; +duck; wait; +attack; wait 500; -attack; wait; -duck; lastinv"
 +
What that does is switch his Wrench, ducks, starts swinging the Wrench and continues for 5 seconds or so, stops swinging, stands up, and switches back to the last weapon used.  If you were to attempt that without the waits, there's a pretty good chance it would fail rather spectacularly.
 +
It is important to note that, unlike wait commands of the past, waits will not delay further input, and can be used simply as a timer for scripting in general.
 +
*Syntax
 +
*:wait [wait_time]
 +
*Arguments
 +
**[wait_time]
 +
**:A value between 1 and <unknown>.  Default is 1.
 +
*'''A Note About The Wait Command'''
 +
:Valve has fixed the functionality of the sv_allow_wait_command server variable. When disabled (set to 0) the engine simply ignores and omits any wait commands that the server is given. Consequently, many scripts on this website are broken or will only function in very specific situations. This variable is set to 1 by default, but many servers base their server.cfg files off of competitive league settings, which typically disable wait commands. Furthermore, scripts that do loops (see [[Scout scripts#Autopistol|Autopistol Script]] for an example) will crash your client when triggered.  There is a workaround to fix loop crashing, revolving around aliasing the wait command itself to do an alias over a repeating loop name.
 +
 
 +
===Other Common GoldSource/Source Scripting Commands===
 +
 
 +
Class select '''changeclass'''
 +
 
 +
Console Toggling  '''toggleconsole'''
 +
 
 +
Crouch  '''+duck'''
 +
 
 +
Drop item  '''dropitem'''
 +
 
 +
Echo message  '''echo'''
 +
 
 +
Fire weapon  '''+attack'''
 +
 
 +
FPS view  '''cl_showfps 1'''
 +
 
 +
Handedness left  '''setinfo lefthand 1'''
 +
 
 +
Handedness right  '''setinfo lefthand 0'''
 +
 
 +
Jump  '''+jump'''
 +
 
 +
Last weapon  '''lastinv'''
 +
 
 +
Logo spray  '''impulse 201'''
 +
 
 +
Look down  '''+lookdown'''
 +
 
 +
Look up  '''+lookup'''
 +
 
 +
Map info  '''showbriefing'''
 +
 
 +
Map list  '''listmaps'''
 +
 
 +
Move backward  '''+back'''
 +
 
 +
Move forward  '''+forward'''
 +
 
 +
Netgraph  '''netgraph <num>'''
 +
 
 +
Next weapon  '''invnext'''
 +
 
 +
Playerlist  '''listplayers'''
 +
 
 +
Previous weapon  '''invprev'''
 +
 
 +
Public message  '''say'''
 +
 
 +
Reload weapon  '''+reload'''
 +
 
 +
Score overview  '''+showscores'''
 +
 
 +
Screenshot  '''snapshot'''
 +
 
 +
Strafe  '''+strafe'''
 +
 
 +
Strafe Left  '''+moveleft'''
 +
 
 +
Strafe Right  '''+moveright'''
 +
 
 +
Secondary weapon function  '''+attack2'''
 +
 
 +
Taunt '''taunt'''
 +
 
 +
Suicide '''kill'''
 +
 
 +
Suicide by Explosion '''explode'''
 +
 
 +
Team message  '''say_team'''
 +
 
 +
Team select  '''changeteam'''
 +
 
 +
Turn left  '''+left'''
 +
 
 +
Turn right  '''+right'''
 +
 
 +
Voice Chat  '''+voicerecord'''
 +
 
 +
( ''"S.A.S's Guide to Counter-Strike: Scripting"'' )
 +
 
 +
==Bindable keys==
 +
The following is a list of bindable keys in TF2 and the terms used in [[scripting]]. The left column shows the name used in TF2 scripting to identify each key. The right column shows the key's name in plain English.
 +
 
 +
<div align="left">
 +
 
 +
<table border="1" cellpadding="3" cellspacing="0" bordercolordark="#000000" bordercolorlight="#000000">
 +
<tr>
 +
<th>Scripting Name</th>
 +
<th>Normal Name</th>
 +
</tr>
 +
 
 +
<!-- Numbers -->
 +
<tr>
 +
<td class="lgray" align="center">1</td>
 +
<td class="lgray" align="center">One</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">2</td>
 +
<td bgcolor=#ffb449 align="center">Two</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">3</td>
 +
<td class="lgray" align="center">Three</td>
 +
 
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">4</td>
 +
<td bgcolor=#ffb449 align="center">Four</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">5</td>
 +
<td class="lgray" align="center">Five</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">6</td>
 +
<td bgcolor=#ffb449 align="center">Six</td>
 +
</tr>
 +
 
 +
<tr>
 +
 
 +
<td class="lgray" align="center">7</td>
 +
<td class="lgray" align="center">Seven</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">8</td>
 +
<td bgcolor=#ffb449 align="center">Eight</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td class="lgray" align="center">9</td>
 +
<td class="lgray" align="center">Nine</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">0</td>
 +
<td bgcolor=#ffb449 align="center">Zero</td>
 +
 
 +
</tr>
 +
 
 +
<!-- Letters -->
 +
<tr>
 +
<td class="lgray" align="center">A</td>
 +
<td class="lgray" align="center">A</td>
 +
</tr>
 +
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">B</td>
 +
<td bgcolor=#ffb449 align="center">B</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">C</td>
 +
<td class="lgray" align="center">C</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">D</td>
 +
<td bgcolor=#ffb449 align="center">D</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">E</td>
 +
<td class="lgray" align="center">E</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F</td>
 +
<td bgcolor=#ffb449 align="center">F</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">G</td>
 +
<td class="lgray" align="center">G</td>
 +
 
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">H</td>
 +
<td bgcolor=#ffb449 align="center">H</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">I</td>
 +
<td class="lgray" align="center">I</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">J</td>
 +
<td bgcolor=#ffb449 align="center">J</td>
 +
</tr>
 +
 
 +
<tr>
 +
 
 +
<td class="lgray" align="center">K</td>
 +
<td class="lgray" align="center">K</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">L</td>
 +
<td bgcolor=#ffb449 align="center">L</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td class="lgray" align="center">M</td>
 +
<td class="lgray" align="center">M</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">N</td>
 +
<td bgcolor=#ffb449 align="center">N</td>
 +
 
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">O</td>
 +
<td class="lgray" align="center">O</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">P</td>
 +
<td bgcolor=#ffb449 align="center">P</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">Q</td>
 +
<td class="lgray" align="center">Q</td>
 +
</tr>
 +
 
 +
<tr>
 +
 
 +
<td bgcolor=#ffb449 align="center">R</td>
 +
<td bgcolor=#ffb449 align="center">R</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">S</td>
 +
<td class="lgray" align="center">S</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">T</td>
 +
<td bgcolor=#ffb449 align="center">T</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">U</td>
 +
<td class="lgray" align="center">U</td>
 +
 
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">V</td>
 +
<td bgcolor=#ffb449 align="center">V</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">W</td>
 +
<td class="lgray" align="center">W</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">X</td>
 +
<td bgcolor=#ffb449 align="center">X</td>
 +
</tr>
 +
 
 +
<tr>
 +
 
 +
<td class="lgray" align="center">Y</td>
 +
<td class="lgray" align="center">Y</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">Z</td>
 +
<td bgcolor=#ffb449 align="center">Z</td>
 +
</tr>
 +
 
 +
 
 +
<!-- F Keys -->
 +
<tr>
 +
<td class="lgray" align="center">F1</td>
 +
<td class="lgray" align="center">F1</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F2</td>
 +
<td bgcolor=#ffb449 align="center">F2</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">F3</td>
 +
<td class="lgray" align="center">F3</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F4</td>
 +
<td bgcolor=#ffb449 align="center">F4</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">F5</td>
 +
<td class="lgray" align="center">F5</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F6</td>
 +
<td bgcolor=#ffb449 align="center">F6</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">F7</td>
 +
<td class="lgray" align="center">F7</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F8</td>
 +
<td bgcolor=#ffb449 align="center">F8</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">F9</td>
 +
<td class="lgray" align="center">F9</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F10</td>
 +
<td bgcolor=#ffb449 align="center">F10</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">F11</td>
 +
<td class="lgray" align="center">F11</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">F12</td>
 +
<td bgcolor=#ffb449 align="center">F12</td>
 +
</tr>
 +
 
 +
 
 +
<!-- Other keys -->
 +
<tr>
 +
<td class="lgray" align="center">`</td>
 +
<td class="lgray" align="center">Left Quote or Tilde</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">'</td>
 +
<td bgcolor=#ffb449 align="center">Right Quote</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">-</td>
 +
<td class="lgray" align="center">Hyphen</td>
 +
</tr>
 +
 
 +
<tr>
 +
 
 +
<td bgcolor=#ffb449 align="center">=</td>
 +
<td bgcolor=#ffb449 align="center">Equals sign</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">]</td>
 +
<td class="lgray" align="center">Right Bracket</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">\</td>
 +
<td bgcolor=#ffb449 align="center">Backslash</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">,</td>
 +
<td class="lgray" align="center">Comma</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">/</td>
 +
<td bgcolor=#ffb449 align="center">Slash</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">SPACE</td>
 +
<td class="lgray" align="center">Spacebar</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">ENTER</td>
 +
<td bgcolor=#ffb449 align="center">Enter</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">ESCAPE</td>
 +
<td class="lgray" align="center">Escape</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">PAUSE</td>
 +
<td bgcolor=#ffb449 align="center">Pause/Break</td>
 +
</tr>
 +
 
 +
 
 +
 
 +
 
 +
<tr>
 +
<td class="lgray" align="center">BACKSPACE</td>
 +
<td class="lgray" align="center">Backspace</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">TAB</td>
 +
<td bgcolor=#ffb449 align="center">Tab</td>
 +
</tr>
 +
 
 +
 
 +
<tr>
 +
<td class="lgray" align="center">SEMICOLON</td>
 +
<td class="lgray" align="center">Semicolon ; </td>
 +
</tr>
 +
 
 +
 
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">SHIFT</td>
 +
<td bgcolor=#ffb449 align="center">Shift</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">CTRL</td>
 +
<td class="lgray" align="center">Control</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">ALT</td>
 +
<td bgcolor=#ffb449 align="center">Alt</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">UPARROW</td>
 +
<td class="lgray" align="center">Up Arrow</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">DOWNARROW</td>
 +
<td bgcolor=#ffb449 align="center">Down Arrow</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">LEFTARROW</td>
 +
<td class="lgray" align="center">Left Arrow</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">RIGHTARROW</td>
 +
<td bgcolor=#ffb449 align="center">Right Arrow</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">INS</td>
 +
<td class="lgray" align="center">Insert</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">HOME</td>
 +
<td bgcolor=#ffb449 align="center">Home</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">PGUP</td>
 +
<td class="lgray" align="center">Page Up</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">PGDN</td>
 +
<td bgcolor=#ffb449 align="center">Page Down</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">DEL</td>
 +
<td class="lgray" align="center">Delete</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">END</td>
 +
<td bgcolor=#ffb449 align="center">End</td>
 +
</tr>
 +
 
 +
 
 +
<!-- Keypad -->
 +
<tr>
 +
<td class="lgray" align="center">KP_HOME</td>
 +
<td class="lgray" align="center">Keypad Home/7</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_UPARROW</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Up Arrow/8</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_PGUP</td>
 +
<td class="lgray" align="center">Keypad Page Up/9</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_LEFTARROW</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Left Arrow/4</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_5</td>
 +
<td class="lgray" align="center">Keypad 5</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_RIGHTARROW</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Right Arrow/6</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_END</td>
 +
<td class="lgray" align="center">Keypad End/1</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_ENTER</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Enter</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_DOWNARROW</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Down Arrow/2</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_PGDN</td>
 +
<td class="lgray" align="center">Keypad Page Down/3</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_INS</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Insert/0</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_DEL</td>
 +
<td class="lgray" align="center">Keypad Delete</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_SLASH</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Backslash</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_MINUS</td>
 +
<td class="lgray" align="center">Keypad Hyphen</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">KP_PLUS</td>
 +
<td bgcolor=#ffb449 align="center">Keypad Plus</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">KP_MULTIPLY</td>
 +
<td class="lgray" align="center">Keypad Asterisk</td>
 +
</tr>
 +
 
 +
 
 +
<!-- Mouse buttons -->
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">MOUSE1</td>
 +
<td bgcolor=#ffb449 align="center">Mouse Button 1</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">MOUSE2</td>
 +
<td class="lgray" align="center">Mouse Button 2</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">MOUSE3</td>
 +
<td bgcolor=#ffb449 align="center">Mouse Button 3 (Middle Button)</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">MOUSE4</td>
 +
<td class="lgray" align="center">Mouse Button 4(*)</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">MOUSE5</td>
 +
<td bgcolor=#ffb449 align="center">Mouse Button 5(*)</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td class="lgray" align="center">MWHEELUP</td>
 +
<td class="lgray" align="center">Mouse Scroll Wheel Up</td>
 +
</tr>
 +
 
 +
<tr>
 +
<td bgcolor=#ffb449 align="center">MWHEELDOWN</td>
 +
<td bgcolor=#ffb449 align="center">Mouse Scroll Wheel Down</td>
 +
</tr>
 +
 
 +
</table>
 +
</div>
 +
 
 +
(*)Not standard on all mice. Only applies when the mice uses those two buttons as generic buttons.
 +
 
 +
==Scripting FAQ==
 +
===Global Script Questions===
 +
 
 +
====Print Console to TXT file from Console Command====
 +
:Posted by [[User:Josiah|Josiah]]
 +
*'''Q.''' Is there a way to Print the contents of the console to a txt file through a console command? I set up a simple script for my server to print out the status and go right to the ban menu of sourcemod. We have some bookkeeping practices for my server where we like to keep steam ids of banned people. There fore I want to get that status list in to a simple text file so it can be accessed later.
 +
 
 +
*'''A.''' There is a command called "condump" that saves all of the text currently in the console window to a condump###.txt file in Team Fortress 2/tf. It saves ''the entire console'', but your status list would just be at the bottom. --[[User:IAmThermite|IAmThermite]] 21:25, 13 September 2009 (UTC)
 +
 
 +
====HUD On/Off====
 +
:Posted by [[User:Bolange|Bolange]]
 +
*'''Q.''' Is there anyway to turn the HUD on or off for use in a script?
 +
*'''A.''' '''''cl_hud_minmode''''' set to "1" will give you a minimalist HUD view, you can also set this by going to your Options->Multiplayer. If you want to completely remove all HUD items though, you can use the commands '''''cl_drawhud 0''''' to remove the HUD and '''''r_drawviewmodel 0''''' to remove the gun (useful for screenshots), ''but'' Valve seem to have now classed these commands as cheats so they can '''only''' be used when '''''sv_cheats''''' is set to "1" --[[User:Aurora|Aurora]] 01:00, 22 November 2007 (BST)
 +
 
 +
====Reloading .cfg without closing the game?====
 +
:Posted by [[User:Jabu2oz|Jabu2oz]]
 +
*'''Q.''' Is there a way of "refeshing" a .cfg file (e.g. autoexec.cfg) without closing/reopening TF2? This would be useful when trying out scripts. (NB, I have tried "exec autoexec" from the console (and restarting the server) but this didn't seem to work).
 +
 
 +
Edit: Thanks, "exec autoexec.cfg" worked, but I did have to start a server without commentary mode on (single player). --[[User:Jabu2oz|Jabu2oz]] 15:10, 19 December 2007 (CST)
 +
*'''A.''' Did you try entering "exec autoexec.cfg" into the developer console? You need to give it the full file name if memory serves. If you're working with a server, some settings require a map change to take effect (sv_pure comes to mind here). -- [[User:WanderingFox|<span style="color:#8F0000;">WanderingFox</span>]]&nbsp;<span style="vertical-align:super;font-size: smaller;">([[User talk:WanderingFox|<span style="color:#8F0000;">Talk</span>]]&nbsp;•&nbsp;[[Special:Contributions/WanderingFox|<span style="color:#8F0000;">Contribs</span>]])</span> 15:15, 18 December 2007 (CST)
 +
 
 +
===Removing Scripts===
 +
How do we remove scripts?--[[User:B-MAN|B-MAN]] 09:57, 1 May 2010 (UTC)
 +
 
 +
A. You can just delete them from your cfg file. To temporary delete them, type alias "YourOriginalAliasHere" " " to replace the offending alias with a blank one. This applies until the cfg files are run again. --[[User:Kurathedog|Kurathedog]] 03:33, 19 October 2010 (UTC)
 +
 
 +
===Class Specific Script Questions===
 +
====Multiple Key Binds====
 +
:Posted by [[User:Bolange|Bolange]]
 +
 
 +
*'''Q.''' Is it possible to make a variable to use the same key with multiple bindings depending on the class you are? e.g. In Spy, press F1 to disguise in Scout, in Engineer, press F1 to build a sentry etc...
 +
 
 +
*'''A.''' Yes, however you will need to create separate scripts for each class, i.e. Spy.cfg and engi.cfg and put the binds in these, see the [[General class scripts#Class Config Switcher|Class Config Community Scripts]] for more information. --[[User:Aurora|Aurora]] 14:10, 21 November 2007 (BST)
 +
 
 +
====CTF Getting -or not- Intelligence as Spy====
 +
:Posted by [[User:Xerox|Xerox]]
 +
 
 +
*'''Q.''' Is there a way to bind a command for not to take enemies intelligence when you're in Spy, unless you press a key? You might need it if a sentry is very near the case and you want to sap it first.
 +
 
 +
*'''A.''' None that I know of, you can throw the [[Intelligence]] but by this time it will be too late and you will have lost your [[disguise]]. It's actually a common tactic of some [[Engineer]]'s (especially on [[2Fort]]) to position a [[Sentry Gun]] or [[Dispenser]] behind the [[Intelligence]] in the hope that the [[Spy]] will pick up the [[Intelligence]] by mistake when trying to [[Sapper|sap]] the [[Building]]. Another way [[Engineer]]'s use this to their advantage is if the [[Intelligence]] is in a corridor; by placing the [[Sentry Gun]] behind the [[Intelligence]] it forces the [[Spy]] to go an alternative way round to be able to [[Sapper|sap]] the [[Sentry Gun]] or hop over the [[Intelligence]] and therefore clearly identify himself. --[[User:Aurora|Aurora]] 01:20, 22 November 2007 (BST)
 +
 
 +
==See also==
 +
* [[Bindable keys]] - A List of the keys that are bindable and their scripting names
 +
<nowiki>[[Category:Scripts]]</nowiki>

Latest revision as of 00:10, 16 November 2010

{{rewrite}} Note that the word "scripts" as it is used on this page should not be confused with the .scr files that modify server behavior.

For common scripting questions, please visit the Scripting Faq page.

A Brief Overview of Scripts

What are binds?

Scripts in TF2 are known by several names, including "binds," "keybinds," and "bindings." Binds are a way to attach (or bind) game commands to a key.

Aren't binds cheating?

Not in many people's opinion. Think of it this way: binds allow you to do things you could have done easily, but faster. Everyone has easy access to binds, so they don't give you any advantage over other people. Also, the developers of the game put this feature in deliberately and allow it to happen (and they really don't like cheating because it is a multiplayer game) so it is seen as a legitimate use of the game.

Where are binds located?

The game itself stores binds in the file:

<Steam Folder>\SteamApps\<account_name>\team fortress 2\tf\cfg\config.cfg

The commands in this file are executed every time the game starts. Even though the user can modify this file in any text editor, it's often a good idea to add custom binds elsewhere. To this end, there is another file where users can add their own binds:

<Steam Folder>\SteamApps\<account_name>\team fortress 2\tf\cfg\autoexec.cfg

This file does not exist by default, but can be created by the user. As with config.cfg, the autoexec.cfg is just a simple text file that can be edited by the user. And just like config.cfg, the autoexec.cfg file is executed whenever the game starts.

When you create your autoexec.cfg file in your favorite text editor, be sure your text editor isn't tacking on a ".txt" to the end of the filename as is default with notepad (i.e. autoexec.cfg.txt), as that will not be auto-executed. It might not even be accessible from the console!

A good way to make sure that your autoexec.cfg file is not named incorrectly is to have your operating system show all file extensions of known filetypes. Googling found this page [1] which gives good graphical instructions on exactly how to do that.

Using Scripts

Putting a script in autoexec.cfg will apply that script to every class, so if there's a class you don't want to use the script, you have to counter it in the specific <class>.cfg file. Also, putting a script in <class>.cfg will also apply it to every class, so you have to counter it in the other classes too. For example, if you bind 'mouse2" to "reload" in 'Engineer.cfg', but you want it to be bound to something else in the other classes, you have to re-bind "mouse2" to "something else" in all the other '(class).cfg' files.

Syntax

For any key binding or alias binding script within the Source engine developer console, the following format must be followed: COMMAND <argument1> <argument2>

Quotation marks are NOT necessary for binds and aliases with singular arguments, such as bind 1 slot1. However, if you wish to create a bind whose arguments may have multiple commands or parameters, you must enclose the plural arguments with quotation marks and separate the individual components with semicolons, such as alias melee1 "slot3; +attack" (creates a new "command," the alias "melee1," to automatically switch to your melee weapon and start attacking).

Examples:

COMMAND  <argument1>    <argument2>
alias    qBetween1and2  "slot2; wait 10; slot1"
bind     1              qBetween1and2

Note: I spaced the arguments out so you could see what applies to what, don't do this when you script.

How are simple binds written?

A simple bind takes the form of bind <key> <command>. For example, if we wanted to activate our primary weapon whenever we press the 1 key, then we could write a bind that looks like this:

bind 1 slot1
("slot1" is the command to activate your primary weapon)

Each bind must be written to a separate line in the autoexec.cfg file. For an example of basic keybinds, look at your config.cfg file in any text editor. For a list of useful commands, see the "Console Commands" section of this page.

How are complex binds written?

Complex binds take the same form as simple binds, except that they execute multiple commands when you press the key. Each command must be separated by a semicolon (;). For example, let's take a look at this complex bind for an Engineer (swiped from Patty on the TF2 boards):

bind "q" "build 0; wait 50; +attack; wait; -attack; slot1"
This bind attaches a series of commands to the q key. When the user presses the q key, the following series of commands is executed in order:
  • build 0 tells the game to enter the build mode for a Dispenser
  • wait 50 tells the game to wait 50 frames before executing the next command
  • +attack tells the game to start and continue the primary attack (we will learn more about plus and minus commands a little later)
  • wait tells the game to wait a moment before executing the next command
  • -attack tells the game to end the primary attack
  • slot1 tells the game to activate the primary weapon (in the case of the Engineer, this is the Shotgun)

How do plus(+) and minus(-) commands work?

Plus and minus commands are two-state commands. The plus state is executed (and continues to execute) while the key is pressed. The minus state executes when the key is released. For example:

bind "c" "+duck"
This bind causes the player to duck and remain crouched as long as the c key is pressed. When the c key is released, the player stands again.

It is important to note that, although the -duck command is never explicitly mentioned in the bind, it will still be executed upon release of the key.

What are aliases and how are they written?

Aliases are similar to binds except that, instead of binding a series of commands to a key, they allow the user to name a series of commands. That name can later be used in place of the series of commands. Using the Engineer example above, for example:

alias "buildDispenser" "build 0; wait 50; +attack; wait; -attack; slot1"
bind "q" "buildDispenser"
This alias followed by a keybind begins to show the power of the scripting system for TF2. We have created an alias called "buildDispenser" (although we could just as easily have called it "Fred" or "Snuffalupagus" or whatever we chose). Whenever we call the name of this alias, it executes the commands to which it's bound. Then we bind the q key to the alias name. Whenever we press the q key, that alias is executed.

Why are aliases more useful than binds? We'll get into that a little more deeply later, but imagine if you wanted to bind that same series of commands to multiple keys. Instead of typing the series again for each key, you can now just bind the alias name to each key. This way, if you want to change something in that series of commands, you only have to change it in one place.

How do plus(+) and minus(-) aliases work?

As with plus and minus commands, plus and minus aliases are two-state aliases. The plus state is executed (and continues to execute) while the key is pressed. The minus state executes when the key is released. For example, let's take a look at this plus/minus alias for an Engineer (swiped from Patty on the TF2 boards):

alias "+upgradeBuilding" "slot3; +attack"
alias "-upgradeBuilding" "-attack; wait; slot1"
bind "mouse3" "+upgradeBuilding"
  • +upgradeBuilding switches to the Wrench and begins to swing it.
  • -upgradeBuilding stops swinging the Wrench, waits a moment, then switches back to the Shotgun.
  • Then we bind the middle mouse button to the plus-state of the alias we just created. As long as the button is held down, the Wrench will continue to swing. As soon as the button is released, the minus-state will be executed.

Note that, even though the minus state is never explicitly mentioned in the keybind, the minus-state is executed upon release of the button. This is an automatic function of plus/minus aliases. {{Cleanup}}

How are cyclical or complex aliases written?

Cyclical or complex aliases are aliases that reference or even create other aliases. Since it's difficult to explain on a general level, let's take a look at an example:

alias "duckToggle" "duck1"
alias "duck1" "+duck; alias duckToggle duck2"
alias "duck2" "-duck; alias duckToggle duck1"
  • First, we create an alias called duckToggle and assign it to another alias called duck1.
  • Second, we create the duck1 alias, which begins and continues the duck command. Then it reassigns duckToggle to a third alias called duck2.
  • Third, we create the duck2 alias, which ends the duck command (i.e. causes the player to stand up). Then it reassigns duckToggle back to duck1.

Now, the first time we execute the duckToggle alias, it will perform the duck1 alias. But the next time we execute duckToggle, it will perform the duck2 alias. Now all that's left to do is to bind a key to the duckToggle alias:

bind "c" "duckToggle"

The next time we press the c key, the player will crouch. When we press c again, the player will stand up.

Key Combinations

I've used the word key combinations by lack of another word. What it actually does is this: by pressing a key, you temporary bind one or more keys to a different command then default. This makes it look just like you are using a key combination. An example to change class:

// Quick Class Joiner Script. It has been tested and works.
//Press shift and a key from 1-9 to change class.
//
alias +joinclass "bind 1 scout; bind 2 soldier; bind 3 pyro; bind 4 demoman; bind 5 heavy; bind 6 engineer; bind 7 medic; bind 8 sniper; bind 9 spy"
alias "-joinclass" "bind 1 slot1; bind 2 slot2; bind 3 slot3; bind 4 slot4; bind 5 slot5; bind 6 slot6; bind 7 slot7; bind 8 slot8; bind 9 slot9"
//
alias scout "join_class scout"
alias soldier "join_class soldier"
alias pyro "join_class pyro"
alias demoman "join_class demoman"
alias heavy "join_class heavyweapons"
alias engineer "join_class engineer"
alias medic "join_class medic"
alias sniper "join_class sniper"
alias spy "join_class spy"
//
bind "shift" "+joinclass"

By CupOfTea

Additional Scripting Tips

Why shouldn't I bind keys within aliases?

There are several reasons why you generally shouldn't bind keys inside of aliases.

  1. It makes it difficult for the user to find and change those keybinds.
  2. If you have several keybinds within the alias and the user wants to change keys, missing one of the binds could break the alias.
  3. It makes that alias specific to only that key, and prevents the user from binding multiple keys to a single alias.

Let's look at the duckToggle alias as an example. If we were to bind keys within that alias, it might look like this:

//This is an example of how NOT to write an alias!
alias "duck1" "+duck; bind c duck2"
alias "duck2" "-duck; bind c duck1"
bind "c" "duck1"

As you can see, when the alias is written this way, the c key is bound three times! In order for users to change that key, they must find every place where the c key has been bound. If they miss even one instance, that alias will break. Now let's replace those binds with alias reassignments:

//This is a much better approach
alias "duckToggle" "duck1"
alias "duck1" "+duck; alias duckToggle duck2"
alias "duck2" "-duck; alias duckToggle duck1"

bind "c" "duckToggle"

Now why is this better? Well, first, the user only needs to look in one place for the keybind, so it's much easier to change. But it also allows the user to bind multiple keys or buttons without changing the alias at all!

bind "c" "duckToggle"
bind "v" "duckToggle"
bind "b" "duckToggle"
bind "MOUSE3" "duckToggle"
//And so on, and on, and on

If we were binding our keys inside our aliases, then we'd have to write the aliases multiple times: once for each key we want to bind. But when we move the keybinding outside the aliases, we only have to write the alias once and can bind as many keys as we want to it.

When you're writing scripts for everyone to use, try to keep this principle in mind. Not only is it easier for users to customize, but it's also easier for you to write and maintain.

How to display text onscreen

First is the example of how, followed by the explanation.

You will need a file called con_filter_text_clear.cfg that contains:

 con_filter_text ""

Then in your autoexec.cfg

// aliases to execute the 2 scripts we made
alias "cft_clear" "exec con_filter_text_clear.cfg"
alias "cft_script" "con_filter_text |}"
// aliases to toggle console filtering
alias "cf1" "con_filter_enable 1"
alias "cf0" "con_filter_enable 0"
// to echo a newline
alias "cfnl" "cf0;echo;cf1"

// if you turn this off all text disapears!  it is left always on
developer 1
// start with filtering enabled so we don't see all the console garbage on our screen
cf1

// you can play with the following settings
con_notifytime 8	// How long to display recent console text to the upper part of the game window
con_nprint_bgalpha 50	// Con_NPrint background alpha.
con_nprint_bgborder 5	// Con_NPrint border size.
contimes 8		// Number of console lines to overlay for debugging.

// our simple screen print test... which you can expand to do menus or whatever
echo "|} Isn't ofb's screen printing cool?"
cfnl

Okay, that's it! Remember that when building menus you can use the clear console command to clear away your menu after it's done so it doesn't stay on the screen! Please don't clutter people's screen with "my script loaded v1.2.3 by alphaguy", we don't need spam, TF2 is pretty; leave it that way.

To understand how it works, we set up a .cfg because you can't nest quotes in an alias, alias "myalias" "echo "hi okay?"" for example doesn't work. If you've found a way to escape them properly, just edit this article and update it! We set developer to 1 which spams our users a lot, and they wouldn't know when to look for the menu, so we turn on console filtering which only prints messages that contain |}, we want something unique that wont' come up often but that doesn't look like ass on the screen because we'll always need to put it there.

Then when we used cfnl to echo a newline after our filtered text. This is because filtered echo's don't add a newline, and if we didn't all our later echos would just put all the text on the same line. Give it a try to see what I mean. So we turn filtering off, echo a newline, then turn it back on so we don't spam our users.

Warning: console filtering means that you will not get any console text that isn't from your scripts! To see console output again just type cft_clear.

Console Commands

A note on syntax... if an item is surrounded in square brackets ([ or ]) it is optional; if an item is enclosed in angle brackets (< or >) then it is required for that command to work.

ALIAS

  • Class Restrictions
    None
  • Description
    Alias is simply a means of reducing a long list of commands into a small package. For instance, take that example from the 'wait' command. If that were aliased, you could simply use that alias rather than try to remember the whole thing. Much easier. Plus it makes it easier to make things like communications scripts and such.
  • Syntax
    alias "<name_of_alias>" "<command; list>"
  • Arguments
    • None


BUILD

  • Class Restrictions
    Engineer, Spy
  • Description
    If the Engineer who used this command has enough metal, it will put him into build mode for the item specified. If a Spy uses this command, he will arm the Electro Sapper, ready to use on any hostile gadgets targeted.
  • Old syntax
    build <gadget_number>
  • Old arguments
  • New syntax
    build <group_number> <gadget_number>
  • New arguments
    • <group_number>
      0: Dispenser (only Engineer)
      1: Teleporter (only Engineer)
      2: Sentry Gun (only Engineer)
      3: Electro Sapper (only Spy)
    • <gadget_number>
      0: for Sentry Gun, Dispenser, teleporter entry or Electro Sapper
      1: for teleporter exit
  • Example
    > build 2 0 (build a Sentry Gun)
    > build 1 1 (build a tele exit)

NOTE: Currently you cannot call build a second time with an Engineer when you are already in build mode, you need to swap to any of your weapon before being able to call build again (bug or feature?)

NOTE: This issue is fixed, the build command can now be called repeately without problems.

NOTE: After the 01 may 2010 update, old syntax still works the same.

DESTROY

  • Class Restrictions
    Engineer, Spy
  • Description
    If you have built the gadget represented by the number, congratulations, you are the prowd owner of newly minted scrap metal. Useful for Engineers who want to relocate their buildings, but largely useless for Spies (who would be very unlikely to actually want to destroy their own Sappers).
  • Old syntax
    destroy <gadget_number>
  • Old arguments
    • <gadget_number>
      0: Dispenser (Engineer)
      1: Teleport Entrance (Engineer)
      2: Teleport Exit (Engineer)
      3: Sentry (Engineer)
      4: Electro Sapper (Spy)
  • New syntax
    destroy <group_number> <gadget_number>
  • New arguments
    • <group_number>
      0: Dispenser (only Engineer)
      1: Teleporter (only Engineer)
      2: Sentry Gun (only Engineer)
    • <gadget_number>
      0: for Sentry Gun, Dispenser or teleporter entry
      1: for teleporter exit
  • Example
    > destroy 2 0 (destroy Sentry Gun)
    > destroy 1 1 (destroy tele exit)

DISGUISE

  • Class Restrictions
    Spy
  • Description
    This, as is fairly easy to tell from the command itself, will disguise you as someone. Who, however, depends on the numbers. The first number represents the class you wish to be, while the second represents the team. When I was testing this out, team numbers above two still worked, so I imagine that it's forward-thinking support in case someone wants to remake a murderball map or something. Also, using negative numers allows you to disguise as either your team or the enemy team without setting up a team loader.
  • Syntax
    disguise <class_number> <team_number>
  • Arguments
    • <class_number>
      1: Scout
      2: Sniper
      3: Soldier
      4: Demoman
      5: Medic
      6: Heavy Weapons Guy
      7: Pyro
      8: Spy
      9: Engineer
    • <team_number>
      1: BLU
      2: Red
      -1: The Enemy Team
      -2: My Team

LASTDISGUISE

  • Class Restrictions
    Spy
  • Description
    As one might imagine, this command changes your disguise to the last one you had. It will remember disguises after a death. This is bound to 'b' by default. Lastdisguise random will chooses a random disguise that's neither Spy nor Scout. Using the command whilst already disguised as your last disguise will switch the weapon of the disguise to the corresponding weapon armed.
  • Syntax
    lastdisguise [random]
  • Arguments
    • [random]
      Chooses a random disguise that's neither Spy nor Scout

LASTINV

  • Class Restrictions
    None
  • Description
    This one's real easy. All it does is switch you back to your previously used weapon. (And I'm sure some of you probably realize that this is exactly the command that 'q' is bound to by default.)
  • Syntax
    lastinv
  • Arguments
    • None


MENUSELECT

  • Class Restrictions
    None
  • Description
    Menuselect does ONLY the menu portion of slotX, so refer to that entry for the detailed explanation. Also, it ONLY works on VGUI menus, such as the voice command menus, not the visual menus like those that are used to choose class, or select which building to construct as an Engineer, etc.
  • Syntax
    menuselect <item_number>
  • Arguments
    • <item_number>
      Any valid menu choice.
  • Note: Use cancelselect to leave a menu.



PLAY

  • Class Restrictions
    None
  • Description
    Plays a selected .wav file locally (which is to say, only the user will hear it through their client). To find a .wav file to play, you will need to have a GCF explorer such as GCFScape [2]. With this you can find the path and the sound file you wish to play, and reference it via the console (or scripting).
You can also add your own .wav files to C:\Program Files\Steam\steamapps\USERNAME\team fortress 2\tf\sound\. (See Custom .wav files below.)
  • Syntax
    play <path><sound_file_name.wav>
  • Example
    play vo/demoman_specialcompleted11.wav
  • Arguments
    • None

Custom .wav files

Adding your own .wav files is as simple as dropping them in your C:\Program Files\Steam\steamapps\USERNAME\team fortress 2\tf\sound\ folder. This folder represents the root of the .wav file's path. For example, if you drop a single .wav file called soldier.wav into that folder, then you can play it by using the following command:

play soldier.wav

If you drop a .wav file into a subdirectory of that folder, then you need to preface the filename with the name of that subdirectory. For example, if you drop Soldier.wav into C:\Program Files\Steam\steamapps\USERNAME\team fortress 2\tf\sound\classes\ then you can play it using the following command:

classes/soldier.wav

SLOT<X>

  • Class Restrictions
    None
  • Description
    This command has a little more depth to it than first appears. While it is mainly used to choose a weapon, it can also be used as feedback to the default voice menus at 'z', 'x', and 'c'. For instance, if you have 'f' bound to 'slot1' and activate voice_menu_1 ('z'), pressing 'f' would cause you to call for a Medic. With regard to choosing a weapon, this command can act one of two ways. If you have fast weapon switching turned on, this command will immediately switch to that weapon. If you do not, this command will only highlight whatever weapon slot it represents and it remains up to you to do the final selection. Or you can use this to do it for you: "slot1; wait 50; +attack; wait; -attack".
  • Syntax
    slot<slot_number>
  • Arguments
    • <slot_number>
      Needs to be a number between 0 and 10. slot10 exits a menu.


USE

  • Class Restrictions
    None
  • Description
    The "use" command is used to literally use the specified weapon. No muss, no fuss, you just pull out that weapon if you have it.
  • Syntax
    use <weapon_name>
  • Arguments
    • <weapon_name>
      • Scout
      tf_weapon_scattergun
      tf_weapon_handgun_scout_primary
      tf_weapon_pistol_scout
      tf_weapon_lunchbox_drink
      tf_weapon_jar_milk
      tf_weapon_bat
      tf_weapon_bat_wood
      tf_weapon_bat_fish
      • Soldier
      tf_weapon_rocketlauncher
      tf_weapon_rocketlauncher_directhit
      tf_weapon_shotgun_soldier
      tf_weapon_buff_item
      tf_weapon_shovel
      tf_weapon_sword
      • Pyro
      tf_weapon_flamethrower
      tf_weapon_shotgun_pyro
      tf_weapon_flaregun
      tf_weapon_fireaxe
      • Demoman
      tf_weapon_grenadelauncher
      tf_weapon_grenade_demoman
      tf_weapon_pipebomblauncher
      tf_weapon_pumpkin_bomb
      tf_weapon_bottle
      tf_weapon_base
      tf_weapon_sword
      • Heavy Weapons Guy
      tf_weapon_minigun
      tf_weapon_shotgun_hwg
      tf_weapon_lunchbox
      tf_weapon_fists
      • Engineer
      tf_weapon_shotgun_primary
      tf_weapon_sentry_revenge
      tf_weapon_pistol
      tf_weapon_laser_pointer
      tf_weapon_wrench
      tf_weapon_robot_arm
      tf_weapon_pda_engineer_destroy
      tf_weapon_pda_engineer_build
      • Medic
      tf_weapon_syringegun_medic
      tf_weapon_medigun
      tf_weapon_bonesaw
      • Sniper
      tf_weapon_sniperrifle
      tf_weapon_compound_bow
      tf_weapon_smg
      tf_weapon_jar
      tf_weapon_club
      • Spy
      tf_weapon_revolver
      tf_weapon_knife
      tf_weapon_pda_spy
      see the Build section for how to equip sapper

VOICEMENU

  • Class Restrictions
    None
  • Description
    This command is basically a direct method of using the 'z', 'x', and 'c' keys to send voice messages. Basically this allows you to bind a voice message directly to a key in the same fashion as how 'e' is by default bound to call in a Medic.
  • Syntax
    voicemenu <menu_number> <phrase_number>
  • Arguments
    • <menu_number>
      • 0 <phrase_number>
        0: Medic
        1: Thanks
        2: Go
        3: Move Up
        4: Flank Left
        5: Flank Right
        6: Yes
        7: No
      • 1 <phrase_number>
        0: Incoming
        1: Cloaked Spy
        2: Sentry Ahead
        3: Teleporter Here
        4: Dispenser Here
        5: Sentry Here
        6: Activate ÜberCharge
        7: (Medic Only) ÜberCharge Ready
      • 2 <phrase_number>
        0: Help
        1: Battlecry
        2: Cheers
        3: Jeers
        4: Positive
        5: Negative
        6: Nice Shot
        7: Good Job


WAIT

  • Class Restrictions
    None
  • Description
    This command is very useful when running multiple commands on the same line. Basically, what this command does is halts the execution of that line for X frames based on its parameter. If you don't use a parameter, it defaults to 1. For me, a value of 100 equals roughly a second, but I haven't had time to check whether this is server or client dependant or not, so you may have to adjust your own times accordingly. An example might be as follows for an Engineer upgrading his SG:

"use tf_weapon_wrench; wait; +duck; wait; +attack; wait 500; -attack; wait; -duck; lastinv" What that does is switch his Wrench, ducks, starts swinging the Wrench and continues for 5 seconds or so, stops swinging, stands up, and switches back to the last weapon used. If you were to attempt that without the waits, there's a pretty good chance it would fail rather spectacularly. It is important to note that, unlike wait commands of the past, waits will not delay further input, and can be used simply as a timer for scripting in general.

  • Syntax
    wait [wait_time]
  • Arguments
    • [wait_time]
      A value between 1 and <unknown>. Default is 1.
  • A Note About The Wait Command
Valve has fixed the functionality of the sv_allow_wait_command server variable. When disabled (set to 0) the engine simply ignores and omits any wait commands that the server is given. Consequently, many scripts on this website are broken or will only function in very specific situations. This variable is set to 1 by default, but many servers base their server.cfg files off of competitive league settings, which typically disable wait commands. Furthermore, scripts that do loops (see Autopistol Script for an example) will crash your client when triggered. There is a workaround to fix loop crashing, revolving around aliasing the wait command itself to do an alias over a repeating loop name.

Other Common GoldSource/Source Scripting Commands

Class select changeclass

Console Toggling toggleconsole

Crouch +duck

Drop item dropitem

Echo message echo

Fire weapon +attack

FPS view cl_showfps 1

Handedness left setinfo lefthand 1

Handedness right setinfo lefthand 0

Jump +jump

Last weapon lastinv

Logo spray impulse 201

Look down +lookdown

Look up +lookup

Map info showbriefing

Map list listmaps

Move backward +back

Move forward +forward

Netgraph netgraph <num>

Next weapon invnext

Playerlist listplayers

Previous weapon invprev

Public message say

Reload weapon +reload

Score overview +showscores

Screenshot snapshot

Strafe +strafe

Strafe Left +moveleft

Strafe Right +moveright

Secondary weapon function +attack2

Taunt taunt

Suicide kill

Suicide by Explosion explode

Team message say_team

Team select changeteam

Turn left +left

Turn right +right

Voice Chat +voicerecord

( "S.A.S's Guide to Counter-Strike: Scripting" )

Bindable keys

The following is a list of bindable keys in TF2 and the terms used in scripting. The left column shows the name used in TF2 scripting to identify each key. The right column shows the key's name in plain English.

Scripting Name Normal Name
1 One
2 Two
3 Three
4 Four
5 Five
6 Six
7 Seven
8 Eight
9 Nine
0 Zero
A A
B B
C C
D D
E E
F F
G G
H H
I I
J J
K K
L L
M M
N N
O O
P P
Q Q
R R
S S
T T
U U
V V
W W
X X
Y Y
Z Z
F1 F1
F2 F2
F3 F3
F4 F4
F5 F5
F6 F6
F7 F7
F8 F8
F9 F9
F10 F10
F11 F11
F12 F12
` Left Quote or Tilde
' Right Quote
- Hyphen
= Equals sign
] Right Bracket
\ Backslash
, Comma
/ Slash
SPACE Spacebar
ENTER Enter
ESCAPE Escape
PAUSE Pause/Break
BACKSPACE Backspace
TAB Tab
SEMICOLON Semicolon ;
SHIFT Shift
CTRL Control
ALT Alt
UPARROW Up Arrow
DOWNARROW Down Arrow
LEFTARROW Left Arrow
RIGHTARROW Right Arrow
INS Insert
HOME Home
PGUP Page Up
PGDN Page Down
DEL Delete
END End
KP_HOME Keypad Home/7
KP_UPARROW Keypad Up Arrow/8
KP_PGUP Keypad Page Up/9
KP_LEFTARROW Keypad Left Arrow/4
KP_5 Keypad 5
KP_RIGHTARROW Keypad Right Arrow/6
KP_END Keypad End/1
KP_ENTER Keypad Enter
KP_DOWNARROW Keypad Down Arrow/2
KP_PGDN Keypad Page Down/3
KP_INS Keypad Insert/0
KP_DEL Keypad Delete
KP_SLASH Keypad Backslash
KP_MINUS Keypad Hyphen
KP_PLUS Keypad Plus
KP_MULTIPLY Keypad Asterisk
MOUSE1 Mouse Button 1
MOUSE2 Mouse Button 2
MOUSE3 Mouse Button 3 (Middle Button)
MOUSE4 Mouse Button 4(*)
MOUSE5 Mouse Button 5(*)
MWHEELUP Mouse Scroll Wheel Up
MWHEELDOWN Mouse Scroll Wheel Down

(*)Not standard on all mice. Only applies when the mice uses those two buttons as generic buttons.

Scripting FAQ

Global Script Questions

Print Console to TXT file from Console Command

Posted by Josiah
  • Q. Is there a way to Print the contents of the console to a txt file through a console command? I set up a simple script for my server to print out the status and go right to the ban menu of sourcemod. We have some bookkeeping practices for my server where we like to keep steam ids of banned people. There fore I want to get that status list in to a simple text file so it can be accessed later.
  • A. There is a command called "condump" that saves all of the text currently in the console window to a condump###.txt file in Team Fortress 2/tf. It saves the entire console, but your status list would just be at the bottom. --IAmThermite 21:25, 13 September 2009 (UTC)

HUD On/Off

Posted by Bolange
  • Q. Is there anyway to turn the HUD on or off for use in a script?
  • A. cl_hud_minmode set to "1" will give you a minimalist HUD view, you can also set this by going to your Options->Multiplayer. If you want to completely remove all HUD items though, you can use the commands cl_drawhud 0 to remove the HUD and r_drawviewmodel 0 to remove the gun (useful for screenshots), but Valve seem to have now classed these commands as cheats so they can only be used when sv_cheats is set to "1" --Aurora 01:00, 22 November 2007 (BST)

Reloading .cfg without closing the game?

Posted by Jabu2oz
  • Q. Is there a way of "refeshing" a .cfg file (e.g. autoexec.cfg) without closing/reopening TF2? This would be useful when trying out scripts. (NB, I have tried "exec autoexec" from the console (and restarting the server) but this didn't seem to work).

Edit: Thanks, "exec autoexec.cfg" worked, but I did have to start a server without commentary mode on (single player). --Jabu2oz 15:10, 19 December 2007 (CST)

  • A. Did you try entering "exec autoexec.cfg" into the developer console? You need to give it the full file name if memory serves. If you're working with a server, some settings require a map change to take effect (sv_pure comes to mind here). -- WanderingFox (Talk • Contribs) 15:15, 18 December 2007 (CST)

Removing Scripts

How do we remove scripts?--B-MAN 09:57, 1 May 2010 (UTC)

A. You can just delete them from your cfg file. To temporary delete them, type alias "YourOriginalAliasHere" " " to replace the offending alias with a blank one. This applies until the cfg files are run again. --Kurathedog 03:33, 19 October 2010 (UTC)

Class Specific Script Questions

Multiple Key Binds

Posted by Bolange
  • Q. Is it possible to make a variable to use the same key with multiple bindings depending on the class you are? e.g. In Spy, press F1 to disguise in Scout, in Engineer, press F1 to build a sentry etc...
  • A. Yes, however you will need to create separate scripts for each class, i.e. Spy.cfg and engi.cfg and put the binds in these, see the Class Config Community Scripts for more information. --Aurora 14:10, 21 November 2007 (BST)

CTF Getting -or not- Intelligence as Spy

Posted by Xerox
  • Q. Is there a way to bind a command for not to take enemies intelligence when you're in Spy, unless you press a key? You might need it if a sentry is very near the case and you want to sap it first.

See also

  • Bindable keys - A List of the keys that are bindable and their scripting names

[[Category:Scripts]]