On this page 11 sections
Come here when your mod reacts to keys or the mouse: a hotkey that opens your menu, a new action on a key the player already uses, a key the game should ignore while your panel is open, or a script that presses a key for the player.
A first example: F7 shows a message while playing.
import blse
def on_key(topic, data):
key, where = data.split('\0')
if key == 'F7' and where == 'game':
blse.show_text('Hotkey!')
blse.subscribe('blse.key_down', on_key)Read this first
- Prefer the player's own bindings to fixed keys. Players rebind keys; react to
blse.control_down('+jump','+use') or look keys up withkeys_forinstead of assumingSPACEorE. - Check
where: key events come in play, in menus, in the console and while typing into a field. Usually you only want'game'. - Blocked keys stay blocked until you unblock them (or Python starts again): unblock when your panel closes.
- Key events are delivered immediately, not at the next frame.
- On a game version BLSE does not recognize, these functions raise
RuntimeError.
Words used on this page#
- Key name: a key or mouse button as the console's
bindcommand names it:'a','5','F5','SPACE','MOUSE1'(left button),'MWHEELUP'. Any case is accepted. An unknown name raisesValueError. - Binding, command: what a key does in the game: the console command bound to it (
bind SPACE +jump). Commands starting with+run while the key is held ('+attack'), others once ('slot1'). where: where the key went:'game'(playing),'cursor'(a mouse button in cursor mode),'text'(typing into a focused HUD text field),'console'(the console is open) or'menu'(a game screen or the Esc menu is open, or no level runs).- Blocking: BLSE keeps a key press from reaching the game; your mod still hears it.
- Simulating: BLSE presses a key as if the player did, so its binding runs.
- Payload: the text an event hands to your handler: fields separated by NUL characters (character 0), read with
data.split('\0').
Keys and mouse buttons#
Since b0.5.24 (recognized builds): every key and mouse button that reaches the game, named as in the console's bind command: 'a', '5', 'F5', 'SPACE', 'ENTER', 'SHIFT', 'CTRL', 'ALT', 'TAB', 'UPARROW', 'MOUSE1'..'MOUSE5', 'MWHEELUP', 'MWHEELDOWN', 'KP_ENTER', 'KP_HOME', ... (letters in lower case; any case is accepted). Keys without a name are reported as 'KEY<number>' and accepted in that form. Laptop Fn keys for Home, End, PgUp and so on usually arrive as the numpad names (KP_HOME, KP_END, KP_PGUP).
| Function / topic | |
|---|---|
blse.key_down, blse.key_up |
key, where = data.split('\0'). where: 'game' (playing), 'cursor' (a mouse button in cursor mode), 'text' (typing into a focused HUD input, b0.5.25), 'console' (typing in the console) or 'menu' (a game screen or the Esc menu is open, or no level runs). Auto-repeat is not reported. Keys pressed in the Esc menu are reported since b0.5.25. Delivered immediately |
blse.control_down, blse.control_up |
command, key = data.split('\0'): a key press in play ran its binding ('+jump', '+attack', '+use', 'slot1', ...), whichever key the player bound to it; control_up when that key is released (b0.5.26). Not sent for blocked keys, typing, the console or menus. Prefer this to fixed keys for reacting to game actions |
blse.is_control_down(command) |
1 while a key whose press ran command is held (b0.5.26). A key already held when play resumes (pressed during a loading screen, a menu or the console) counts from its first repeat in play (0.6) |
blse.is_key_down(key) |
1 if the key is held, else 0 |
blse.key_binding(key) |
The command bound to it ('' if none), e.g. key_binding('F5') → 'slot4' |
blse.keys_for(command) |
The keys bound to command, e.g. keys_for('+jump') → ['SPACE']. Use it instead of hard-coding keys the player may have changed |
blse.block_key(key[, blocked]) |
While blocked (by any mod), pressing the key during play does not reach the game; blse.key_down is still sent, so the mod can give the key its own meaning. blocked=0 unblocks. Not applied in the console or menus |
blse.clear_blocked_keys() |
Unblocks every key blocked from Python |
blse.press_key(key[, mode]) |
Simulates the key: 'tap' (default: pressed now, released after the next game frame), 'down' (pressed until 'up'; released for you if the mod is disabled or the scripts run again after an engine restart), 'up'. Its binding runs as for a real press. Simulated keys are not reported as key_down/key_up and are never blocked. While the console or a menu pauses the game there are no game frames: a tap is released when play goes on |
blse.key_simulated (event) |
(b0.5.34) key, what, mod = data.split('\0'): a mod's press_key; what is 'down' or 'up', mod is 'python' or the plugin's name |
blse.mouse_move (event) |
(b0.5.34) dx, dy, x, y, where = data.split('\0'): the mouse moved, at most once per rendered frame, while the game window is in front. dx, dy: pixels since the last event (right and down are positive; while the game looks around with the mouse it puts the cursor back in the middle every frame, which is not counted). x, y: the cursor in the window (0..1; in play it sits in the middle). where: 'game', 'menu', 'console' or 'cursor'. Many events: keep the handler short |
Unknown key names raise ValueError; on unrecognized builds these functions raise RuntimeError.
import blse
def on_key(topic, data):
key, where = data.split('\0')
if where == 'game' and key == 'F7':
blse.show_text('Hotkey!')
blse.subscribe('blse.key_down', on_key)blse.key_down and blse.key_up#
(b0.5.24) Fire when a key or mouse button is pressed (key_down) or released (key_up). Auto-repeat (a held key typing again and again) is not reported. Keys pressed in the Esc menu are reported since b0.5.25. Keys a mod simulates with press_key are not reported here (see blse.key_simulated).
Payload, in order: key (the key name), where (see Words used on this page).
def on_up(topic, data):
key, where = data.split('\0')
if key == 'MOUSE2' and where == 'game':
blse.log('right button released')
blse.subscribe('blse.key_up', on_up)blse.control_down and blse.control_up#
(b0.5.26) Fire when a key press in play runs its binding (control_down), and when that key is released (control_up), whichever key the player bound to it. Not sent for blocked keys, typing, the console or menus. Use them to react to game actions (jumping, attacking, using) without caring about the keys.
Payload, in order: command (the binding, '+jump'), key (the key that ran it).
def on_control(topic, data):
command, key = data.split('\0')
if command == '+jump':
blse.log('jump with ' + key)
blse.subscribe('blse.control_down', on_control)blse.is_control_down#
blse.is_control_down(command) # -> 1 or 0(b0.5.26) 1 while a key whose press ran command ('+duck', '+speed') is held, else 0. Use it for "while the player holds sprint" checks. A key already held when play resumes (pressed during a loading screen, a menu or the console) counts from its first repeat in play (about 0.6 seconds later).
if blse.is_control_down('+duck'):
blse.log('crouching')blse.is_key_down#
blse.is_key_down(key) # -> 1 or 01 while the key is held, else 0. Raises ValueError for an unknown key name.
if blse.is_key_down('SHIFT') and blse.is_key_down('F7'):
blse.log('Shift+F7')blse.key_binding and blse.keys_for#
blse.key_binding(key) # -> str
blse.keys_for(command) # -> [key, ...]key_binding gives the command bound to a key ('' if none): key_binding('F5') is 'slot4'. keys_for gives the keys bound to a command: keys_for('+jump') is ['SPACE'] ([] if none). Use keys_for to show the player's own key in a hint.
keys = blse.keys_for('+use')
if keys:
blse.show_text('Press %s to open' % keys[0])blse.block_key and blse.clear_blocked_keys#
blse.block_key(key[, blocked]) # -> 1
blse.clear_blocked_keys() # -> Noneblock_key keeps a key from reaching the game during play (blocked 1, the default) or lets it through again (0); blse.key_down is still sent, so your mod can give the key its own meaning. Not applied in the console or menus. A key stays blocked while any mod blocks it. clear_blocked_keys unblocks every key Python blocked. block_key raises ValueError for an unknown key name.
blse.block_key('ESCAPE') # while your panel is open
blse.block_key('ESCAPE', 0) # when it closesblse.press_key#
blse.press_key(key[, mode]) # -> 1Presses a key for the player: its binding runs as for a real press.
key(str): a key name.mode(str, optional, lower case):'tap'(default: pressed now, released after the next game frame),'down'(held until you send'up'),'up'. Another word raisesValueError.- Returns
1. RaisesRuntimeErrorif the key could not be pressed.
A key held with 'down' is released for you if the mod is disabled or the scripts run again after an engine restart. Simulated keys are not reported as key_down/key_up and are never blocked. While the console or a menu pauses the game there are no game frames: a tap is released when play goes on.
blse.press_key('SPACE') # jump once (if SPACE is bound to +jump)blse.key_simulated#
(b0.5.34) Fires when a mod presses or releases a key with press_key. Payload, in order: key, what ('down' or 'up'), mod ('python' or the plugin's name).
def on_sim(topic, data):
key, what, mod = data.split('\0')
blse.log('%s pressed %s (%s)' % (mod, key, what))
blse.subscribe('blse.key_simulated', on_sim)blse.mouse_move#
(b0.5.34) Fires when the mouse moved, at most once per drawn frame, while the game window is in front. Many events: keep the handler short, and listen only while needed.
Payload, in order:
dx,dy: whole pixels moved since the last event, as text (right and down are positive). While the game looks around with the mouse it puts the cursor back in the middle every frame; that jump is not counted.x,y: the cursor's place in the window, 0 to 1, as text with 4 decimals (in play it sits in the middle).where:'game','menu','console'or'cursor'.
def on_move(topic, data):
dx, dy, x, y, where = data.split('\0')
if where == 'cursor':
blse.hud_set('mymod_pos', '%s, %s' % (x, y), 0.02, 0.02)
blse.subscribe('blse.mouse_move', on_move)