Key Scripter
AboutInstallationSetupUsageCreating scriptsDownloads

Creating scripts

Many games support key scripting functionality, notably fist-person shooters. However, typically only key press events are supported while key release events are ignored. Key Scripter removes this limitation by providing support for both key event types.

When no configuration file is specified, Key Scripter simply sends a copy of each received key event to the target display or, when no display is specified, prints a command representing the event to the standard output. With a configuration however, Key Scripter checks whether an action is bound to the received key event. When a bound action is found, it is executed, otherwise the event is ignored. A configuration file can be specified using the -c command-line option (see Usage for a list of available command-line options).

Note that when Key Scripter is reading from a device, it does not consume events produced by the device. They are still processed by the system, as is the case when Key Scripter is not running. Any fake key events generated by Key Scripter will be processed by the system in addition to the real key events.

A configuration may contain bind commands, named action declarations, comments and include statements. A semicolon may be used to separate commands for better readability. A single-line comment is text starting with a '#' character or double slash '//', while a multi-line comment is a section of text starting with '/*' and ending with '*/' characters.

A bind command is specified by the word 'bind' followed by either a key event or a mouse event specification, and ends with a specification of an action. A key event starts with either a 'p' or an 'r' character, depending on whether it represents a press or a release event respectively, and ends with the scan code of the key. Similarly, a mouse event starts with either 'mp' or 'mr' characters, representing a press or a release event respectively, and ends with the button number. Mouse button numbers start with 1, with 2 being the right mouse button and 3 the middle. Mouse wheel events are specified with either mwf or mwb, representing a forward or a backward rotation event respectively. The following example instructs Key Scripter to press the 'p' key for 1 second when the 'q' key is released:

bind p24 { /* ignored */ }
bind r24 { p33; s1000; r33 } // press 'p' for 1 second when 'q' is released

Bind commands also support a wildcard notation, such as bind p* or bind r*. Such binds will catch events not currently bound to an action.

An action may either contain a single command, contain multiple commands to be executed one after another, or be empty. An empty action or an action containing multiple commands must be surrounded by curly brackets. The brackets may be omitted for an action with a single command, such as shown in the following example:

bind p24 p33 // press 'p' when 'q' is pressed
bind r24 r33 // release 'p' when 'q' is released

Named actions are declared with the set command. A set command is specified by the word 'set' followed by the name of a new or an existing action and ends with a specification of an action. The name of an action may contain the following characters: a-z, A-Z, 0-9, _, -, +. A named action can be executed from within another action by specifying its name with a '$' character prepended to it:

bind r24 $press_p // execute the 'press_p' action when 'q' is released
set press_p { p33; s1000; r33; $something_else } // press 'p' for 1 second and then execute the 'something_else' action
set something_else { /* does nothing */ } // executed by the 'press_p' action

Actions may span multiple lines and include an arbitrary number of spaces:

set example_action
{
p24 // press 'q'
s50 // wait for 50 milliseconds
r24 // release 'q'

set example_action // modifies itself
{
p33 // press 'p'
s50 // wait for 50 milliseconds
r33 // release 'p'
}
}

Both the set and the bind commands can be used to dynamically declare an action or bind an action to a key during execution of Key Scripter. This allows creation of complicated scripts that can modify current key bindings or action declarations while processing received events.

When a set command is followed by the word 'true' or 'false' instead of an action, it sets a boolean variable with the specified name to either a true or a false value:

bind p37 { set left_ctrl_is_pressed true }
bind r37 { set left_ctrl_is_pressed false }
bind p50 { set left_shift_is_pressed true }
bind r50 { set left_shift_is_pressed false }

Such boolean variables may then be used in an if command:

bind p33 { if left_ctrl_is_pressed and left_shift_is_pressed { /* do something on ctrl+shift+p */ } }

The initial value of a boolean variable is false. Boolean variables may be chained together with an 'and' or an 'or' word to create a condition containing multiple variables. If a boolean variable is preceded by an '!' character, its value is inverted. An if statement may optionally be followed by an else statement.

The set {name} {true|false} command also support the following notation: set {name} {true|false}/{milliseconds}. When this notation is used, the value of the boolean variable will be automatically inverted after the specified number of milliseconds. This notation is useful for detecting keystrokes pressed one after another:

bind r37 set ctrl_released_within_last_second true/1000 // when 'ctrl' is released, set the flag to true for one second
bind p38 if ctrl_released_within_last_second $process-ctrl-a // when 'a' is pressed after ctrl, execute the specified action

More command types are supported when specified within an action. The following is a list of all supported commands:A t{scancode} command is handled exactly as the following three commands one after another: p{scancode}, s1, r{scancode}. An mc{number} command is handled exactly as the following three commands one after another: mp{number}, s1, mr{number}. Key and mouse event commands also support the following notation: p{scancode}/{milliseconds}, which is handled exactly as the following two commands one after another: s{milliseconds}, p{scancode}.

If a configuration file becomes too long, it may be better to split it into several smaller files. These smaller files can then be combined into a single configuration by specifying all or some of them in a master configuration file using include statements. Creating a special configuration per application becomes easier this way, because such a configuration doesn't need to contain a full copy of each script, it can simply point to the file the script is defined in.

An include statement is specified by the word 'include' followed by the name of the configuration file surrounded by double quotes. If the file name contains a relative path or doesn't specify any path at all, it is considered relative to the parent configuration file. The following is an example of an include statement:

include "file name"

When loading a configuration file, Key Scripter stops if a syntax error is encountered. The line and column number of the invalid content is printed to the standard error output. However, even when loaded successfully, a complex configuration file may still contain errors that are only visible during execution of Key Scripter. In order to simplify searching for such hard-to-find errors, Key Scripter provides the -d command-line option (see Usage for a list of available command-line options). When this option is enabled, Key Scripter prints debug messages to the standard error output, describing each executed command and informing when each executed named action begins or ends.