BLSE0.6

Python mods

Screens and windows

On this page 8 sections

The game's menus and screens: reading and restyling them, adding to them, mods' own windows, button sounds and blocked screens. Text and elements drawn over the game are in the HUD overlay.

Come here when your mod changes one of the game's screens (renames a button, adds a line to the character sheet, recolours the Esc menu), opens a window of its own with buttons, text fields, checkboxes and lists, gives buttons sounds, or replaces a game screen (its own inventory instead of the game's).

A first example: a console command that opens a small window with a button; clicking the button closes it.

Python
import blse

def open_hello(name, args):
    blse.window_create('mymod_hello', 'Hello', 200, 150, 300, 160)
    blse.menu_add_label('mymod_hello', '', 'text', 'Good evening, Kindred.', 20, 40, 260, 30)
    blse.menu_add_button('mymod_hello', '', 'close', 'Close', 100, 100, 100, 30)

def on_button(topic, data):
    screen, path = data.split('\0')
    if screen == 'mymod_hello' and path == 'close':
        blse.window_remove('mymod_hello')

blse.subscribe('blse.menu_button', on_button)
blse.add_command('hello', open_hello, 'hello: opens a small window')

Read this first

  • A screen must be open to read or change it: most menu_ functions return 0 (or None) when the screen named is not open. Change a game screen from a blse.menu_opened handler.
  • Your windows count as screens: a window's name works as screen in every menu_ function, and '' as path is the window itself.
  • Changes do not last. The game may rebuild a screen each time it opens or when the player does something in it; labels and buttons you add live as long as the screen (or window) does. Python's windows, added panels, styles and button sound rules are removed when Python starts again with the engine: your script makes them again.
  • Nothing is saved.
  • Find panel names with menu_panels: log it once and look up the path of the panel you want.
  • These functions need a game version BLSE recognizes (they return 0 / None otherwise).

Words used on this page#

  • Screen: one of the game's menus or panels with a name BLSE gives it ('game_menu', 'inventory', 'character', see the table below), or a mod's window by its name.
  • Panel: one rectangle of a screen: a label, a button, an image, a text field, or a container of other panels. Screens are trees of panels (Valve's VGUI system).
  • Path: names a panel inside a screen: the names from the screen down, joined by / ('StatsPanel/HumanityLabel'). '' is the screen itself. A panel without a name is named by its position, #0, #1, ... Case does not matter.
  • Parent path: the panel a new panel is put into ('' for the screen itself). Positions of new panels are relative to it.
  • Pixels: positions and sizes on this page are in screen pixels, from the parent's top left corner (unlike the HUD overlay, which uses fractions).
  • Kind: what a panel is: 'label', 'button', 'text_entry' (a text field), 'image', 'panel' (another VGUI panel) or ''.
  • Command: a word a button sends to its screen when clicked ('Close').
  • Owner: who added a panel or window (Python or a plugin). You can only remove or change the style of what your side added, unless stated.
  • Pattern: a text with wildcards: * any characters, ? one character.
  • Payload: the text an event hands to your handler: fields separated by NUL characters (character 0), read with data.split('\0').

On builds with the analyzed vgui2.dll (b0.5.17):

Topic data
blse.menu_opened cls, name = data.split('\0'): a game screen opened
blse.menu_closed Same fields: it closed (only after it was reported open; tabs close with their screen)
name Screen (cls)
game_menu The Esc menu (CVMainMenu)
inventory Inventory, also used for trading (VBarterUI)
character Character screen, the C key (CharEditPanel)
journal The journal tab of the character screen (QuestLogPanel)
load_game, save_game, options, new_game, help The game menu's dialogs
map, hotkeys, character_creation, dialog, console, loading Other screens

Delivered immediately (menus run outside game logic).

blse.menu_opened and blse.menu_closed#

(b0.5.17) blse.menu_opened fires when a game screen opens, blse.menu_closed when it closes (only after it was reported open; tabs close with their screen). Use menu_opened to change a screen each time it appears.

Payload, in order: cls (the panel's class, 'CVMainMenu'), name (BLSE's name for the screen, 'game_menu'; see the table above).

Python
def on_open(topic, data):
    cls, name = data.split('\0')
    if name == 'character':
        blse.log('character screen opened')
blse.subscribe('blse.menu_opened', on_open)

What a screen shows#

Every game screen is a tree of panels (VGUI). Mods can read it, change texts, images, visibility and positions, press its buttons, give it commands and add their own labels while the screen is open:

Function
blse.open_menus() The open screens' names, e.g. ['inventory']
blse.menu_panels(screen) [(path, class, visible, x, y, w, h, text, kind, image, command), ...]: the screen (path '') and every panel in it, in pixels. text: the text of a label, button or text field, else None. kind: 'label', 'button', 'text_entry', 'image', 'panel' (another VGUI panel) or ''. image: an image panel's image, else None. command: the command a button sends (b0.5.32; 'ActionClicked', 'Close', ...), else None. None if the screen is not open
blse.menu_set_text(screen, path, text) Changes the text of a label, button or text field (b0.5.31); 1 or 0
blse.menu_set_visible(screen, path, visible) Shows (1) or hides (0) a panel; 1 or 0
blse.menu_move(screen, path, x, y[, w, h]) Moves a panel (and resizes it); 1 or 0
blse.menu_press(screen, path) Presses a button as a mouse click does: it does whatever the button does (b0.5.31); 1 or 0
blse.menu_command(screen, path, command) Gives a panel a command, the way its buttons do (Panel::OnCommand). Source's standard dialogs take 'Close' (Options, Load, Save, ...); Bloodlines' own screens (Esc menu, inventory, character) do not use commands: press their buttons instead (b0.5.31); 1 or 0
blse.menu_set_image(screen, path, image) Shows another image in an image panel (kind == 'image'): a name below materials/vgui/, as in the game's .res files (b0.5.31). The game's own image names look like 'hud/signs/ventrue'
blse.menu_add_label(screen, parent_path, name, text, x, y, w, h) Adds a label below the panel at parent_path ('': the screen), or updates the one added before with that name (b0.5.31); 1 or 0. It stays as long as the screen does; labels from Python go when Python restarts
blse.menu_add_button(screen, parent_path, name, text, x, y, w, h) Adds a button (b0.5.32): clicking it sends blse.menu_button. Updates the one added before with that name
blse.menu_add_image(screen, parent_path, name, image, x, y, w, h) Adds an image panel showing image (b0.5.32); change it with menu_set_image
blse.menu_add_text_entry(screen, parent_path, name, text, x, y, w, h[, multiline]) Adds a text field of the game's own kind (b0.5.36); multiline=1: several lines, Enter starts a new one. Read its text with menu_panels (kind text_entry), change it with menu_set_text. text is real text the player has to delete; for a faint hint use menu_set_hint (b0.5.37)
blse.menu_remove(screen, path) Removes a label, button, image or text field this mod added (b0.5.31)
blse.menu_button (event) screen, path = data.split('\0'): a button this or another mod added was clicked (b0.5.32). Delivered at the next painted frame, outside the game's click handling, so a handler may remove the button or its window. In Bloodlines' Esc menu, which keeps the mouse to its own buttons, an added button does not light up, but its clicks are reported all the same

A path names a panel by the panel names from the screen down, joined by / ('ActionButton', 'StatsPanel/HumanityLabel'); any panel can also be named by its position, #0, #1, ... (for unnamed panels). Case does not matter. Log menu_panels once to find the names.

The game may refill a screen when it opens or updates it (selecting an item, switching tabs): change it again from blse.menu_opened or after the player's action. A label keeps its size when its text changes, so longer text is cut off unless the label is also made wider with menu_move.

Python
def on_open(topic, data):
    cls, name = data.split('\0')
    if name == 'game_menu':
        blse.menu_set_text('game_menu', 'BTN_OPTIONS', 'Settings')
blse.subscribe('blse.menu_opened', on_open)

blse.open_menus#

Python
blse.open_menus()   # -> [name, ...]

The names of the screens open now (['game_menu'], [] in play). Use it to check whether the player is in a menu.

blse.menu_panels#

Python
blse.menu_panels(screen)   # -> [(path, class, visible, x, y, w, h, text, kind, image, command), ...] or None

Lists a screen and every panel in it (the screen first, with path ''). Use it to find the paths of the panels you want to change, and to read the text of text fields.

  • screen (str): a screen's name or a mod window's name.
  • Returns tuples of: path (str), class (str, the panel's VGUI class), visible (1 or 0), x, y, w, h (int, pixels), text (str for labels, buttons and text fields, else None), kind (see Words used on this page), image (an image panel's image, else None), command (b0.5.32; the command a button sends, else None). None if the screen is not open. Raises RuntimeError if memory runs out.
Python
for path, cls, visible, x, y, w, h, text, kind, image, command in blse.menu_panels('game_menu') or []:
    blse.log('%s %s %s' % (path, kind, text))

blse.menu_set_text, blse.menu_set_visible and blse.menu_move#

Python
blse.menu_set_text(screen, path, text)        # -> 1 or 0
blse.menu_set_visible(screen, path, visible)  # -> 1 or 0
blse.menu_move(screen, path, x, y[, w, h])    # -> 1 or 0

Change one panel of an open screen: its text (labels, buttons, text fields, b0.5.31), whether it is shown (visible 1 or 0), or its position and, with w and h, its size (pixels, relative to its parent). All return 1, or 0 if the screen is not open, the path names no panel, or the panel cannot take the change (text on an image).

Python
blse.menu_set_text('game_menu', 'BTN_OPTIONS', 'Settings')
blse.menu_set_visible('game_menu', 'BTN_QUIT', 0)
blse.menu_move('game_menu', 'BTN_OPTIONS', 40, 200, 300, 30)

blse.menu_press and blse.menu_command#

Python
blse.menu_press(screen, path)              # -> 1 or 0
blse.menu_command(screen, path, command)   # -> 1 or 0

(b0.5.31) menu_press presses a button as a mouse click does. menu_command gives a panel (usually the screen, path '') a command, the way its buttons do: Source's standard dialogs take 'Close'; Bloodlines' own screens do not use commands (press their buttons instead). Both return 1, or 0 if the screen is not open or the panel cannot take it.

Python
blse.menu_command('options', '', 'Close')

blse.menu_set_image#

Python
blse.menu_set_image(screen, path, image)   # -> 1 or 0

(b0.5.31) Shows another picture in an image panel (kind == 'image'). image is a name below materials/vgui/ as in the game's .res files ('hud/signs/ventrue'). Returns 1, or 0 if the screen is not open or the panel is not an image panel.

blse.menu_add_label, blse.menu_add_button, blse.menu_add_image and blse.menu_add_text_entry#

Python
blse.menu_add_label(screen, parent_path, name, text, x, y, w, h)                    # -> 1 or 0
blse.menu_add_button(screen, parent_path, name, text, x, y, w, h)                   # -> 1 or 0
blse.menu_add_image(screen, parent_path, name, image, x, y, w, h)                   # -> 1 or 0
blse.menu_add_text_entry(screen, parent_path, name, text, x, y, w, h[, multiline])  # -> 1 or 0

Add a panel of the game's own kind to an open screen or a window: a label (b0.5.31), a button (b0.5.32, clicks send blse.menu_button), an image (b0.5.32) or a text field (b0.5.36). Called again with the same name, they update the panel added before.

  • screen: an open screen or a window. parent_path: the panel to put it in ('': the screen).
  • name (str): your name for it; not empty, without /, not starting with #. Its path is then parent_path + '/' + name (or just name on the screen).
  • text (str): the text shown; a $ text is translated for labels and buttons (translations). For a text field it is real text the player has to delete (for a faint hint use menu_set_hint).
  • image (str): as for menu_set_image; not empty.
  • x, y, w, h (int): pixels, relative to the parent.
  • multiline (int, optional): 1 for a text field of several lines (Enter starts a new one).
  • Return 1, or 0 if the screen is not open, the parent cannot hold panels, or the name is not allowed.
Python
def on_open(topic, data):
    cls, name = data.split('\0')
    if name == 'character':
        blse.menu_add_label('character', '', 'mymod_note', 'Feeding: 3 tonight', 30, 520, 300, 24)
blse.subscribe('blse.menu_opened', on_open)

Read a text field's text with menu_panels (its text), change it with menu_set_text.

blse.menu_remove#

Python
blse.menu_remove(screen, path)   # -> 1 or 0

(b0.5.31) Removes a label, button, image, text field or control Python added. Returns 1, or 0 if Python added no such panel.

blse.menu_button#

(b0.5.32) Fires when a button a mod added is clicked (Python's or a plugin's; also rows of lists). Delivered at the next painted frame, outside the game's click handling, so a handler may remove the button or its window.

Payload, in order: screen (the screen or window), path (the button's path, '<list>/<row>' for a list row).

Python
def on_button(topic, data):
    screen, path = data.split('\0')
    if screen == 'notes' and path == 'save':
        blse.log('save pressed')
blse.subscribe('blse.menu_button', on_button)

Windows of the game's own kind#

Function / topic
blse.window_create(name, title, x, y, w, h) A window like the game's own dialogs (a vgui2 Frame: title bar, close button, moved and resized by the player), shown, at x, y with size w, h (pixels). It takes the mouse and keyboard while shown, as the inventory does. name (1-63 of A-Z a-z 0-9 _ -) works as the screen for every menu_ function: menu_add_label('mywin', '', ...), menu_add_button, menu_add_image, menu_add_text_entry, menu_panels('mywin'), ... ('' is the window itself). Called again for your window: a new title, position and size, and shown again if the player closed it (b0.5.37). Returns 1 or 0
blse.window_show(name, visible) / blse.window_remove(name) Hide or show it again; delete it with what is in it. Only your own windows
blse.windows() The mods' windows' names
blse.window_closed (event) name: the player closed it with its close button (it is hidden; window_show(name, 1) shows it again)

A Python restart removes Python's windows (scripts make them again), and a plugin's go when it is unloaded. The windows look like the game's other Valve-style dialogs and the console, from the game's scheme files; their colors and fonts can be changed (see Restyling below). A shown window has the keyboard: the console cannot be typed into until it is hidden or closed, so give it a button to close it. For a look entirely of your own, draw a panel with the HUD overlay instead (boxes, images, text and fields).

Python
def open_notes(name, args):
    blse.window_create('notes', 'Notes', 120, 100, 460, 330)
    blse.menu_add_text_entry('notes', '', 'text', '', 20, 40, 420, 220, 1)
    blse.menu_add_button('notes', '', 'save', 'Save', 20, 275, 120, 30)
blse.add_command('notes', open_notes)

A window stays until your mod hides or removes it, also over the Esc menu, the main menu and loading screens. To hide it with the game's menus, use the screen and level events:

Python
def on_menu(topic, data):
    if data.split('\0')[1] == 'game_menu':                       # the Esc menu
        blse.window_show('notes', topic == 'blse.menu_closed')   # hidden while it is open
blse.subscribe('blse.menu_opened', on_menu)
blse.subscribe('blse.menu_closed', on_menu)
blse.subscribe('blse.level_shutdown', lambda topic, data: blse.window_remove('notes'))

blse.window_create#

Python
blse.window_create(name, title, x, y, w, h)   # -> 1 or 0

Makes and shows a window like the game's own dialogs (title bar, close button, moved and resized by the player). Use it for a mod's settings, a shop, a notebook.

  • name (str): 1 to 63 characters of A-Z a-z 0-9 _ -; used as screen in every menu_ function.
  • title (str): the title bar's text (a $ text is translated).
  • x, y, w, h (int): position and size in pixels; w and h must be more than 0.
  • Returns 1, or 0 for a bad name or size, a window of that name made by another mod, or when the game's interface is not ready. Called again for your window: a new title, position and size, and shown again if the player closed it (b0.5.37).

blse.window_show, blse.window_remove and blse.windows#

Python
blse.window_show(name[, visible])   # -> 1 or 0
blse.window_remove(name)            # -> 1 or 0
blse.windows()                      # -> [name, ...]

window_show shows (visible 1, the default) or hides (0) one of Python's windows. window_remove deletes it with everything in it. Both return 1, or 0 if Python has no window of that name. windows() lists every mod's windows.

blse.window_closed#

Fires when the player closes a window with its close button. The window is hidden, not deleted: window_show(name, 1) shows it again. Payload: the window's name (one field).

Python
def on_closed(topic, data):
    if data == 'notes':
        blse.log('notes closed')
blse.subscribe('blse.window_closed', on_closed)

Restyling#

Colors and fonts of any panel: the game's screens (the Esc menu's buttons, the inventory's and character screen's labels) and mods' own panels and windows. A screen applies its scheme (its colors and fonts) when it is shown, sometimes again later: BLSE keeps the style and sets it again whenever the game changes it, for as long as the panel exists. A screen the game makes anew (some are made each time they open) needs it again: restyle in blse.menu_opened. The latest change wins when two mods restyle the same panel.

Function
blse.menu_set_colors(screen, path, fg[, bg]) The text color (fg) and the background (bg) as '#RRGGBB' or '#RRGGBBAA'; None keeps one. A background with alpha 00 is not drawn. Labels, buttons and text fields color their text; windows and other panels their background. Returns 1 or 0
blse.menu_set_font(screen, path, face, size[, weight]) A font for a label, button or text field: any Windows font ('Georgia', 'Courier New') or one the game installed, size in pixels (6-128), weight 100-900 (400 normal, 700 bold). Works once the game has drawn its first frame (fonts are made through its drawing surface). Returns 1 or 0
blse.menu_set_border(screen, path, visible) Whether the panel draws its outline. Returns 1 or 0 (a window's frame lines are drawn by the window itself and stay)
blse.menu_reset_style(screen, path) The game's own colors, font and outline again (what the game itself last set). Returns 1, or 0 if the panel was not restyled from Python
blse.menu_set_hint(screen, path, hint) A hint shown faintly while a text field added from Python is empty ('' removes it). Only fields mods added (the game's own text fields draw themselves). Returns 1 or 0

A Python restart gives every panel Python restyled its own look back; a plugin's go when it is unloaded or disabled.

Python
def on_opened(topic, data):
    cls, name = data.split('\0')
    if name == 'game_menu':
        for button in ('BTN_CONTINUE', 'BTN_SAVEGAME'):
            blse.menu_set_colors('game_menu', button, '#E0C060')
            blse.menu_set_font('game_menu', button, 'Georgia', 22, 700)
blse.subscribe('blse.menu_opened', on_opened)

Round corners and other shapes: VGUI draws rectangles only. A window can still look rounded: make its background transparent (menu_set_colors(name, '', None, '#00000000')) and put an image with rounded corners behind its contents (menu_add_image with your own material).

blse.menu_set_colors#

Python
blse.menu_set_colors(screen, path, fg[, bg])   # -> 1 or 0

(b0.5.37) Sets a panel's text colour (fg) and background (bg), as '#RRGGBB' or '#RRGGBBAA'; None keeps one of them. Giving neither, or a bad colour, raises ValueError. Returns 1, or 0 if the screen is not open or the path names no panel.

blse.menu_set_font#

Python
blse.menu_set_font(screen, path, face, size[, weight])   # -> 1 or 0

(b0.5.37) A font for a label, button or text field: face 1 to 63 characters, size 6 to 128 pixels, weight 100 to 900 (default 400; 700 bold). Bad values raise ValueError. Returns 1, or 0 if the panel cannot take a font, the screen is not open, or the game has not drawn its first frame yet.

blse.menu_set_border, blse.menu_reset_style and blse.menu_set_hint#

Python
blse.menu_set_border(screen, path, visible)   # -> 1 or 0
blse.menu_reset_style(screen, path)           # -> 1 or 0
blse.menu_set_hint(screen, path, hint)        # -> 1 or 0

(b0.5.37) menu_set_border switches a panel's outline on (1) or off (0). menu_reset_style gives a panel Python restyled the game's own colours, font and outline back (0 if Python did not restyle it). menu_set_hint sets the faint hint of a text field a mod added (None or '' removes it). All return 1 on success, else 0.

Python
blse.menu_set_hint('notes', 'text', 'Write here...')

Button sounds#

(b0.5.49) The game's buttons have no sounds of their own (only the main menu plays a few, its own way). Mods give any button sounds, the game's own (main and Esc menu, Options and the other GameUI dialogs, the character sheet, the inventory, ...) and mods' own, also on the main menu with no level loaded:

Function
blse.set_button_sound(screen, button, kind, file[, volume[, pitch]]) When a button on screen matching button does kind, file (below sound/) plays. screen: a screen name ('game_menu' is the main menu and the Esc menu, 'options', 'character', ...; a mod's window name) or a pattern. button: the path as menu_panels shows it, or just the button's own name, or a pattern. kind: 'hover' (it lights up under the pointer), 'leave' (it goes dark), 'press' (the left mouse button goes down on it), 'click' (it does its action: mouse release, keys, menu_press). volume 0..1 (default 1), pitch 100 normal. file '' or None removes the rule. 1 or 0
blse.button_sounds([screen]) [(screen, button, kind, file, volume, pitch, mine), ...]: every mod's rules (those whose screen pattern matches screen), oldest first; mine is 1 for Python's. For finding out who set what
blse.play_ui_sound(file[, volume[, pitch]]) Plays an interface sound the way the game's main menu plays its own: also at the main menu with no level loaded and over the paused Esc menu. 1 or 0
blse.menu_hover (event) screen, path = data.split('\0'): a button lit up under the pointer (any button of an open screen or window). Delivered at the next painted frame

Patterns: * any characters (/ included), ? one character; case does not matter. A pattern without / matches a button's whole path or its own name ('BTN_*' matches 'Panel/BTN_OPTIONS'). When several rules name the same button and kind, one naming it without wildcards wins over a wildcard one; otherwise the rule set later wins (whichever mod set it). Setting a rule again replaces your own and makes it the latest. Rules from Python go when Python restarts; a plugin's when it is unloaded or disabled.

Rules apply to buttons as they appear: a screen the game builds anew each time it opens gets them again by itself (no need to set them in blse.menu_opened). Buttons the player cannot use (disabled) are silent. A button press runs before the button's action, so a press sound plays even when the action closes the screen.

The main menu's own sounds stay (interface/mm_cursor_over.wav, mm_cursor_left.wav, mm_click_on.wav): to change or silence them, replace those files in a mod folder. A hover rule on the main menu plays together with the game's own hover sound.

Core rule: nothing is attached to any button while no rule exists and nobody listens to blse.menu_hover; listening to blse.menu_hover attaches BLSE to every button of the open screens.

Python
blse.set_button_sound('*', '*', 'hover', 'interface/bubble_click_on.wav', 0.6)
blse.set_button_sound('*', '*', 'click', 'interface/bubble_click_off.wav')
blse.set_button_sound('game_menu', 'BTN_QUIT', 'hover', 'mymod/ui/creak.wav')  # beats the '*' rule

blse.set_button_sound#

Python
blse.set_button_sound(screen, button, kind, file[, volume[, pitch]])   # -> 1 or 0

(b0.5.49) Gives buttons a sound. Use it for a mod that makes the menus feel alive, or for your own window's buttons.

  • screen (str): a screen or window name, or a pattern ('*' every screen).
  • button (str): a button's path as menu_panels shows it, its own name, or a pattern.
  • kind (str): 'hover', 'leave', 'press' or 'click' (see the table above).
  • file (str or None): a sound below sound/ ('interface/bubble_click_on.wav'); '' or None removes your rule for this screen, button and kind.
  • volume (float, optional): 0 to 1, default 1. pitch (int, optional): 100 is normal (default).
  • Returns 1, or 0 for bad values.

blse.button_sounds#

Python
blse.button_sounds([screen])   # -> [(screen, button, kind, file, volume, pitch, mine), ...]

(b0.5.49) Lists every mod's button sound rules, oldest first; with screen, only rules whose screen pattern matches it. mine is 1 for Python's rules. Use it to find out which mod set a sound.

blse.play_ui_sound#

Python
blse.play_ui_sound(file[, volume[, pitch]])   # -> 1 or 0

(b0.5.49) Plays an interface sound (below sound/) the way the main menu plays its own: also at the main menu with no level loaded, and over the paused Esc menu. volume 0 to 1 (default 1), pitch 100 normal. Returns 1, or 0 if it could not be played. For sounds in the world, see the world page.

Python
blse.play_ui_sound('interface/bubble_click_on.wav', 0.8)

blse.menu_hover#

(b0.5.49) Fires when a button of an open screen or window lights up under the pointer. Delivered at the next painted frame. Listening to it attaches BLSE to every button of the open screens, so listen only while needed.

Payload, in order: screen, path (the button's path).

Python
def on_hover(topic, data):
    screen, path = data.split('\0')
    if screen == 'game_menu':
        blse.log('pointer on ' + path)
blse.subscribe('blse.menu_hover', on_hover)

Controls, lists and blocked screens#

The game's own controls, added like menu_add_button (to a game screen or a mod's window; they live as long as it does). Positions and sizes in pixels. Each returns 1 or 0.

Function
blse.menu_add_checkbox(screen, parent_path, name, text, checked, x, y, w, h) A checkbox
blse.menu_add_slider(screen, parent_path, name, minimum, maximum, value, x, y, w, h) A slider of whole numbers. A click on it moves the knob there
blse.menu_add_dropdown(screen, parent_path, name, items, selected, x, y, w, h) A drop-down list (1-256 strings); its value is the chosen text
blse.menu_add_progress(screen, parent_path, name, value, x, y, w, h) A progress bar, 0 to 1
blse.menu_add_list(screen, parent_path, name, x, y, w, h) A scrolling list (scroll bar and mouse wheel)
blse.menu_list_add(screen, list_path, row, text[, height]) A row at the end (24 pixels high by default), or new text for an existing row. Rows are buttons: a click is blse.menu_button with the path '<list>/<row>'
blse.menu_list_clear(screen, list_path) Removes every row
blse.menu_value(screen, path) A control's value as text: '1'/'0', a slider's number, a progress bar's '0.400', a drop-down's text; also the game's own controls (the options screens). None for other panels
blse.menu_set_value(screen, path, value) Sets a checkbox, slider, progress bar or drop-down (also the game's own)
blse.menu_set_items(screen, path, items) New choices for a drop-down this mod added
blse.menu_changed (event) screen, path, value = data.split('\0'): the player changed a checkbox, slider or drop-down a mod added (not changes made with menu_set_value)
blse.menu_block(screen[, on]) Keeps a game screen from opening so a mod shows its own: 'inventory', 'character', 'journal', 'map', 'hotkeys' or 'game_menu' (ValueError for others). The key that opens it does nothing while the player is in the game (found by the command bound to it, so it follows the player's own keys; Escape for the game menu); a screen open already stays open. Several mods may block a screen; it opens again when none does. Blocking the inventory also blocks bartering (the same screen)
blse.menu_blocked (event) cls, name = data.split('\0'): the player pressed the key of a blocked screen: show the mod's own now
blse.hud_in_menus(id[, on]) A HUD element (text, box, image, input) also drawn, and clicked, while game screens are open, the game's menu is up and in the main menu

Notes: this game's scroll bars and sliders cannot be dragged (also the game's own, in its options); they move by clicking and the mouse wheel. Sliders BLSE adds show a track but no knob; their value is set by clicking along them and read with menu_value.

Python
def open_bag(topic, data):
    blse.window_create('bag', 'Bag', 200, 100, 420, 520)
    blse.menu_add_list('bag', '', 'items', 10, 40, 400, 470)
    for cls in blse.inventory():
        blse.menu_list_add('bag', 'items', cls, cls)
blse.menu_block('inventory')
blse.subscribe('blse.menu_blocked', open_bag)

blse.menu_add_checkbox, blse.menu_add_slider, blse.menu_add_dropdown and blse.menu_add_progress#

Python
blse.menu_add_checkbox(screen, parent_path, name, text, checked, x, y, w, h)              # -> 1 or 0
blse.menu_add_slider(screen, parent_path, name, minimum, maximum, value, x, y, w, h)      # -> 1 or 0
blse.menu_add_dropdown(screen, parent_path, name, items, selected, x, y, w, h)            # -> 1 or 0
blse.menu_add_progress(screen, parent_path, name, value, x, y, w, h)                      # -> 1 or 0

The game's own controls, for a settings window. screen, parent_path, name, x, y, w, h as for menu_add_label.

  • Checkbox: text its label, checked 1 or 0.
  • Slider: whole numbers from minimum to maximum (maximum must be above minimum, else ValueError), starting at value.
  • Drop-down: items a list of 1 to 256 strings (else ValueError), selected the text chosen at first.
  • Progress bar: value from 0 to 1.
  • Return 1, or 0 if the screen is not open or the parent cannot hold panels.

When the player changes a checkbox, slider or drop-down, blse.menu_changed fires.

Python
blse.window_create('mymod_cfg', 'My mod', 200, 120, 360, 220)
blse.menu_add_checkbox('mymod_cfg', '', 'hud', 'Show the counter', 1, 20, 40, 300, 24)
blse.menu_add_slider('mymod_cfg', '', 'speed', 1, 10, 5, 20, 80, 300, 24)
blse.menu_add_dropdown('mymod_cfg', '', 'mode', ['easy', 'normal', 'hard'], 'normal', 20, 120, 200, 24)

blse.menu_add_list, blse.menu_list_add and blse.menu_list_clear#

Python
blse.menu_add_list(screen, parent_path, name, x, y, w, h)    # -> 1 or 0
blse.menu_list_add(screen, list_path, row, text[, height])   # -> 1 or 0
blse.menu_list_clear(screen, list_path)                      # -> 1 or 0

A scrolling list of rows; each row is a button. menu_list_add adds a row named row at the end, or gives an existing row new text; height is 8 to 512 pixels (default 24, else ValueError). A click on a row fires blse.menu_button with the path '<list>/<row>'. menu_list_clear removes every row. All return 1, or 0 if the screen is not open or list_path is not a list Python added.

blse.menu_value, blse.menu_set_value and blse.menu_set_items#

Python
blse.menu_value(screen, path)               # -> str or None
blse.menu_set_value(screen, path, value)    # -> 1 or 0
blse.menu_set_items(screen, path, items)    # -> 1 or 0

menu_value reads a control's value as text: '1'/'0' for a checkbox, a slider's number, a progress bar's fraction ('0.400'), a drop-down's chosen text; also for the game's own controls (the options screens). None for other panels or when the screen is not open.

menu_set_value sets a checkbox, slider, progress bar or drop-down (also the game's own); value may be text or a number (it is turned into text). It does not fire blse.menu_changed. menu_set_items gives a drop-down Python added new choices (a list of up to 256 strings, else ValueError). Both return 1, or 0 if the panel is not such a control or the screen is not open.

Python
if blse.menu_value('mymod_cfg', 'hud') == '1':
    blse.ini_set('mymod', 'General', 'hud', 1)

blse.menu_changed#

Fires when the player changes a checkbox, slider or drop-down a mod added (not changes made with menu_set_value).

Payload, in order: screen, path, value (the new value as text, as menu_value gives it).

Python
def on_changed(topic, data):
    screen, path, value = data.split('\0')
    if screen == 'mymod_cfg' and path == 'speed':
        blse.ini_set('mymod', 'General', 'speed', int(value))
blse.subscribe('blse.menu_changed', on_changed)

blse.menu_block#

Python
blse.menu_block(screen[, on])   # -> 1 or 0

(b0.5.46) Keeps a game screen from opening (on 1, the default) or lets it open again (0), so a mod can show its own instead. screen is exactly one of 'inventory', 'character', 'journal', 'map', 'hotkeys', 'game_menu' (lower case; another name raises ValueError). Returns 1, or 0 if it could not be set. See the table above for how the keys behave.

blse.menu_blocked#

(b0.5.46) Fires when the player presses the key of a blocked screen: show your own screen now. Payload, in order: cls, name, as for blse.menu_opened (see the open_bag example above).

blse.hud_in_menus#

Python
blse.hud_in_menus(id[, on])   # -> 1 or 0

Lets one of Python's HUD overlay elements also be drawn, and clicked, while game screens are open, in the game's menu and in the main menu (on 1, the default), or not (0). Returns 1 if Python has an element with this id, else 0.