[nice picture]

Keymap Design Guide

By Dave Morris and Frank Niessink.
Last updated on 22 october 1996.
Disclaimer This article is intended for Bronco, and has been based on the COW client (version 1.03, patch level 1), though it should work for most other Bronco clients as well.

Acknowledgement A lot of information comes from the COW documentation, hence we are indepted to all people who contributed to the COW client.

Contents

Introduction This article describes what a keymap is and how you can design one that best suits your needs. All Netrek clients have a default mapping of keys to actions. For example, the key _ (underscore) is mapped to the action turn on tractor beam. Of course, this key is kind of hard to reach during tight combat. To adjust the keymap to your personal preferences, clients provide a way to alter the default key layout.

In this article you will learn more precisely what a keymap is, how it can be changed and how you can design a keymap that suits your needs. We are not going to tell you that a certain keymap is the one best keymap. We will merely try to hand you the necessary information you need to design your own keymap.

How to specify a Keymap This chapter will explain how you can specify your keymap. It not only covers the keymap syntax, but also the control-keymap, buttonmaps, mouse-as-shift, and all other things you can use to create the keymap you want.

Keymap Syntax

Keymaps can be defined in the options window (shift-O by default) or in your .xtrekrc. We would not recommend that the options window be used as it has very limited space and requires altering every game. To set up a .xtrekrc just create a file of that name in your home directory with personal read permissions set for it (if you are not using UNIX just check the documentation that came with the client for the proper name and place of the xtrekrc-file). A .xtrekrc only acts on changes in the defaults, so a blank .xtrekrc should not affect your client in any way.

For remapping keys in the options window use the form 'xy' where 'y' is the default key of the action that you wish to now be in position 'x' on the keyboard. So, if in the default keymap 'y' invokes action 'do y' and 'x' invokes 'do x', then after remapping 'y' to 'x', 'x' will invoke the action 'do y'.

For example:

keymap:		xy

This will make the key 'x' act as pressor toggle, the key 'y'.

Note that 'y' will invoke 'do y' too, until you map another action onto it. Also note that you no longer can invoke 'do x', since there is no key that invokes that function. To make 'z' invoke 'do x', add 'zx' to your keymap. As you can see it is possible to make certain actions unreachable: if 'q' invokes fast quit and you never want to use that action (i.e. to prevent quitting out of the game by accident), you just map 'q' to some other function, and you do not map any key to 'q' (i.e. you don't have anything of the form <key>q in your keymap).

For multiple entries use the form 'xyabcd'. If you are using a .xtrekrc the form is similar but you need a command line. The command line for the basic keymap is:

keymap:		xyabcd

It is possible to remap <space>. The next keymap maps 'x' to <space>:

keymap:		 x

i.e.

keymap:       <space>x

Be careful though: if you put two spaces at the end of the keymap, <space> would be mapped upon itself, and would override the mapping of 'x':

Best is to put <space> somewhere in the middle of your keymap, for clarity. Like this for example:

keymap:		tT x

It is also possible to map <shift><key> combinations:

keymap:		xYYx

Here x will invoke <shift>y (Y) and <shift>y will invoke x, i.e. the functions have been swapped.

Ship Specific Keymaps

As well as the normal keymap, keymaps can be specified for individual ship types by using the suffix '-??' where '??' is the two letter code of the ship (sc for scout, dd for destroyer, ca for cruiser, bb for battleship, as for assault ship and sb for starbase).

e.g. For a Starbase:

keymap-sb:	xyabcd

The individual ship keymaps act in addition to the basic keymap, so that you can have both but the specific ship keymap takes precedence. Ship specific keymaps alone can be used and may reduce confusion as to where each key is defined.

Whenever you refit into a new shiptype, the keymap for that shiptype becomes active. One caveat: if you try to refit into a starbase and that fails (for example, because it has not been build yet), some clients still load the starbase-keymap. In order to get your CA-keymap back, you need to refit into a CA, in spite of the fact that you are already in a CA!

Control Keymaps

On top of these there are <ctrl> keymaps. These allow you to map <ctrl> characters. They will also deal with the normal keys. That means you can use ckeymap to map all your keys, both normal and <ctrl> keys, and omit keymap altogether. Special case: the '^' must be mapped with a double ^ ("^^") in either the bound or binding key position. (It should be noted that <space> can be mapped as a <ctrl> function but not as <shift> function). The command line for these is:

ckeymap:	^xy^a^b^C^def

Here <ctrl>x is mapped to y; <ctrl>a to <ctrl>b, <shift><ctrl>c to <ctrl>d and e to f.

<ctrl> keymaps can also be set for individual ships, e.g.:

ckeymap-sb:	^xy^a^b^C^d

All these can be used together in your .xtrekrc, with the ckeymap taking precedence over the normal keymap.

Buttonmaps

In case you thought that remapping almost any key on the keyboard to almost any other was all there was to it, there is also a buttonmap. This maps buttons on your mouse and includes a facility for <shift> and <ctrl> to activate further mouse functions. If you do not wish to use more than the 3 basic functions it may be advisable to add the following line to your .xtrekrc:

shiftedMouse:	off

because the default value for shiftedMouse is on. So you can remap the mouse buttons with a buttonmap line of the form:

buttonmap:	1*2*3*4*5*6*7*8*9*a*b*c*

Where * is the key you want to be mapped and:

button with:none<shift> <ctrl><shift>+<ctrl>
left button147a
middle button258b
right button369c

The important thing to note with buttonmaps is that keymaps take precedence. This means that if you have a buttonmap line the keys it takes as functions are the remapped ones from your keymap. I.e. don't put in a buttonmap: 1t2p3k if you have mapped t, p or k in your keymap. However the default buttonmap will operate, no matter what your keymap, as long as there is no buttonmap: line. So you should make sure that you use the mapped keys rather than the default keys when creating your buttonmap. Also see the tips section below.

Mouse as Shift

Even this is not the entirity of it. You can also use mouse buttons as a form of shift in order to get more functions from your normal keys. Each button on the mouse gives a different set of functions. You will need the following in your .xtrekrc:

mouseAsShift:	on

Then each of the buttons has it's own keymap, e.g:

	b1keymap:	xyabcd
b2keymap: xratcy
b3keymap: xuaibo

Where if 'x' is pressed with button 1 then 'y' occurs, if pressed with button 2 'r' occurs and with button 3 'u' occurs. Where 'y', 'r' and 'u' are the default keymap functions.

It is also possible to use a mixture of buttonkeymaps and the normal buttonmap. If you do not specify b3keymap, for example, the right mouse button will still have its default function, i.e. set course.

Macro's and RCD's

This section deals with the binding of macro's and RCD's (Receiver Configurable Distresses) to keys. For more details on how to use and write macro's and RCD's please consult other sources.

Macro's can be sent by hitting the enter macro mode key (defaults to 'X') followed by a key that determines the macro. Macro's are specified as follows:

mac.<key>[.<destination>]: <macro code>
	

So hitting <enter macro mode> followed by <key> will cause the macro to be sent to <destination>. If you do not specify a destination, your client will ask you to provide one after hitting enter macro mode<key>.

Distresses are specified like this:

dist.<key>.<distress name>: <distress code>
	

RCD's can be sent as shown in Appendix B, just press the key(s) while holding your mouse pointer in either the tactical or the galactic display.

If you want a key to send a macro directly, without the need of entering macro mode, use:

singleMacro:	abC

This will cause the macro's or RCD's bound to a, b and C to be sent as soon as you hit a, b or C. Note that the default RCD's can all be sent both with and without the enter macro mode.

Concluding As we have seen we can map up to 7 actions (e.g: a, A, ^a, ^A, button1-a, button2-a, button3-a) to one key using keymap, ckeymap and mouseAsShift. Using a buttonmap we can map up to 4 actions to one mouse button, in combination with <shift>, <ctrl> and <shift>+<ctrl> (e.g: button1, <shift>button1, <ctrl>button1 and <shift><ctrl>button1).

So we really have plenty of choice where to map our actions to.

Designing your Keymap Having seen how a keymap works, you now have to try and produce one that suits your needs. This is harder than it appears and it might take several hours to achieve a good result, but it will be time well spent. To design and implement your keymap, you will need to take the following steps:
  1. determine any restrictions you may have to take into account;
  2. determine your requirements, i.e. what do you want?;
  3. design the mapping of actions to keys;
  4. implement the new keymap.
You might also take a look at these hints and suggestions.

Restrictions

Take note of any restrictions that will be posed upon your keymap. Restrictions may be:

  • Physical: most people find it hard to move all fingers independently from eachother. For example, put all fingers of your left hand on the table and try to raise only your ringfinger. Most people find the ringfinger more difficult to raise then their index finger. So you have to take that into account when designing your keymap. Of course if you have any disabilities you need to take those into account as well;
  • Mental: how many <shift><ctrl> combinations can you remember? If you have mapped 7 actions mapped to one key using <shift>, <ctrl> and mouseAsShift can you still invoke the right action during stress situations?
    How well are you accustomed to your keyboard: can you type without looking at the keyboard? If you move your hand to press some keys, can you move your hand back to its original (home) position without looking at the keyboard?
  • Environmental: when you play in a shared office or a computer lab, your roommates might find it annoying when you click your mouse a lot. If this is the case, you might want to map some less used actions to your mouse;
    Other issues concern your hardware, e.g. how many buttons does your mouse have?
From the previous observations and from common sense we can conclude some general design rules:
  • keeping your hand in one position may decrease the chance of putting your hand in a wrong position greatly, i.e. having a home position is recommendable;
  • some fingers are more flexible than others, so some fingers are more suitable than other fingers for time critical actions. For example, the thumb of the left hand can press space rather precise, so we would prefer a time critical action mapped to space;
  • KISS! (Keep It Simple, Stupid!). Why make a complicated keymap when a simple one is suitable enough? Why make a different keymap for each ship type when one keymap with minor adjustments would be enough?

Determine requirements

After we have determined the restrictions, we now move on to our demands: what do we want? As we have seen in the previous section there are some design rules that apply to all keymaps. So we will assume that you have one hand operating the mouse and one hand operating the keyboard. The keyboard hand will have a home position. Obviously, the fingers of the keyboard hand also have a home position.

First, we will try to make a list of requirements our new keymap will have to fulfill as well as possible. It is your task to decide what aspects you find important and assign priorities to the different requirements. Make a note of all the functions that you use and decide on their relative importance to you. However, there are some general principles which could be useful.

  • Don't overwork your fingers - when one finger is responsible for multiple actions, those actions should be exclusive, i.e. there should never be the need to invoke both actions at the same time. For example: cloak and uncloak are exclusive as are cloak and turn on tractor beam. Fire phaser and fire photon torpedo are, obviously, not exclusive;
  • Decide where you will have your home hand position. If you touch type well then a s d f is probably a good position. However, s d f g or even d f g h gives you a greater number of readily accessible keys. On the other hand, if you want to use shift and control combinations, then putting the home position on the left side of the keyboard seems advisable.
  • Decide what actions are most time dependent, e.g. det enemy torpedoes and fire phaser. These actions should be mapped to a single key press, preferably on your home row or mouse.
  • Decide which other functions you want nearby and whether they are important enough to take up one of the easy to reach keys. This will depend on playing style as much as anything else.
  • Use as few toggles as possible - this has as its disadvantage that you need more keys, but it has great advantages when playing with packet loss.
  • Use key combinations (e.g. <shift><ctrl>t for turn on tractor beam) as little as possible. Though possibly a <shift> function as the opposite to a key's normal function could work for some people. (e.g. s turn shields on and <shift>s turn shields off)
  • When using key combinations, use as few keys for a combination as possible. For example, use <shift>y instead of <shift><ctrl>y for turn on pressor beam.
  • All key combinations should be easily accessable with one hand, i.e. no <shift><ctrl>p for fire plasma torpedo.
  • Suggested important keys: A 't' by the function is where it is time critical as well.
    low speed (t)
    high speed (t)
    speed = maximum (t)
    set course (t)
    turn on pressor beam (t)
    turn on tractor beam
    turn off tractor/pressor
    raise shields (t)
    lower shields
    fire phaser (t)
    fire photon torpedo (t)
    det enemy torps (t)
    det own torps
    beam down armies (t)
    beam up armies
    bomb armies (t)
    lock on planet (t)
    show info
    cloak
    uncloak (t)
    For Starbases also:
    fire plasma torpedo (t)
    send distress signal

Mapping

Now that you have made up a list of requirements, it is time to design a keymap that will fulfill those requirements, and that will not violate the restrictions. One thing that is making the design of a keymap particularly difficult is the fact that there are so many keys, all asking for an easy to reach and easy to remember place! One way to deal with this problem is using a divide and conquer strategy. There are two ways to use the divide and conquer strategy, the first being to divide all actions into different sets of actions depending on their type (e.g. combat actions, manouvering actions, communication, keys to bring up pop-up windows, etc.) and the second being sets that depend on the different modes of playing state we can identify, for example carrying or not, (scout-)bombing or not, basing or not, cloaking or not, etc.

Group actions by purpose

First we divide all actions in groups using the purpose of the action as criterium. For example, we can group the actions in categories for manouvering, for combat, for communication, for pop-ups, etc. One possible grouping is given in appendix A.

We then can decide to use a certain group (or type of) keys to map the actions from a specific group. For example, we could decide to use <ctrl> combinations for macro's and distress signals and use <shift><ctrl> combinations for multiline macro's.

Group actions by mode

To discover different modes, look at your playing style. Different modes could be: carrying or not carrying, scout-bombing or not scout-bombing, basing or not basing, cloaked or not cloaked, etc. One way to implement different modes is the use of <shift>, <ctrl>, and mouseAsShift. This does imply that you have <shift> and <ctrl> under your fingers, i.e. the home position of your left hand will be quite far on the left side of your keyboard. And that limits the number of keys you can operate with your left hand. One way to circumvent this is to use <Caps Lock>. For example: When you want to use one set of actions when being cloaked and another set when not cloaked, you can use <Caps Lock> to toggle between the two modes. Of course this implies that the one set consists of all lower case keys and the other set of all upper case keys. Another possible way is to have two different home positions for your hand depending on what you are doing. For Example: a s d f when uncloaked and j k l ; when cloaked.

Implementation

  • Implement: Follow the methodology in How to specify a Keymap lli>Test: Practice using the keymap. Play for a couple of hours just dogfighting; it is probably best to start off fighting robots. At this point you may find that it is difficult to reach certain keys when necessary - this can happen through actions being needed at the same time requiring movement of all fingers at once. If so, adjust until you are satisfied and test again. Once you are vaguely comfortable with dogfighting start playing normally. Again see if there are any difficult to reach keys which are necessary for your normal style of play. If so adjust, if not practice with it. It will take about ten hours to become comfortable with the keymap depending on how complicated it is. At this point you may find that there are one or two keys which you are still unhappy with. You can then either adjust again and slowly improve the keymap, or you can decide to stick with it and learn to get round the minor difficulties.

Hints and Suggestions

  • If you are going to have a buttonmap, decide what you wish on the mouse first. Then the first part of your keymap should be mapping these functions well out of the way on the keyboard. This means that alterations to your keymap do not mean that you have to alter your buttonmap. It also means that you don't have to worry about mapping over these functions in your normal keymap. e.g. For a mouse with fire photon torpedoes, fire phasers and turn mapped to it, the start of the keymap could look like this:
    keymap:		[t]p\k
    This means that a buttonmap of the form:
    buttonmap:		1[2]3\
    would rarely need altering.
  • When mapping <space> put the <space> in the middle of your keymap not at either end. This avoids confusion.
  • Make your home row the most useful in panic situations - we nearly all get a little stressed out at times. This will mean that you can just hammer the keyboard frantically without moving your fingers and something vaguely useful might occur. e.g. pressor on, maxwarp, detonate enemy torpedoes, shields up.
  • If you have never thought about it before, then firing off the keyboard should be strongly considered when creating your keymap. This is useful especially in conjunction with a cohesive idea for the mouse. For example a mouse for manoeuvering which has high warp, low warp and turn mapped onto it. Some of the strongest players use this idea.
  • When mapping speeds you only need a few. Three speeds and maxwarp are more than enough. You can probably get away with just using maxwarp and a low warp. By continually flicking between them you can achieve any speed inbetween. This is especially useful when using the mouse for speeds.
  • A possible way to save a key when mapping tractors and pressors, is to map a pressor on key and a tractor toggle key.
  • When you remap the less used functions try to map them to a memorable key e.g. 'W' brings up the war window, and 'H' the help window.
  • If you have different keymaps for different ships, try to keep them the same as much as possible;
  • Consider mapping something to 'q' (which is fast quit by default) to prevent quitting out of the game by accident.
  • When testing your new keymap on some empty server you might want to make some minor changes. Just open another window to edit your .xtrekrc, make the changes and save them, and then use & to let the client reread your .xtrekrc.

APPENDIX A: The Default Keymap

The following list contains the default keymap from the COW-client. It has been partitioned for easy reference.

ManoeuveringCombatPopups
0-9 Set SpeedspFire Phaseri Info on Player/Planet
) Set Speed=10tFire Photon Torpedoh Help Screen
! Set Speed=11fFire Plasma TorpedoI Extended Info on Player
@ Set Speed=12dDetonate Enemy Torpedosw War Declarations Window
# Set Speed=1/2 MaximumDDetonate Enemy Torpedos+ Show UDP Options Window
% Set Speed=Maximum]Put Up ShieldsO Options Window
< Decrease Speed 1[Put Down shieldsP List Planets
> Increase Speed 1sShield ToggleX? Show all Macros
k Set CourseuShield Toggle
 
(<space>) Unmap Popups
o Orbit Planet or Dock on StarbaseTTractor Beam ToggleS Status Bars
; Lock On To Planet or StarbaseyPressor Beam Toggle, Ping Statistics
l Lock On To Player/Planet_Turn On Tractor BeamU Rank Window
* Transwarp (only on some servers)^Turn On Pressor Beam. Netstat Window
Communication$Turn Off Tractor/Pressor Beam~ Sound Window
E Send Distress SignalOther Ship Controls` Network Window
F Send Armies Carried ReportbBomb PlanetM Tools Window
? Cycle Message WindowszBeam Up Armies Miscellaneous
m Message Window ZoomxBeam Down ArmiesL List Players
: Toggle Message Logging{Cloaking Device OnQ Quit
X Enter Macro Mode}Cloaking Device Offq Fast Quit
Network ConnectioncCloaking Device ToggleC Coup Home Planet
= Request Full UpdateREnter Repair Mode* Send in Practice Robot (when noone else playing)
| Request Intermediate UpdateeDocking Permission ToggleN Toggle Short/Long Planet Names Display On Tactical Window
- Request Partial UpdaterRefit (change ship)& Reread .xtrekrc
BCycle Galctic Map Planet Display
VCycle Tactical Map Planet Display

APPENDIX B: RCD's

These are the default RCD's (Receiver Configurable Distresses) from the COW client.

keynamedefault distress macro
^eescorting%T%c->%O ESCORTING %g (%d%%D %s%%S %f%%F)
^t, ^Ttaking%T%c->%O (%S) Carrying %a to %l%?%n>-1%{ @ %n%}
^oogg%T%c->%O Help Ogg %p at %l
^O, ^pogging%T%c->%O Ogging %h
^ffree_beer%T%c->%O %p is free beer
^hcrippled%T%c->%O %h @ %l is crippled
^cspace_control%T%c->%O Help Control at %l
^C, ^lcontrolling%T%c->%O Controlling at %l
^bbomb%T%c->%O %?%n>4%{bomb %l @ %n%!bomb%}
^B, ^mbombing%T%c->%O Bombing %l @ %n
^nno_gas%T%c->%O %p @ %l has no gas
^1save_planet%T%c->%O Help at %l!%?%a> 0%{ (have %a arm%?%a=1%{y%!ies%}%}) %s%% shld, %d%% dam, %f%% fuel
^2base_ogg%T%c->%O Sync with --]> %g <[-- OGG ogg OGG base!!
^3help1%T%c->%O Help me! %d%% dam, %s%% shd, %f%% fuel %a armies.
^4help2%T%c->%O Help me! %d%% dam, %s%% shd, %f%% fuel %a armies.
^5asw%T%c->%O Anti-bombing %p near %b.
^6asbomb%T%c->%O DON'T BOMB %l. Let me bomb it (%S)
^7doing1%T%c->%O (%i)%?%a>0%{ has %a arm%?%a=1%{y%!ies%}%} at %l. %d%% dam, %s%% shd, %f%% fuel
^8doing2%T%c->%O (%i)%?%a>0%{ has %a arm%?%a=1%{y%!ies%}%} at %l. %d%% dam, %s%% shd, %f%% fuel
^9pickup%T%c->%O %p++ @ %l
^0pop%T%c->%O %l%?%n>-1%{ @ %n%}!
^@other1%T%c->%O (%i)%?%a>0%{ has %a arm%?%a=1%{y%!ies%} at %l. (%d%%D, %s%%S, %f%%F)
^#other2%T%c->%O (%i)%?%a>0%{ has %a arm%?%a=1%{y%!ies%} at %l. (%d%%D, %s%%S, %f%%F)
Ehelp%T%c->%O Help(%S)! %s%% shd, %d%% dmg, %f%% fuel,%?%S=SB%{ %w%% wtmp,%}%?%E{ ETEMP!%}%?%W{ WTEMP!%} %a armies!
Fcarrying%T%c->%O %?%S=SB%{Your Starbase is c%!C%}arrying %?%a>0%{%a%!NO%} arm%?%a=1%{y%!ies%}.