'Rotating keybinds' is something I came up with for remapping large numbers of
keybinds quickly and easily, without ever having to type 'bind' or 'exec'
commands in the console.
This technique allows you to have an infinite (yes, infinite!) number of keybind
sets that you can cycle through. You can have different keybinds for
assault/defense, or a keybind set for each map. You can have two sets of 'Great
Job Team!', etc. keybinds; one that does the squad commo of 'GJT', and another
that does 'GJT' as a teamsay. (No more "West!" when you meant to say "Good Job
Soldier!") And you can probably do some cool stuff that I haven't even thought
of yet!
The 0XC0FFEE Keybind Philosophy
Generally, binding multiple (non-commo) actions to a key will get you into
trouble (some multiple action keybinds are considered cheating by many people,
including me). Don't bind multiple actions to keys unless they are all commo
actions.
Also, please don't bind extra comms to common actions like reloading. It's a
waste of a line on people's consoles to have someone say 'Cover me while I
reload' when they are on the other side of the map. Remember that there are only
a limited number of lines in each person's message console, and everyone needs
to see reports and deaths. Don't clog people's message consoles up with useless
blabbering.
My keybinds (and there are a LOT of them) are for communicating with my team
only. They are not for saying 'W+f 0\/\/|\|3D!' every time I get a kill. They
are not for belittling or harassing other players. They are for reporting
enemies and issuing instructions or warnings: "Coming up the ladder, HOLD YOUR
FIRE!", "E MAIN ENTRANCE!", "Please keep the main pump room doors closed!" etc.
To summarize: don't be a chat-spamming idiot. Use commo keybinds judiciously and
when appropriate. With good commo keybinds, you can help your team win by
providing timely and accurate information on enemy movements, and by the
superior teamwork enabled by good communication.
Rotating Keybind Tutorial
This is an advanced technique. If you are unfamiliar with changing keybinds,
creating and executing text files, and editing the command aliases in your
USER.INI file, you should probably acquaint yourself with those subjects first.
I will attempt to explain this as best I can, using some very simple examples.
This will take a while, bear with me...
The first step in creating your own rotating keybinds is to create text files
that contain your keybinds. I'm a Pipeline whore, so my example will use
Pipeline specific keybinds for reporting enemies. (NOTE: teamsay commands do not
work in single-player mode, you will need to connect to a server to try out the
examples.)
Create a text file in your AA/system directory named DEFENSE.TXT with the
following contents:
code:
;DEFENSE.TXT
bind numpad1 teamsay E PRIMARY VALVE!
bind numpad2 teamsay E SECONDARY VALVE!
bind numpad3 teamsay E EXTERIOR VALVE!
You can load these keybinds by typing 'exec defense.txt' in the AA console.
Now, let's make one for assault. Instead of reporting enemies at the objectives
(which is practically a given), our assault keybinds will be for reporting
enemies exiting the buildings.
Create a text file in your AA/system directory named ASSAULT.TXT with the
following contents:
code:
;ASSAULT.TXT
bind numpad1 teamsay E MAIN ENTRANCE!
bind numpad2 teamsay E NORTHSIDE (SECONDARY) ENTRANCE!
bind numpad3 teamsay E OUTSIDE EXT VALVE!
You can load these keybinds by typing 'exec assault.txt' in the AA console.
We can bind the execution of these two text files to the PageUp and PageDn keys
by doing these commands in the AA console:
Now, pressing PageUp will load the defense keybinds, and pressing PageDn will
load the assault keybinds.
But what would be even better is if we could have just one button switch between
assault and defense keybinds, an assault/defense toggle, if you will. This is
easily possible. The trick is that the toggle key has its mapping changed by the
very text file it is invoking.
So let's add a line at the bottom of the DEFENSE.TXT:
code:
;DEFENSE.TXT
bind numpad1 teamsay E PRIMARY VALVE!
bind numpad2 teamsay E SECONDARY VALVE!
bind numpad3 teamsay E EXTERIOR VALVE!
bind pageup exec assault.txt
And let's add a similar line at the bottom of ASSAULT.TXT:
code:
;ASSAULT.TXT
bind numpad1 teamsay E MAIN ENTRANCE!
bind numpad2 teamsay E NORTHSIDE (SECONDARY) ENTRANCE!
bind numpad3 teamsay E OUTSIDE EXT VALVE!
bind pageup exec defense.txt
Now we can switch between assault and defense keybind sets by pressing only the
PageUp key! Each keybind set remaps PageUp to load the other set.
This could be carried on infinitely, with each press of the PageUp key loading a
different set of keybinds and remapping PageUp to load the next set. You could
even remap PageUp and PageDn to 'page' through the list, by remapping them to
act as 'next' and 'previous' buttons. (This is what I have done. Although I only
have three sets of keybinds to cycle through, I had to do it just as 'proof of
concept'.)
But now we have another problem: how to know which keybind set is the active
one. And AA does not provide any means (that I know of) for displaying messages
on the console, other than teamsay or global messages. The 'type' command in the
Unreal engine doesn't seem to work. And we don't want to bother our teammates by
announcing what keybind set we just loaded, because we might be switching them a
lot.
Fortunately, there's a way around this. We can use the PunkBuster client to
display a console message, like this:
code:
pb_* YOUR MESSAGE HERE *
If you put a line like that in a text file that you exec, the Punkbuster client
will display an error message on the console, like this:
code:
PunkBuster Client: Unknown Command/Setting: pb_* YOUR MESSAGE HERE *
Crude, but effective. There may be a better way to put a message on the console,
but I don't know it. If anyone knows of one, I'd love to hear about it. For now,
this will have to do. (If anybody is worried that PB is logging your PB client
error messages, I've been doing this for months and have never had a problem. So
either they aren't, or they don't care.)
To have our text files display a message on the console, let's add another line
to DEFENSE.TXT:
code:
;DEFENSE.TXT
bind numpad1 teamsay E PRIMARY VALVE!
bind numpad2 teamsay E SECONDARY VALVE!
bind numpad3 teamsay E EXTERIOR VALVE!
bind pageup exec assault.txt
pb_* DEFENSE keybinds loaded *
And ASSAULT.TXT:
code:
;ASSAULT.TXT
bind numpad1 teamsay E MAIN ENTRANCE!
bind numpad2 teamsay E NORTHSIDE (SECONDARY) ENTRANCE!
bind numpad3 teamsay E OUTSIDE EXT VALVE!
bind pageup exec defense.txt
pb_* ASSAULT keybinds loaded *
Now when we press the PageUp key, not only is a different set of keybinds
loaded, but we also get a nifty message on the console saying WHICH keybinds
have just been loaded.
You could also take this one step further, and make a text file with nothing but
pb_** messages. Make one called DEFENSELIST.TXT like this:
code:
;DEFENSELIST.TXT
pb_* 1 - E PRI *
pb_* 2 - E SEC *
pb_* 3 - E EXT *
If you exec DEFENSELIST.TXT, you will see this on your console:
code:
PunkBuster Client: Unknown Command/Setting: pb_* 1 - E PRI *
PunkBuster Client: Unknown Command/Setting: pb_* 2 - E SEC *
PunkBuster Client: Unknown Command/Setting: pb_* 3 - E EXT *
And, of course, you could bind execution of DEFENSELIST.TXT to, for example, the
K key, by doing 'bind K exec defenselist.txt'. You could also add a line to
DEFENSE.TXT and ASSAULT.TXT that would remap K to exec DEFENSELIST.TXT and
ASSAULTLIST.TXT respectively. (I use the F12 key for this function.)
Unfortunately, there are limitations to what you can accomplish with keybinds by
using text files. You cannot bind multiple actions to a key, like you can in the
USER.INI file. For example:
code:
I=reportin|commoradio|commosendmessage 25
This binds the following actions to the I key: report in, switch to radio commo
(in case commo was set to something else, like hand), and send the message "I'm
hit!".
You can't do the same thing with a 'bind' command in a text file. What happens
is that the text file executes the commands after each pipe, so having:
code:
bind I reportin|commoradio|commosendmessage 25
in a text file results in the following actions:
'I' gets mapped to the 'reportin' action, and nothing else
your commo gets switched to radio
the message 'I'm hit' is sent over the radio
To get around this limitation, you can use command aliases. At the top of the
[Engine.Input] section of your USER.INI file are several lines like this:
The 'commoradio|commosendmessage 99' is to put your commo back to regular radio,
rather than leaving it on the squad radio. The 'commosendmessage 99' part is
required because 'commoradio' switches to radio commo and leaves the radio commo
menu open, and you have to press a key to close it. '99' is just an invalid
message number that closes the menu. '666' would probably work just as well.
To map F7 to our squad radio 'Good Job Soldier', we can put this line in a text
file, then 'exec' it:
code:
bind F7 Squad_GJS
And then, of course, you could have in another text file:
code:
bind F7 teamsay "Good Job Soldier!"
In my own configuration, I have F5 switch between squad leader messages and
teamsays by executing the text files SQUAD.TXT and NO_SQUAD.TXT.
First, you need to have the following lines in the aliases section of your
USER.INI file:
With the no_squad keybinds loaded, F5 switches back to the squad keybinds.
Now I can use the same key (Enter) for "Report In!" regardless of whether I am
squad leader or not. If I am squad leader, I press F5 until I see 'SQUAD
keybinds loaded', and Enter sends "Report in!" over the squad radio. If I am not
squad leader, I load the no_squad keybinds, again, simply by pressing F5 until I
see 'NOSQUAD keybinds loaded', and Enter teamsays ">> REPORT IN! <<". Same thing
for GJS, GJT, etc.
Rotating Keybinds: A Critical Analysis
In my
rotating keybinds tutorial, I explained how it was possible to make a
single key cycle through multiple sets of keybinds by execing text files. This
is very useful for map-specific enemy reporting or gameplan keybinds, which I
map to my number pad.
The trick was that the key that exec'd a text file would be re-bound during the
execution of that text file. So, you would press a key, PageUp, for example,
which would exec text file A. Inside text file A was a bind command to re-bind
PageUp to exec text file B. When text file B was exec'd, PageUp could be
re-bound back to exec text file A, completing the loop, or you could continue on
with text files C,D,E, and F. The last text file must remap PageUp to load the
first text file in order to maintain a looping structure.
This is all well and good. Except for a number of shortcomings:
1) Execution of each text file would remap 11 (0-9, plus period) keys on the
numberpad. This would cause the game to lag a bit, because each bind requires
that the USER.INI file be changed. Bind a key, write to USER.INI. Bind a key,
write to USER.INI. And then nine more times. For each press of the 'cycle
keybind' button.
Given that this keybind loading lag is unavoidable, it only makes sense to
minimize the number of times new keybinds are loaded. The ‘rotating keybinds’
technique does not do this. In fact, if you have more than two keybind sets in
the rotation, you _will_ have to load a set you aren’t going to use (possibly
several), on your way to the one you want.
2) Although the number of keybind sets that you could cycle through is
theoretically limitless, it quickly becomes impractical as you add keybind sets.
If you are on set #1 for example, and want to load set #9, you would have to
press your 'cycle keybind' button eight times. 11 writes to USER.INI times 8
keypresses means that USER.INI is updated 88 times! And if you don't have two
'cycle' buttons (forward and backward), you could easily skip past the set you
wanted, and have to go all the way through the list again! This is highly
inefficient and annoying.
3) The 'rotating' enabled by the looping structure requires that multiple text
files be edited to add or remove text files from the rotation. This is not a big
deal if you just need to add one more set to the rotation, but if you want to
move a set from the middle of the list to the end, or if you want to insert a
set into the middle of the list, you will have your work cut out for you. And it
can get tough to keep it all straight.
4) There are 32 AA maps. And two teams per map. That’s 64(!) keybind sets, if
you wanted to do them all. How the hell do you manage that many keybind sets?!
Not by loading each one in sequence until you find the one you want, that’s for
sure!
With all these points in mind, I set about developing my next keybind loading
technique. I wanted the following:
-random access to a full set (11 keys) of number pad keybinds for every single
AA map (currently 64 sets)
-the capability to (easily) add maps in the future, when they are included with
new releases of AA
-easy changing of keybinds for individual maps (by editing as few files as
possible, with no knowledge or understanding of the keybind loading mechanisms
required)
-the ability to display a list of the currently active keybinds
-keybinds must be toggle-able between assault & defense
Over the past few weeks, I have come up with another way to load map-specific
number pad keybinds, that meets all of the requirements above. It relies on two
of the techniques employed with 'rotating' keybinds: 1) using the Punkbuster
client to display 'error' messages with the menu contents, and 2) re-binding the
'exec' key in exec'd text files
I am providing the system I came up with for AA community use
HERE. Installation instructions and full keybind and map lists are
included.
AA Binds v2
Since I created the rotating keybinds tutorial, I have discovered that Unreal
color codes work in the PB client error messages. This is fortunate, as it
allows menus with much greater readability.
So what I did was to have PageUp exec a text file that remaps the number pad to
act as menu selections. So, you press PageUp, and you see this in your console
window:
At this point, the only number keys on the numpad that are active are 0, 1, and
2. All other numeric numpad binds have been erased, so pressing 4 or 5 won't do
anything.
Pressing 0 will present a list of the regular map groupings, like this:
Then, pressing 0 to select 172nd Infantry Brigade shows a list of the 172nd
maps:
Pressing 1 will load the Pipeline keybinds and display the message:
Notice that you do not have to select assault or defense. The Pipeline map
defaults to 'defense', but this is easily changed by editing the appropriate
text file. To switch between assault and defense, I have utilized the PageDn key
to act as an assault/defense toggle. Repeated pressing of PageDn does this:
I have also employed the F12 key to display a list of the key assignments for
the active bind set. Pressing F12 with the pipeline defense binds loaded
displays:
So, you can press in rapid succession: PageUp 0 0 1 and you will load the
Pipeline keybinds. PageUp 1 0 1 will load SF Hospital binds, etc. Each map has a
three digit code assigned to it, making random access to all 32 maps a piece of
cake!
Another bonus is the single player keybind set. Press PageUp, then 2 to load the
single player keybind list. Here it is:
Notice items 0 and 1. While the single player menu is active, you can type the
three digit map code and instead of loading keybinds for that map, it loads that
map. No more checking a map list to see what the actual filename is if you want
to check out a map in single player mode. They’re all right here!
I have also incorporated the SSG/not SSG toggle (on F6) used in the rotating
keybinds method:
While in a keybind or map loading menu, the numpad period key acts as a ‘cancel’
button and will unbind all of the number keys on the numpad.
It also remains active as ‘cancel’ in the single player bindset.
All the keybinds reside in the directory C:\aabinds2, with each map having its
own subdirectory. Inside each map subdirectory are four files: the defense
keybinds, the defense keybind list, and the assault keybinds and keybind list.
This makes it very easy to edit the keybinds and their associated listing.
You can edit keybinds for only the maps you use, without having to bother with
any of the others. In my own case, I only have pipeline binds configured, so
that’s all that is configured in the aabinds2 system. I have only provided a
framework that others can build on.