Scripting is the use of configuration files (.cfg) to create new keybinds and aliases automating complex behaviors and console command sequences.
- Keybinds connect a key to a console command, such as choosing a weapon slot or saying pre-written text in chat.
- Aliases build new commands by executing a series of console commands whenever they are used. An alias might define crouching and jumping as a single crouch-jump command, which can then be bound to a key.
These scripts range in complexity from simple lists of commands to self-referential loops and nested aliases that redefine one another. With enough time and effort, you can use these tools to create almost any behavior available to the client at the press of a single key.
Basic scripting files
Left4Dead2 automatically reads several game files and executes any keybinds and aliases within them. Here is the list of those files:
- 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. It should also be noted that anything changed in another .cfg is also changed in the config.cfg file.
- 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 within this file.
Here is a list of syntactic rules:
- For any keybind or alias to work, you need to follow this format:
- command <argument1> <argument2>
- command is the kind of scripting you want. You have three choices:
- bind - Used to bind commands to a particular key.
- alias - Used to execute commands when the alias is executed.
- exec - Used to execute commands automatically when a configuration file is loaded.
- <argument1> is either the key being bound or the name of the alias being created.
- <argument2> is either the command being bound or the commands executed by the alias.
- To run multiple commands, you must put the entire argument in quotation marks and separate the commands with semicolons, like so:
- alias "spraynpray" "+attack; wait 500; -attack"
- bind "mouse3" "spraynpray"
- When executed, the alias starts firing the player's weapon, continues for 500 physics frames (that is roughly five seconds if you are on a server that runs at a 100 frames per second), and then stops firing. The alias is keybound to execute when you press the middle mouse button.
Source allows scripts and aliases to be bound to any key on the keyboard. The key you wish to bind a command to is placed after your bind command and before the action you want the key to execute, as in the section above. Most keys are self-explanatory, as all alphanumerics (a-z, 0-9) and function keys are simply listed by typing that key ("bind a" binds a key to 'a', "bind 5" binds to '5' and "bind F7" binds to 'F7'). Other keys require you type specific names into your .cfg file in order to access them, and these names are not all obvious. A list of these keys is provided below:
List of key names
- Keyboard Keys: Names of Keybinds
- Left Shift: SHIFT
- Left Ctrl: CTRL
- Left Alt: ALT
- Right Shift: RSHIFT
- Right Control: RCTRL
- Right Alt: RALT
- Tab: TAB
- Backspace: BACKSPACE
- Insert: INS
- Scroll Lock: SCROLLLOCK
- Pause/Break: NUMLOCK
- Home: HOME
- End: END
- Delete: DEL
- Page Up: PGUP
- Page Down: PGDN
- Up Arrow: UPARROW
- Down Arrow: DOWNARROW
- Left Arrow: LEFTARROW
- Right Arrow: RIGHTARROW
- Numpad Keys: Names of Keybinds
- 0: KP_INS
- 1: KP_END
- 2: KP_DOWNARROW
- 3: KP_PGDN
- 4: KP_LEFTARROW
- 5: KP_5
- 6: KP_RIGHTARROW
- 7: KP_HOME
- 8: KP_UPARROW
- 9: KP_PGUP
- Enter: KP_ENTER
- ".": KP_DEL
- "+": KP_PLUS
- "-": KP_MINUS
- "*": KP_MULTIPLY
- Mouse Wheel Direction: Names of Keybinds
- Mouse Wheel Up: MWHEELUP
- Mouse Wheel Down: MWHEELDOWN
- Mouse Left Click: MOUSE1
- Mouse Right Click: MOUSE2
- Mouse Wheel Click: MOUSE3
- Mouse Left Side Click: MOUSE4
- Mouse Right Side Click: MOUSE5
Using the above keynames, you are able to place the following example command into one of your config files: <bind KP_ENTER "voicemenu 0 1">. When you hit 'Enter' on your numpad in-game, you will trigger the "Thanks" voice command.
Most commands accept a single argument, which is whatever value you want to execute.
bind "q" "sv_alltalk 1"
A handful of important commands accept multiple arguments. Here are some examples:
- disguise X Y - This disguises the Spy. X is the class numbered 1 through 9, while Y is the team numbered 1 or 2.
- voicemenu X Y - This executes a voice command. X is the number of the primary menu, while Y is the command position in that menu.
Example: "voicemenu 1 1" is the command for Spy, so:
bind "t" "voicemenu 1 1"
This command will make your character yell Spy whenever you hit the key.
This command cycles through a range of specified values whenever it executes and applies those values to another command. This has the form of:
- command "<argument1>" "incrementvar <argument2> X Y Z"
- X and Y represent the range of values you want to execute with <argument2>.
- Z is the size of the step you want to make while you cycle through the range.
If you wanted a value range of 1 through 10 and you wanted to increment your value by 2 each time the command was executed, you'd make X Y Z into 1 10 2. Each time it executes, <argument2> will execute with an incrementing value of 2, 4, 6, 8, 10, 2, 4, 6, 8, 10... and so forth.
Here is a real example of incrementvar in action:
- bind "n" "incrementvar net_graphpos 1 3 1"
This binds the key "n" to cycle to the next position in the 3 available net_graph positions.
The + and - commands
These commands have two states. While the bound key is pressed, the + command executes and continues to execute. When the key is released, the - command executes and continues to execute.
- bind "c" "+duck"
This + command is bound to "c" so whenever the key is pressed, the player ducks. Whenever the key is released, "+duck" is swapped to "-duck" and the player stops ducking.
In general, if a command or alias is bound to a key, a + tells the game to run the command as long as the key is held. Similarly, if a command or alias is bound to a key, a - tells the game to run the command when the key is released.
If an alias is defined with a + in front of it, the alias will be run whenever the key is pressed, as the key is pressed. The - command will then run as the key is released.
If you want the game to delay for a period of time during an alias, or if you want to avoid client crashes caused by executing commands too quickly, use the wait command.
The wait command tells the game to delay the next command in the script by one physics frame, something like a full turn in the TF2 rules. It accepts values such as "wait 50", telling the game to wait fifty frames before the alias continues. "wait 100" is roughly a second on a 100 FPS server.
Some servers disable the wait command. While playing on them, wait commands will be ignored, making some scripts susceptible to crashes. A script containing an indeterminate loop spaced by wait commands will always immediately hang upon usage on such servers.
An alias is like a variable that stores a series of commands which can be executed as a group. A simple alias will take the form:
alias "aliasname" "command1; command2; command3"
You can then execute the commands through a bound key:
bind "key" "aliasname"
Whenever the key is pressed, "command1", "command2", and "command3" are executed in order.
Aliases can execute any command including other aliases. Furthermore, an alias can execute an alias in order to redefine that alias's commands. This allows you to create cycling aliases. Here is a very simple example:
bind "key" namescroll
alias namescroll "firstname"
alias firstname "setinfo name "First_name"; alias namescroll secondname"
alias secondname "setinfo name "Second_name"; alias namescroll thirdname"
alias thirdname "setinfo name "Third-name"; alias namescroll firstname"
This is difficult to read, so to break it down.
- The first line binds "key" to an alias "namescroll" which we have yet to define.
- The second line creates the alias "namescroll" which executes the command "firstname"
- The third line defines the "firstname" alias as two commands:
- The first command sets your in-game name to "First_name"
- The second command redefines the alias "namescroll" as an alias for executing the alias "secondname"
- The fourth line defines "secondname" in the same manner. A different in-game name is set, and then "namescroll" is redefined to another alias "thirdname"
- The fifth line defines "thirdname" just like the two before it, but with a twist. It redefines the "namescroll" alias as executing the "firstname" alias.
This completes a loop. Each press of the key executes a command and redefines the alias bound to the key, so that when it is next pressed it will execute a different command. If there were no loop, then the alias "namescroll" wouldn't always have another alias to execute with each keypress.
Aliases can be used in conjunction with the wait command to create looping aliases.
Warning:Not having the wait in place, or being on a server with wait disabled will cause this example to crash TF2.
alias "Loop" "echo Looping every 150 ticks.;wait 150;Loop"
Lets break this down into components:
The echo displays a message to the console, just so you know it works.
The wait makes it wait 150 ticks between iterations
Loop calls the alias again, restarting at the echo.
Loop starts the looping alias.
You can also create loops of alias commands, like this example:
alias "Loop1" "echo Loop 1;wait 150;Loop2"
alias "Loop2" "echo Loop 2;wait 150;Loop1"
Loop1 calls Loop2 which in turn calls Loop1, etc...
This method can also be used for breaking a loop without clearing the loop alias:
alias "Loop1" "echo Loop1;wait 150;Loop2"
alias "Loop2" "Loop1"
This would create a loop, then
would break it, by clearing the Loop2 alias.
You can use these for button presses(Via the +/- prefixes covered earlier) like this:
alias "Loop2" "Loop1"
alias "Loop1" "echo Loop1;wait 150;Loop2"
alias "+Loop" "alias Loop2 Loop1;Loop2"
alias "-Loop" "alias Loop2"
bind "<Key>" "+Loop"
In order of what it's doing:
Make Loop2 point to Loop1
Make Loop1 echo 'Loop1' to the console, wait 150, then call Loop2
make +Loop point Loop2 to Loop1 and run Loop2
make -Loop clear Loop2's link, breaking the loop
Here are a few examples of useful scripts.
Displays netgraph only when you hit tab.
//netgraph toggle alias "+ng" "+showscores; net_graph 1" alias "-ng" "net_graph 0; -showscores" net_graphheight 0 //Move the graph closer to bottom net_scale 1 //Smaller net_graph
A glow script is a script that changes the default auras around item, team mates, and enemies to make important events more visible on screen or to convey additional information about the game state.
This script for infected will toggle survivor auras between temporary and permanent health, so that infected can see which survivors are bleeding out.
cl_glow_survivor_health_bleed_pulse_amount 0;cl_glow_survivor_health_bleed_pulse 0 alias GlowIncludeBuffer "incrementvar cl_glow_survivor_health_include_buffer 0 1 1; wait 50; GlowIncludeBuffer" GlowIncludeBuffer
Null cancelling movement
This script rebinds movement keys so that accidentally pressing two opposing directions will not cause the player to stop moving. This is useful for juking tanks and for smoothing movement in general.
// the jukery is in business // Null-cancelling movement script // (prevents you from pressing two opposing directions, which causes you to stop moving) alias +mfwd "-back;+forward;alias checkfwd +forward" alias +mback "-forward;+back;alias checkback +back" alias +mleft "-moveright;+moveleft;alias checkleft +moveleft" alias +mright "-moveleft;+moveright;alias checkright +moveright" alias -mfwd "-forward;checkback;alias checkfwd;" alias -mback "-back;checkfwd;alias checkback;" alias -mleft "-moveleft;checkright;alias checkleft;" alias -mright "-moveright;checkleft;alias checkright;" alias checkfwd; alias checkback; alias checkleft; alias checkright; bind w +mfwd bind a +mleft bind s +mback bind d +mright
These aliases can be bound to keys to turn autofire on or off with the associated weapon.
alias autofireprimary autofireoff //Status variables invoked when selecting weapons. defaults to off alias autofiresecondary autofireon //Always autofire with the secondary alias autofireon "bind mouse1 +autofiretoggle" alias autofireoff "bind mouse1 +attack; -autofiretoggle"
alias autofireloop "+attack; wait 5; -attack; wait 5; autofire" alias +autofiretoggle "alias autofire autofireloop; autofire" alias -autofiretoggle "alias autofire;"
bind e "slot1;autofireoff" bind q "slot2;autofireon"
Jump spam for bunnyhopping boomers. Bind a key to +jumpp and hold it down for jump spam.
//jump spam like an idiot //> alias jumppp "+jump;wait 5;-jump;wait 5;rejumppp" alias +jumpp "alias rejumppp jumppp;jumppp" alias -jumpp "alias rejumppp wait 5"
- Steam Users' Forums - TF2 Scripting Tutorial. This covers the basics of scripting, using numerous useful, approachable examples.
- TF2 scripting tutorial - Warrior Nation Network. This is a much more advanced article, which requires pre-requisite knowledge of the basic scripting syntax.
- Gamebanana.com - TF2 scripts. Hundreds of scripting examples for TF2.