Skip to content

GUI

Displaying a gui

The gui module

This module exposes the gui function

The gui function is used to present the queued gui layout.

gui() returns Promise and therefore an await should be used to allow the gui to run.

gui_text("Hello, World")
await gui()
Example

To insert a blank part of the layout just call gui_blank::

gui_blank()

Proving a count will allow inserting multiple blanks::

gui_blank(4)

One use of blanks it to help center an element but also adding space::

gui_blank()
gui_icon(...)
gui_blank()

await_gui_sites_clear()

Per-mission reset -- see handlerhooks.reset_mission_state.

gui(buttons=None, timeout=None)

Present the GUI layout that has been queued up for the current client.

Suspends execution until the player presses a button or the timeout fires. GUI elements (text, images, sections, etc.) must be queued with gui_* calls before await gui(); they are rendered when the promise activates.

Parameters:

Name Type Description Default
buttons dict

Extra buttons to add, mapping label text to jump target label name. e.g. {"Start": "start_label"}. Defaults to None.

None
timeout Promise

A promise (e.g. timeout_sim(30)) that cancels the GUI when it resolves. Defaults to None.

None

Returns:

Name Type Description
Promise

Resolves when a button is pressed or timeout fires.

Example

gui_text("Choose your mission") await gui(): + "Patrol": jump patrol_mission + "Escort": jump escort_mission

gui_client_id()

Return the client ID for the currently executing GUI task.

Shortcut for FrameContext.client_id. Returns 0 when running on the server.

Returns:

Name Type Description
int

Current client ID, or 0 for the server.

Example

id = gui_client_id() gui_text("Your client ID is {id}")

gui_hide_choice()

Hide the button that was just pressed during its handler block.

Call this from inside a button's handler block to remove the button from the layout immediately after it is clicked, without waiting for the await gui() to complete. Has no effect if called outside of a running button handler.

Example

await gui(): + "Launch Missile": gui_hide_choice() ~~ fire_torpedo(SHIP_ID) ~~

gui_page_for_client(client_id)

Return the active GUI page for a client.

Parameters:

Name Type Description Default
client_id int

The client to look up.

required

Returns:

Type Description

Page | None: The client's current page, or None if unavailable.

Example

page = gui_page_for_client(CLIENT_ID) if page is not None: ~~ page.dirty() ~~

gui_percent_from_ems(client_id, ems, font)

Convert an em-based size to GUI percentage coordinates for a client's screen.

An em is the width/height of the character "X" in the given font. Use this to size layout elements relative to text size rather than fixed pixels.

Parameters:

Name Type Description Default
client_id int

The client whose screen resolution to use.

required
ems float

The number of em units to convert.

required
font str

Font name used to measure one em (e.g. "hud_font").

required

Returns:

Name Type Description
Vec3

Percentage values (x=horizontal %, y=vertical %, z=0).

Example

pct = gui_percent_from_ems(CLIENT_ID, 2, "hud_font") gui_section(style="width:{pct.x}%;")

gui_percent_from_pixels(client_id, pixels)

Convert a pixel size to GUI percentage coordinates for a client's screen.

GUI layout positions are expressed as percentages (0–100) of the screen dimensions. Use this to convert a fixed pixel measurement to the equivalent percentage for a specific client's resolution.

Parameters:

Name Type Description Default
client_id int

The client whose screen resolution to use.

required
pixels float

The pixel size to convert.

required

Returns:

Name Type Description
Vec3

Percentage values (x=horizontal %, y=vertical %, z=0).

Example

pct = gui_percent_from_pixels(CLIENT_ID, 40) gui_section(style="height:{pct.y}%;")

gui_properties_change(var, label)

Watch a MAST variable and run an inline block when its value changes.

Registers a per-tick change detector on the current client's GUI task. When var changes value, the block at label is pushed and executed immediately within the current tick.

Parameters:

Name Type Description Default
var str

Name of the MAST variable to watch.

required
label

The inline label or block to execute on change.

required
Example

gui_properties_change("shield_level", shield_changed) ///shield_changed gui_text("Shields: {shield_level}")

gui_screen_size(client_id)

Return the pixel dimensions of a client's screen.

CAUTION: when the client has not reported its size yet, this returns a 1024x768 PLACEHOLDER with z == 99 rather than a real measurement, and a client that reconnects goes back to the placeholder until its next resize event. Branching on the width without checking validity silently builds the small-screen layout on a large display:

ss = gui_screen_size(client_id)
if ss.x < 1600:          # WRONG - 1024 placeholder also lands here
    ...

Use gui_screen_size_known to tell "small" from "unknown".

Parameters:

Name Type Description Default
client_id int

The client whose screen to query.

required

Returns:

Name Type Description
Vec3

Screen dimensions in pixels (x=width, y=height); z is

GUI_SCREEN_SIZE_UNKNOWN_Z (99) when the size is not yet known.

Example

size = gui_screen_size(CLIENT_ID) ~~ print(size.x, size.y) ~~

gui_screen_size_known(client_id)

True when the client has actually reported its screen size.

Pair with gui_screen_size before branching on the dimensions, so an unknown size can be handled deliberately (usually: assume the LARGER layout, which degrades better than cramming a wide screen into the narrow one).

Parameters:

Name Type Description Default
client_id int

The client whose screen to query.

required

Returns:

Name Type Description
bool

False while the size is still the 1024x768 placeholder.

Example

ss = gui_screen_size(client_id) if not gui_screen_size_known(client_id) or ss.x >= 1600: gui_row("row-height: 35px;col-width:45px;") else: gui_row("row-height: 35px;col-width:25px;")

gui_task_for_client(client_id)

Return the GUI task currently running for a client.

Each connected client has a dedicated GUI task that drives its page layout. Returns None if the client has no active page.

Parameters:

Name Type Description Default
client_id int

The client to look up.

required

Returns:

Type Description

MastAsyncTask | None: The client's GUI task, or None if unavailable.

Example

task = gui_task_for_client(CLIENT_ID) if task is not None: ~~ task.set_variable("score", 10) ~~

promote_await_gui(page, task, gui_task)

await gui() reached on a task that is not the console's GUI task.

A handler runs on whatever task built the widget, which is very often not the GUI task (LM #714). When such a handler paints a screen and awaits, the console has to follow it -- but the GUI task's in-flight GuiPromise must NOT resolve, or the GUI task falls through past its own await gui() into whatever comes next, leaving a screen nobody asked to leave. So this is a JUMP on the GUI task, not a handover of the promise.

The GUI task is sent to the very command the handler is standing on -- the await gui() itself -- so it re-evaluates gui() as the GUI task and takes the normal swap_gui_promise path. Nothing is re-executed: the widgets the handler already queued stay exactly as it left them.

The old promise is neither resolved nor cancelled here. do_jump does not call leave(), so it is simply abandoned; swap_gui_promise cancels it a moment later, once the GUI task has already jumped off that node.

Returns one of PROMOTED / STEERED_ALREADY / NOT_PROMOTED. The first two both end the calling task and neither warrants a warning; only the last leaves an await gui() that nothing will ever resolve.

warn_await_gui_off_gui_task(task)

Report an await gui() that will never resolve.

Without promotion this hangs the calling task silently and permanently: the promise is returned and awaited, but the page never adopted it, so nothing will ever resolve it. It used to be a bare print(), which in the engine goes nowhere a scripter will look.

This module exposes the gui_blank function

The gui_blank function is used to insert a black space in a layout. Blanks are useful to add space.

Example

To insert a blank part of the layout just call gui_blank::

gui_blank()

Proving a count will allow inserting multiple blanks::

gui_blank(4)

One use of blanks it to help center an element but also adding space::

gui_blank()
gui_icon(...)
gui_blank()

gui_blank(count=1, style=None)

Add one or more empty columns to the current layout row.

Blanks occupy column space without rendering anything visible. Use them to push elements right, add padding, or center icons.

Parameters:

Name Type Description Default
count int

Number of blank columns to insert. Defaults to 1.

1
style str

CSS-like style overrides applied to each blank. Defaults to None.

None

Returns:

Name Type Description
Blank

The last blank layout item created.

Example

gui_blank() gui_icon("icons/shield") gui_blank()

gui_hole(count=1, style=None)

Reserve empty column space that the next layout item expands to fill.

Unlike gui_blank, a hole is consumed by the following item as extra width. Use it to make a single element span multiple column slots.

Parameters:

Name Type Description Default
count int

Number of extra column slots to reserve. Defaults to 1.

1
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Hole

The last hole layout item created.

Example

gui_hole(2) gui_text("This text spans 3 columns")

gui_row(style=None)

Start a new layout row, pushing subsequent items to the next line.

Call before adding items that should appear on a fresh row. Without explicit rows, items flow left-to-right across the current row.

Parameters:

Name Type Description Default
style str

CSS-like style overrides for the row container. Defaults to None.

None

Returns:

Name Type Description
Row

The row layout object.

Example

gui_text("Name:") gui_row() gui_input("", var="ship_name")

PageSubSection

is_message_for(event)

Used by MessageTrigger i.e. gui_message to know if message is for this object

Parameters:

Name Type Description Default
event EVENT

the engine event

required

Returns:

Name Type Description
bool

if the gui_message MessageTrigger should be True

gui_region(style=None)

Create a re-representable GUI region pinned to an absolute screen area.

Unlike gui_sub_section, a region uses absolute positioning (the area style property) and can be redrawn independently with region.represent(). Use it for UI panels that update without redrawing the entire page. Also a context manager — content inside the with block is placed in the region.

Parameters:

Name Type Description Default
style str

CSS-like style string. The area: property sets the absolute screen position (left, top, right, bottom %). Defaults to None.

None

Returns:

Name Type Description
PageRegion

Context manager object with show(), rebuild(), and represent() methods.

Example

hud = gui_region(style="area:0,0,100,10;") with hud: gui_text("HUD content here") ~~ hud.represent(event) ~~ # refresh just this region later

gui_section(style=None)

Create a top-level GUI layout section at a specific screen area.

Sections are the primary way to position content on screen. The area style property sets the region (left, top, right, bottom as percentages). Content added after this call is placed inside the section until the next gui_section or the frame ends.

Parameters:

Name Type Description Default
style str

CSS-like style string. Use area: to position the section, e.g. "area:10,10,90,90;". Defaults to None.

None

Returns:

Name Type Description
Layout

The layout object for this section.

Example

gui_section(style="area:5,5,95,50;") gui_text("Top half of screen") gui_section(style="area:5,50,95,95;") gui_text("Bottom half of screen")

gui_sub_section(style=None)

Create a nested layout sub-section, used as a context manager.

Sub-sections let you group and style a subset of content within the current section. Use with Python's with statement in MAST via the with keyword. The sub-section is added to the current layout when the with block exits.

The returned object can be hidden and restored after it is built, with gui_hide / gui_show or its own show(). Hiding takes the whole sub-tree off screen, and its siblings reclaim the space on the next layout pass. Hold on to the object to do that - hiding one before its with block has run is a no-op, since the layout it stands for does not exist yet.

Parameters:

Name Type Description Default
style str

CSS-like style string controlling the column width, row height, background, etc. of the sub-section. Defaults to None.

None

Returns:

Name Type Description
PageSubSection

Context manager object with show() and is_hidden. Use with with.

Example

gui_row(style="row-height:3em;") with gui_sub_section(style="col-width:30%;"): gui_text("Left column") right = gui_sub_section() with right: gui_text("Right column") gui_hide(right) # and gui_show(right) to bring it back

Responding to gui interactions

dead_handler_sites_clear()

Per-mission reset -- see handlerhooks.reset_mission_state.

gui_host_task(task)

The page's live GUI task -- who can tick a handler this task registered.

gui_message(layout_item, label=None)

Register a MAST label to run when a layout element receives a GUI event.

Attaches a MessageTrigger to the current task so that when the engine fires a gui_message event matching layout_item's tag, the given label is pushed and executed inline. Used to respond to clicks on custom layout items (sections, regions, etc.) that are not plain buttons.

Parameters:

Name Type Description Default
layout_item

The layout object whose tag to watch. Must expose is_message_for(event) (all standard layout items do).

required
label optional

MAST label or inline block to run on the event. Defaults to the current active label.

None

Returns:

Name Type Description
MessageTrigger

The registered trigger object.

Example

region = gui_region(style="area:10,10,50,50;") gui_message(region, on_region_click) ///on_region_click gui_text("Region clicked!")

gui_message_callback(layout_item, cb)

Set a Python callable to invoke when a layout element receives a GUI event.

Attaches a callback directly to the layout item's on_message_cb attribute. The callback is called with the event and the layout item when the engine fires a gui_message event matching the item's tag. Use this for pure-Python handlers; use gui_message for MAST label handlers.

Parameters:

Name Type Description Default
layout_item

The layout object to attach the callback to.

required
cb callable

Function called as cb(event, layout_item) on event.

required
Example

btn = gui_button("Fire!", on_press=None) gui_message_callback(btn, lambda e, item: fire_torpedo(SHIP_ID))

gui_message_clear(layout_item)

Drop EVERY gui_message handler attached to a widget, on both channels.

Handlers accumulate now (LM #614), so replacing rather than adding takes an explicit step: clear, then register. Before #614 a plain re-registration did this implicitly, by throwing the previous handler away.

Parameters:

Name Type Description Default
layout_item

the widget to detach every handler from.

required

Returns:

Name Type Description
int

how many registrations were removed.

gui_message_label(layout_item, label)

Schedule a MAST label as a sub-task when a layout element receives a GUI event.

Similar to gui_message_callback but wraps the label in a gui_sub_task_schedule call, running it as an independent sub-task rather than inline in the current task.

Parameters:

Name Type Description Default
layout_item

The layout object to attach the handler to.

required
label

MAST label to schedule as a sub-task on event.

required
Example

section = gui_sub_section(style="col-width:30%;") gui_message_label(section, handle_section_click)

host_handler_sub_task(builder, sub_task)

Give a handler sub-task a LIVE ticking parent when its builder has ended.

A gui_message(widget, label) handler runs as a sub-task of the task that built the widget, and sub-tasks are only ever ticked by their parent's tick(). On a finished builder that is exactly one tick -- the tick_in_context() at the call site -- after which the handler stalls wherever it happens to be. Single-line handlers looked like they worked; anything that awaited did not.

The page's gui_task takes over the TICKING only. root_task is deliberately left pointing at the builder, so the handler's variable scope is exactly what it is when the builder is alive.

Returns True when the sub-task was re-hosted.

warn_dead_handler(task, label, loc, kind)

Report a click that landed on a task which has already finished.

Without this the failure is completely silent: the widget draws, the click dispatches, the handler is discarded, and nothing is logged anywhere. That silence is most of what made LM issue #707 hard to place.

Gui control formatting

gui_set_style_def(name, style)

Parse a style string and register it under a named class.

After registering, the name can be used as a CSS class reference in any style string (e.g. ".my_style").

Parameters:

Name Type Description Default
name str

Class name to register (conventionally prefixed with "."), e.g. ".alert".

required
style str

CSS-like style string to associate with the name.

required

Returns:

Name Type Description
StyleDefinition

The parsed and registered style object.

Example

gui_set_style_def(".alert", "color:red;background:#400;") gui_text("Warning!", style=".alert")

gui_style_def(style)

Parse a CSS-like style string into a StyleDefinition object.

Useful when you want to pre-parse a style string and inspect or reuse it without re-parsing each time.

Parameters:

Name Type Description Default
style str

CSS-like style string, e.g. "color:red;col-width:50%;".

required

Returns:

Name Type Description
StyleDefinition

Parsed style object.

Example

s = gui_style_def("color:green;font:hud_font;")

GUI Controls

MessageHandler

is_inert()

True when this handler has nothing to run.

gui_button() builds one of these even with no on_press, because the click also sets ITEM and unpacks the widget's data. With no handler it falls through to start_sub_task(None, ...), so it must not become a link in a chain -- see message_chain.compose_handler. (LM #614)

runs_as_sub_task()

Whether this click starts a sub-task or jumps the builder.

Explicit wins in both directions. Unspecified follows MastAsyncTask.handler_defaults_to_sub_task(), which is the #714 pair -- sub-task default + await gui() promotion -- and is all-or-nothing on purpose.

gui_button(props, style=None, data=None, on_press=None, is_sub_task=None)

Add a button to the current GUI layout outside of an await gui() block.

Unlike buttons declared with * or + inside await gui(), this button is placed directly in the layout at the current position and fires its handler without ending the surrounding await gui(). Use it for action buttons embedded in panels, listboxes, or info panels.

Parameters:

Name Type Description Default
props str

Button label text, optionally as a property string (e.g. "$text:Fire!;color:red;"). Supports {var} interpolation.

required
style str

Additional CSS-like style overrides. End each property with a semicolon, e.g. "col-width:20%;". Defaults to None.

None
data object

Arbitrary data passed to the handler. Available as __ITEM__ and (if a dict) as individual variables. Defaults to None.

None
on_press label | callable | Promise

What to do when the button is pressed. A label is jumped to; a callable is called; a Promise has its result set. Defaults to None.

None
is_sub_task bool

How an on_press label runs. True runs it as a sub-task: safe to press repeatedly, and it should end with ->END. False jumps the task that built the widget, so the press takes that task over and the handler must hand the console back -- this is the historical behavior and is deprecated. Defaults to None, meaning the library decides; a handler that paints a screen and reaches await gui() sends the GUI task there either way, so you should not need this.

None
Valid Styles

area: Format as top, left, bottom, right. Just numbers indicates percentage of the section or page to cover. Can also use px (pixels) or em (1em = height of text font). Can combine different units, e.g. 5+5px, 3em, 100-10em, 50px; is a valid area. color: The color of the text background-color: The background color of the button padding: A gap inside the element (makes the button smaller, but the background still is there.) margin: The gap outside the element (makes the button smaller). col-width: The width of the button justify: Where the text is placed inside the button. left, center, or right font: The font to use. Overrides the font in prefernces.json

Returns:

Type Description

layout object: The Layout object created

handler_inputs(data)

A widget's data= as the dict start_sub_task wants.

The two dispatch paths disagreed about non-dict data: the jump path bound it to a variable called data, while the sub-task path handed it straight to start_sub_task, whose for k in inputs then walked a string or a list. A dict was always fine on both. This makes them agree. (LM #714)

gui_checkbox(msg, style=None, var=None, data=None)

Add a checkbox to the current GUI layout.

The current value of var (expected to be a bool) sets the initial checked state. When the player toggles the checkbox, var is updated.

Parameters:

Name Type Description Default
msg str

Label text or property string shown next to the checkbox, e.g. "Enable shields" or "$text:Active;color:white;".

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to read the initial checked state from and update on toggle. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None

Returns:

Name Type Description
Checkbox

The layout item created.

Example

gui_checkbox("Enable auto-fire", var="auto_fire_on")

gui_cinematic_auto(client_id)

Switch a client to cinematic view, automatically tracking its assigned ship.

Sets the client's view mode to "3dview/front/cinematic" with automatic camera control. The tracked ship must expose excitement values; player ships have these set automatically.

Parameters:

Name Type Description Default
client_id int

The client to switch to cinematic view.

required
Example

gui_cinematic_auto(CLIENT_ID)

gui_cinematic_full_control(client_id, camera_id, camera_offset, tracked_id, tracked_offset)

Switch a client to cinematic view with explicit camera and target control.

Sets the view mode to "3dview/front/cinematic" and hands full camera control to the caller. Both offset vectors are converted to engine vec3 objects before being passed to cinematic_control.

Parameters:

Name Type Description Default
client_id int

The client to switch to cinematic view.

required
camera_id int

Object ID to use as the camera position anchor.

required
camera_offset Vec3 | None

Offset from camera_id in world units. Pass None to use the object's origin.

required
tracked_id int

Object ID for the camera to look at.

required
tracked_offset Vec3 | None

Offset from tracked_id to look at. Pass None to use the object's origin.

required
Example

gui_cinematic_full_control(CLIENT_ID, camera_ship_id, Vec3(0,50,0), target_id, None)

gui_content(content, style=None, var=None)

Place a Python widget object into the layout system.

Wraps a pre-built Python widget (e.g. a ship picker, custom control) in a GuiControl so it participates in the normal layout flow.

Parameters:

Name Type Description Default
content widget

A Python GUI widget object.

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to bind the widget's value to. The current value of var is pushed into the widget and updates flow back when the widget changes. Defaults to None.

None

Returns:

Name Type Description
GuiControl

The layout wrapper object.

Example

picker = ShipPicker(0, 0, "mast", "Your Ship") gui_content(picker, var="selected_ship")

gui_drop_down(props, style=None, var=None, data=None)

Add a drop-down list to the current GUI layout.

When the player selects an item, var is updated. var is written, not read: the INITIAL selection comes from text: in props, so interpolate the variable there yourself -- f"text:{speed};list:Slow,Medium,Fast;" -- or set it afterwards with .value.

Parameters:

Name Type Description Default
props str

Semicolon-separated properties. The options go in list: (comma separated) and the closed-state label in text:, e.g. "text:Red;list:Red,Green,Blue". NOT items: - a dropdown with no list: has nothing to render and the engine dies allocating for it (MemoryError: bad allocation), which reads as anything but a typo.

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to write the selection to when it changes. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None

Returns:

Name Type Description
Dropdown

The layout item created.

Example

speed = gui_drop_down("text:Medium;list:Slow,Medium,Fast;", var="speed_setting") speed.value = "Fast" # move the selection from script

gui_face(face, style=None)

Add a character face portrait to the current GUI layout.

Renders the named face asset, typically used in comms panels to show the speaker's portrait.

Parameters:

Name Type Description Default
face str

Face asset name or property string, e.g. "crew/captain".

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Face

The layout item created.

Example

gui_face("crew/captain")

gui_icon(props, style=None, data=None)

Add an icon image to the current GUI layout.

Renders an icon from the atlas or media path. It is not clickable on its own, but a click_tag: in the style makes it so - which is why it can carry data like any other widget.

Parameters:

Name Type Description Default
props str

Icon key, atlas name, or image property string, e.g. "icons/torpedo" or "image:icons/torpedo;color:yellow;".

required
style str

CSS-like style overrides. Defaults to None.

None
data object

Arbitrary data carried by the widget, read back in a handler as __ITEM__.data and - when it is a dict - unpacked into the handler's variables. Defaults to None.

None

Returns:

Name Type Description
Icon

The layout item created.

Example

gui_icon("icons/shield") gui_text("{shield_pct}%")

gui_icon_add_atlas(name, image, left=None, top=None, right=None, bottom=None, color=None)

Claim an icon NAME for a cell of your own sheet.

gui_icon_add_atlas("wanted", media_shared("icons/quest-sheet"), 0, 0, 64, 64)

From then on every gui_icon_name("quest.job") draws your art - the meaning points at the look wanted, and this claims that look. Nothing that draws it changes.

This is gui_image_add_atlas(..., domain="icon"). The domain is what separates a deliberate re-skin from an image that happens to be called square.

gui_icon_add_atlas_grid(image, cols, rows=None, names=None, cell=None, color=None, start=0)

Claim a whole sheet of icon names at once - gui_image_add_atlas_grid in the icon domain. Names are laid out row-major; a None entry skips a cell.

gui_icon_button(props, style=None, data=None, on_press=None, is_sub_task=None)

Add a clickable icon button to the current GUI layout.

Like gui_icon but the rendered item accepts click events. Takes data and on_press exactly as gui_button does, so a row of icon buttons built in a loop can each say which row they belong to (LM #708).

Parameters:

Name Type Description Default
props str

Icon key, atlas name, or image property string, e.g. "icons/fire" or "image:icons/fire;color:red;".

required
style str

CSS-like style overrides. Defaults to None.

None
data object

Arbitrary data carried by the widget. The handler reads it as __ITEM__.data; a dict is also unpacked into the handler's variables. Defaults to None.

None
on_press label | callable | Promise

What to do when the icon is pressed. A label is jumped to; a callable is called; a Promise has its result set. Defaults to None - attach the handler with gui_message / gui_click instead.

None
is_sub_task bool

How an on_press label runs. True runs it as a sub-task: safe to press repeatedly, and it should end with ->END. False jumps the task that built the widget, so the press takes that task over and the handler must hand the console back -- this is the historical behavior and is deprecated. Defaults to None, meaning the library decides; a handler that paints a screen and reaches await gui() sends the GUI task there either way, so you should not need this.

None

Returns:

Name Type Description
IconButton

The layout item created.

Example

btn = gui_icon_button("icons/fire", data={"slot": i}) gui_message(btn, on_fire_clicked) ///on_fire_clicked fire_torpedo(SHIP_ID, slot)

gui_icon_name(name, color=None, style=None, props=None)

Draw an icon by NAME rather than by sheet index.

gui_icon_name("quest.job", color="#cc0")

The name is resolved by icon_names.icon_resolve: a meaning (quest.job) follows its alias to a look, and a look is either a cell of the built-in sheet or - when a mission has registered that name with gui_image_add_atlas - a cell of its own sheet. The caller says what it wants; where the art comes from is not its business, which is what lets a consumer be written before the art exists and lets a mission re-skin every screen that draws it.

An unknown name draws NOTHING and says so once, rather than falling back to some arbitrary glyph: a wrong icon is worse than a missing one, because it looks deliberate.

Parameters:

Name Type Description Default
name str

a meaning or a look - see icon_names.icon_names().

required
color str

tint. The built-in glyphs are white on transparent, so one glyph serves every state.

None
style str

layout style, as for gui_icon.

None
props str

extra icon properties appended verbatim.

None

Returns:

Type Description

Icon | Image | None

gui_icon_recolor(widget, color)

Tint an icon that is already on screen, whatever gui_icon_name gave back.

That function returns an Icon for a built-in glyph and an Image for a name a mission has re-skinned, and the two carry their color in different places - so a caller that recolored by hand would work until someone registered their own sheet, which is the one thing the name indirection exists to survive. Recolor, never rebuild: the widget keeps its tag, so the engine re-sends one glyph instead of the console rebuilding a row that may be under the pilot's cursor.

Parameters:

Name Type Description Default
widget

the layout item from gui_icon_name (None is a no-op).

required
color str

the new tint.

required

Returns:

Name Type Description
bool

whether the tint was applied.

Names for the built-in icon sheet, and one lookup that takes a NAME.

data/graphics/grid-icon-sheet.png is a 2560x2560 sheet of 128px cells, 20 across - 400 slots of which 0..175 are drawn (the rest are free for custom art). The glyphs are white on transparent, which is why color: in the style string does all the work: one glyph serves every state.

Until now every caller wrote a bare number - gui_icon("icon_index:101;...") - so the quest log's state square, the list box's fold arrows and a mission's own icons were all magic constants, and nothing could be re-skinned without editing the code that draws it.

gui_icon_name("square")        -> the built-in glyph
gui_icon_name("quest.job")     -> whatever a mission says a job looks like

WHY A NAME AND NOT A NUMBER. It is the same move the image atlas already makes (gui_image_add_atlas maps a key onto a file + sub-rect): the caller says WHAT it wants and the library decides where that comes from. A name can be backed by a built-in index today and a cell of a custom sheet tomorrow, without the drawing code changing - so consumers can be written before any art exists, and a mission can re-point quest.job at its own sheet and re-skin every quest log in the game.

The identifications come from the sheet itself (most of these are from game-icons.net); a few are best-guess and marked. Adding or correcting a name is a line here.

icon_names()

Every name that resolves - the built-ins plus the meanings. For lint, for a picker, and for anyone wondering what they may ask for.

icon_props(name, color=None, extra=None)

(kind, props) for a DIRECT engine send: kind is "icon" or "image", props the style string to hand it.

Widget code goes through gui_icon_name, but the low-level renderers call send_gui_icon themselves with a hand-written property string - which is where the remaining magic numbers live. This lets them name what they draw without giving up the direct send, and an atlas-backed name comes back as an IMAGE because the engine has no icon concept for art it did not ship.

Never raises and never returns nothing: an unknown name falls back to the built-in look, because a renderer mid-frame is the worst place to discover a typo.

icon_resolve(name)

A name -> (icon_index, atlas_key). Exactly one of the two is set.

Follows aliases first, so quest.job lands on whatever look it currently points at. An unknown name resolves to (None, None) and the caller draws nothing rather than guessing a glyph - a wrong icon is worse than a missing one.

The atlas branch is what makes a custom sheet a drop-in later: register the look in the ICON DOMAIN (gui_icon_add_atlas, or Kind: icon in AMD) and it wins, with no change to anything that draws it.

The domain is a GUARD, not ceremony. ImageAtlas.all is one process-wide dict, so without it any mission registering an image called square or flag - words no one would think twice about - would silently re-skin every icon meaning pointing there. Overriding a look has to be something you meant.

gui_input(props, style=None, var=None, data=None)

Add a text input field to the current GUI layout.

The current value of var is pre-filled as the input text. When the player edits and submits, var is updated with the new value.

Parameters:

Name Type Description Default
props str

Property string for input configuration, e.g. "hint:Enter name;" or "" for defaults.

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to pre-fill and update on submit. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None

Returns:

Name Type Description
TextInput

The layout item created.

Example

gui_input("", var="ship_name", style="col-width:50%;")

ImageAtlas

qualify(key, domain=None) staticmethod

The key a registration is stored under. ImageAtlas.all is one process-wide dict, so without a domain two addons can claim the same word and the last one loaded silently wins. A domain makes the claim explicit and scoped.

gui_image(props, style=None, fit=0, color=None)

Add an image to the current GUI layout.

Resolves the image via the atlas, mission directory, and engine graphics path in that order. Prefer the named wrappers (gui_image_stretch, gui_image_absolute, etc.) over calling this directly.

Parameters:

Name Type Description Default
props str

Image filename (without extension), a registered atlas key (see gui_image_add_atlas), or an image property string like "image:media/logo;color:white;". Supports {var} interpolation.

required
style str

CSS-like style overrides. Defaults to None.

None
fit int

Scaling mode — 0=stretch, 1=absolute pixels, 2=keep aspect ratio (top-left), 3=keep aspect ratio (centered).

0
color str

Tint for this use only, overriding the atlas's own color. Lets one registered cell serve every state. Defaults to 0.

None

Returns:

Name Type Description
Image

The layout item created.

gui_image_absolute(props, style=None)

Add an image to the layout at its native pixel dimensions.

The image is drawn at 1:1 pixel size relative to the client's screen resolution, anchored at the top-left of the layout area.

Parameters:

Name Type Description Default
props str

Image filename (without extension), atlas key, or image property string.

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Image

The layout item created.

Example

gui_image_absolute("media/icons/torpedo")

gui_image_add_atlas(key, image, left=None, top=None, right=None, bottom=None, color=None, domain=None)

The image atlas allows a key name to be used to assign to a set of image properties. This key can be used instead of image properties in any command that expect image properties.

The image file passed will be used to search for the file. It will first check the mission directory followed by data/graphics folder. In the future this could be modified to account for mods, e.g. a common media folders. The image atlas takes care of supplying the correct path for the engine to use.

By specifying the rect (left,top, right, bottom) the image key can reference a part of an image.

Add a key to reference a full image

MAST / python

gui_image_add_atlas("test", "media/LegendaryMissions/operator")

Add a key to reference a full image

MAST / python

gui_image_add_atlas("test2", "media/LegendaryMissions/operator", 645,570, 950,820)

Once the atlas is added the key can be used anywhere images can be used.

MAST / python

gui_image("test")

MAST / python

# Text area also use the image atlas for images
gui_text_area("![](image://test2?scale=0.5&fill=center)")

Parameters:

Name Type Description Default
key str

the key to define in the image atlas

required
image str

The file of the image. This can also be a image property string do not include the extension. Only PNG files are valid.

required
left float

The pixel location of the left. Defaults to None.

None
top float

The pixel location of the top. Defaults to None.

None
right float

The pixel location of the right. Defaults to None.

None
bottom float

The pixel location of the bottom. Defaults to None.

None
color str

default tint for this key. A drawing call may override it.

None
domain str

a namespace for the key. ImageAtlas.all is one process-wide dict, so two addons registering card_back collide silently and the last one loaded wins. A domain scopes the claim - and something that RESOLVES through a domain (icons do) will only honor a deliberate registration.

None

Returns:

Name Type Description
ImageAtlas

The image Atlas object. This is a low level object typically used by the system

gui_image_add_atlas_grid(image, cols, rows=None, names=None, cell=None, color=None, domain=None, start=0)

Register a whole sheet of evenly spaced cells in one call.

Cutting a sheet up by hand is the same four lines of arithmetic every time, and getting one of them wrong shows up as art that is off by a cell rather than as an error (casino_media.py hand-loops exactly this).

gui_image_add_atlas_grid("media/icons/quest-sheet", 8, 8,
                         ["job", "beat", "arc"], cell=64, domain="icon")

Parameters:

Name Type Description Default
image str

the sheet, without the extension.

required
cols int

cells across.

required
rows int

cells down. Needed only to measure a cell from the file.

None
names list | dict

a list is laid out ROW-MAJOR from start, and a None entry skips that cell; a dict is {name: (col, row)} for a sparse sheet. Omit to register nothing and just get the cell size back.

None
cell int | tuple

cell size in PIXELS. Measured from the file (width / cols) when omitted, which requires the file to be readable.

None
color str

default tint for every cell.

None
domain str

namespace for the keys - see gui_image_add_atlas.

None
start int

index of the first name in row-major order.

0

Returns:

Name Type Description
dict

{name: ImageAtlas} for everything registered.

gui_image_get_atlas(text, domain=None)

The atlas registered under a key, or one built from the text as a file name.

Parameters:

Name Type Description Default
text str

a registered key, or an image path / property string.

required
domain str

look only in this domain (see gui_image_add_atlas).

None

gui_image_keep_aspect_ratio(props, style=None)

Add an image scaled to fit the area while preserving aspect ratio.

Scales the image as large as possible without cropping, anchored top-left. Leaves empty space if the area's aspect ratio differs from the image's.

Parameters:

Name Type Description Default
props str

Image filename (without extension), atlas key, or image property string.

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Image

The layout item created.

Example

gui_image_keep_aspect_ratio("media/ship/artemis")

gui_image_keep_aspect_ratio_center(props, style=None)

Add an image scaled to fit the area while preserving aspect ratio, centered.

Like gui_image_keep_aspect_ratio but centers the image in the remaining space when the aspect ratios differ.

Parameters:

Name Type Description Default
props str

Image filename (without extension), atlas key, or image property string.

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Image

The layout item created.

Example

gui_image_keep_aspect_ratio_center("media/crew/captain")

gui_image_size(file)

Return the pixel dimensions of an image file or atlas entry.

Checks the atlas first, then reads the PNG header directly. Results are cached so repeated calls are free after the first read.

Parameters:

Name Type Description Default
file str

Atlas key or image path (without .png extension).

required

Returns:

Type Description

tuple[int, int]: (width, height) in pixels, or (-1, -1) if the file cannot be read.

Example

w, h = gui_image_size("media/backgrounds/nebula")

gui_image_stretch(props, style=None)

Add an image to the layout, stretched to fill its area.

Parameters:

Name Type Description Default
props str

Image filename (without extension), atlas key, or image property string e.g. "image:media/logo;color:white;".

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Image

The layout item created.

Example

gui_image_stretch("media/backgrounds/nebula")

gui_radio(msg, style=None, var=None, data=None, vertical=False)

Add a radio button group to the current GUI layout.

The current value of var sets the initially selected option. When the player selects a button, var is updated to the selected label.

Parameters:

Name Type Description Default
msg str

Comma-separated button labels or property string, e.g. "Alpha,Beta,Gamma" or "items:Slow,Fast;"

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to read the initial selection from and update on selection. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None
vertical bool

Stack buttons vertically. Defaults to False (horizontal).

False

Returns:

Name Type Description
RadioButtonGroup

The layout item created.

Example

gui_radio("Beam,Missile,Mine", var="weapon_type")

gui_vradio(msg, style=None, var=None, data=None)

Add a vertical radio button group to the current GUI layout.

Convenience wrapper for gui_radio(..., vertical=True).

Parameters:

Name Type Description Default
msg str

Comma-separated button labels or property string.

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to read the initial selection from and update on selection. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None

Returns:

Name Type Description
RadioButtonGroup

The layout item created.

Example

gui_vradio("Alpha,Beta,Gamma", var="choice")

gui_ship(props, style=None)

Render a 3D ship model in the current GUI layout.

Displays a real-time 3D render of the named ship type within the layout area. The ship type key must match one defined in the game data.

Parameters:

Name Type Description Default
props str

Ship type key or property string, e.g. "battleship" or "$type:cruiser;angle:45;".

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Ship

The layout item created.

Example

gui_ship("battleship", style="area:20,0,80,60;")

gui_int_slider(msg, style=None, var=None, data=None)

Add an integer-only slider control to the current GUI layout.

Convenience wrapper for gui_slider(..., is_int=True).

Parameters:

Name Type Description Default
msg str

Property string defining the slider range and label, e.g. "low:1;high:10;text:int;"

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to read the initial value from and update on change. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None

Returns:

Name Type Description
Slider

The layout item created.

Example

gui_int_slider("low:1;high:5;text:int;", var="torp_count")

gui_slider(msg, style=None, var=None, data=None, is_int=False)

Add a slider control to the current GUI layout.

The current value of var is used as the initial slider position. When the player adjusts the slider, var is updated.

Parameters:

Name Type Description Default
msg str

Property string defining the slider range and label, e.g. "low:0;high:100;text:float;"

required
style str

CSS-like style overrides. Defaults to None.

None
var str

Variable name to read the initial value from and update on change. Defaults to None.

None
data object

Arbitrary data passed to the event handler. Defaults to None.

None
is_int bool

Restrict values to integers. Defaults to False.

False

Returns:

Name Type Description
Slider

The layout item created.

Example

gui_slider("low:0;high:100;text:float;", var="speed_pct")

gui_text(props, style=None)

Add a text label to the current GUI layout.

Parameters:

Name Type Description Default
props str

Text content or property string, e.g. "Hello" or "$text:Hello;color:white;". Supports {var} interpolation.

required
style str

CSS-like style overrides. Defaults to None.

None

Returns:

Name Type Description
Text

The layout item created.

Example

gui_text("Hull: {hull_pct}%") gui_text("$text:WARNING;color:red;")

gui_text_area(props, style=None, markdown=True, line_styles=None)

Add a rich text area to the current GUI layout.

Supports Markdown-style formatting and inline image references (![](image://key)). Use for multi-line or formatted text blocks.

Parameters:

Name Type Description Default
props str

Text content or Markdown string. Supports {var} interpolation.

required
style str

CSS-like style overrides. Defaults to None.

None
markdown bool

Parse the mini-markdown. Pass False to render lines VERBATIM - the right choice for source code, a MAST error dump or a raw log, where the markup rules actively corrupt the content: # starts a heading (so every MAST comment becomes one), a leading - is consumed as a bullet (->END), any [...] is read as a link reference and replaces the line, and ^ becomes a newline. {var} interpolation is also skipped, since a brace in code is a brace. Defaults to True.

True
line_styles list

One style key per line, applied in order - how you colorize text that is no longer being parsed. Pairs with markdown=False. Defaults to None.

None

Returns:

Name Type Description
TextArea

The layout item created.

Example

gui_text_area("## Status\nAll systems nominal.") gui_text_area(" Mission active") gui_text_area(source, markdown=False, line_styles=per_line_keys)

gui_text_escape(s)

Quote a dynamic value for safe inclusion as a $text: style value.

Wraps s in backticks so any : or ; it contains is treated as literal text by the style parser rather than a style property (issue #569). A literal backtick -- the quoting delimiter itself -- is stripped. An empty or None value returns "" so the caller emits $text:; with no stray backtick in the box (issue #641).

Use this ONLY on the dynamic value, e.g. f"$text:{gui_text_escape(name)};color:red;" -- never on a whole authored props string, so the author's own :/; styling is left untouched.

List boxes

gui_list_box(items, style, item_template=None, title_template=None, section_style=None, title_section_style=None, select=False, multi=False, carousel=False, collapsible=False, read_only=False, reveal=False, hint=None)

Add a listbox to the current GUI layout.

Parameters:

Name Type Description Default
items list

Items to display. Plain strings render as text rows; LayoutListBoxHeader objects (from gui_list_box_header) render as collapsible section dividers.

required
style str

CSS-like style overrides for the listbox container.

row-height is the height of ONE item row, and a FLOOR - a template that needs more grows past it. It also sizes the box each item is measured and drawn in, so a template whose rows declare no height fills the item rather than collapsing, and the item's CLICK REGION is never smaller than the row you can see.

item-gap is the spacing BETWEEN items. This is what row-height used to mean here, which made a list declaring the height its template already used render at twice the pitch.

Declare neither and an item is exactly as tall as its template's rows, with items flush - unchanged from before either key existed.

required
item_template callable | None

Called per item to build its row layout. Defaults to None (built-in text row).

None
title_template str | callable | None

Title for the listbox. A string is used as-is; a callable is invoked to build the title row. Defaults to None.

None
section_style str | None

Style overrides applied to each item row section. Defaults to None.

None
title_section_style str | None

Style overrides applied to the title section. Defaults to None.

None
select bool

Allow item selection. Defaults to False.

False
multi bool

Allow multiple simultaneous selections. Only used when select=True. Defaults to False.

False
carousel bool

Use carousel styling (e.g. ship-type selection). Defaults to False.

False
collapsible bool

Clicking a header collapses items until the next header. Defaults to False.

False
read_only bool

Prevent item modification. Defaults to False.

False
reveal bool

Scroll so the selected row is visible. A repaint rebuilds the listbox and the view starts at the top, so a restored selection can be held but off screen. Opt-in: this widget is load-bearing, and defaulting it on would move every list in every mission. Defaults to False.

False
hint object

An opaque token from the previous listbox's get_selection_hint(). A repaint builds a DIFFERENT listbox whose view starts at the top, so without this the row under the user's mouse moves. Do not inspect it; pass it along.

None

Returns:

Name Type Description
LayoutListbox

The layout object created.

Example

gui_list_box(items, style="area:0,0,100,100;", select=True)

gui_list_box_header(label, collapse=False, indent=0, selectable=False, data=None, visual_indent=None)

Create a collapsible section header for use in a listbox.

When collapsible=True is set on the listbox, clicking a header toggles the visibility of items that follow it until the next header.

Parameters:

Name Type Description Default
label str

Header label text.

required
collapse bool

Start in collapsed state. Defaults to False.

False
indent int

Logical indent level for tree structures. Defaults to 0.

0
selectable bool

Whether clicking the header fires a selection event in addition to toggling collapse. Defaults to False.

False
data object

Arbitrary data attached to the header item. Defaults to None.

None
visual_indent int | None

Override indent level for rendering only. Defaults to None (uses indent).

None

Returns:

Name Type Description
LayoutListBoxHeader

The header item.

gui_list_box_is_header(item)

Return whether a listbox item is a collapsible header.

Parameters:

Name Type Description Default
item

Any item from a listbox items list.

required

Returns:

Name Type Description
bool

True if the item is a LayoutListBoxHeader.

Example

for item in items: if gui_list_box_is_header(item): ~~ print("header:", item.label) ~~

gui_listbox_items_convert_headers(items)

Convert a flat string list into a listbox-ready list with collapsible headers.

Items prefixed with >> become LayoutListBoxHeader objects; all others pass through as plain strings. Pass the result to gui_list_box with collapsible=True to enable collapse on header click.

Parameters:

Name Type Description Default
items list[str]

Flat list of strings. Prefix a string with >> to make it a collapsible header, e.g. ">>Section A".

required

Returns:

Type Description

list[str | LayoutListBoxHeader]: Mixed list ready for gui_list_box.

Example

items = gui_listbox_items_convert_headers( [">>Section A", "Item 1", "Item 2", ">>Section B", "Item 3"] ) gui_list_box(items, style="", select=True, collapsible=True)

gui_properties_set(p=None, tag=None)

Update the data displayed in a property list box.

Parses p (a dict or YAML string) into a flat list of label/control pairs and refreshes the list box stored under tag in the GUI task. Call this whenever the underlying data changes to redraw the panel.

Parameters:

Name Type Description Default
p dict | str

Property data as a Python dict or a YAML string. Dict keys become labels; values are Python expressions evaluated to produce the control widget. Nested dicts become collapsible sections. Defaults to None (clears the list).

None
tag str

Task inventory key holding the list box widget. Defaults to "__PROPS_LB__".

None
Example

gui_properties_set({"Speed": "gui_text(str(ship_speed))", "Shields": "gui_slider(shield_pct)"})

gui_property_list_box(name=None, tag=None, temp=_property_lb_item_template_one_line)

Create a property list box with single-line label/control layout.

Each property is rendered as a label on the left and its control widget on the right of the same row. Suitable for compact property panels. The widget is stored in the GUI task under tag so gui_properties_set can refresh it later.

Parameters:

Name Type Description Default
name str

Title shown in the list box header. Defaults to "Properties".

None
tag str

Task inventory key used to store and retrieve the list box widget. Defaults to "__PROPS_LB__".

None
temp callable

Item template function used to render each row. Defaults to the built-in one-line template.

_property_lb_item_template_one_line

Returns:

Name Type Description
LayoutListBox

The list box widget.

Example

gui_property_list_box("Navigation") gui_properties_set({"Heading": "gui_text(str(heading))", "Speed": "gui_text(str(speed))"})

gui_property_list_box_stacked(name=None, tag=None)

Create a property list box with two-line stacked label/control layout.

Each property is rendered as a label on one line and its control widget on the line below. Useful when controls are wide and need their own row. The widget is stored in the GUI task under tag so gui_properties_set can refresh it later.

Parameters:

Name Type Description Default
name str

Title shown in the list box header. Defaults to "Properties".

None
tag str

Task inventory key used to store and retrieve the list box widget. Defaults to "__PROPS_LB__".

None

Returns:

Name Type Description
LayoutListBox

The list box widget.

Example

gui_property_list_box_stacked("Ship Systems") gui_properties_set({"Warp Core": "gui_slider(warp_pct)"})

Cosmos consoles

gui_activate_console(console)

Set the current page's active console name.

Marks the page as running a specific console type, which affects which console-specific routes and widgets respond to this client.

Parameters:

Name Type Description Default
console str

Console name, e.g. "helm", "weapons", "science".

required
Example

gui_activate_console("helm")

gui_console(console, is_jump=False)

Activate a standard console with its default engine widget layout.

Sets the engine widget list for the named console using the built-in configuration. Supported values: "helm", "weapons", "science", "engineering", "comms", "cinematic", "mainscreen", "cockpit".

Parameters:

Name Type Description Default
console str

Console name (case-insensitive).

required
is_jump bool

For "helm" only — include jump-drive controls in the widget list. Defaults to False.

False
Example

gui_console("helm") gui_console("helm", is_jump=True)

gui_console_clients(path, for_ships=None)

Return the set of client IDs that have a specific console type.

Searches all player ships (or the given ship set) for linked console clients whose role matches console,{path}.

Parameters:

Name Type Description Default
path str

Console path to match, e.g. "helm" or "science".

required
for_ships object | None

Agent ID, object, or set of ships to search. Defaults to all __player__ ships.

None

Returns:

Name Type Description
set

Client IDs that have a console matching path.

Example

helm_clients = gui_console_clients("helm")

Console tabs:

The console tab system allows for creating a page tabbing system that allows the user to switch between pages quickly.

Tabs are defined with a //gui/tab label. This label defines what happens when that tab is press.

Example:

# Allow the debug tab to be shown
# at the top level
gui_tab_add_top("debug")

//gui/tab/debug
    jump show_debug_page

//gui/tab/brain
    jump show_brain_page

=== show_debug_page
    # Set the return page
    gui_tab_back(CONSOLE_SELECT)
    # Add the brain as a tab of the debug page
    gui_tab_enable("brain")
    # Set the back button to the last selected standard console
    # Rest of code to show page

=== show_brain_page
    # Set the back button to the last selected standard console
    gui_tab_back("debug")
    # Rest of code to show page

gui_tab_activate(tab_name)

Sets the back tab (left most) tab for the console tabs. This is general called automatically by //gui/tab and //console labels

Parameters:

Name Type Description Default
tab_name str

The path of a //gui/tab

required

gui_tab_add_top(tab_name)

Specify a tab by default to shown when the page is shown for standard consoles.

Parameters:

Name Type Description Default
tab_name str

A comma separated list of paths of a //gui//tab e.g. helm,weapons

required

gui_tab_back(tab_name)

Sets the back tab (left most) tab for the console tabs. The back tag is set by //gui/tab and //console labels This allows overriding

Parameters:

Name Type Description Default
tab_name str

The path of a //gui/tab

required

gui_tab_clear_top()

Specify a tab by default to shown when the page is shown for standard consoles.

Parameters:

Name Type Description Default
tab_name str

A comma separated list of paths of a //gui//tab e.g. helm,weapons

required

gui_tab_enable(tab_name)

Enable a tab on the console tabs

Parameters:

Name Type Description Default
tab_name str

A comma separated list of paths of a //gui//tab e.g. helm,weapons

required

gui_tab_get_active()

returns the active tab

Parameters:

Name Type Description Default
tab_name str

The path of a //gui/tab

required

gui_tab_is_top(tab_name)

Specify a tab by default to shown when the page is shown for standard consoles.

Parameters:

Name Type Description Default
tab_name str

A comma separated list of paths of a //gui//tab e.g. helm,weapons

required

gui_tab_remove_top(tab_name)

Specify a tab by default to shown when the page is shown for standard consoles.

Parameters:

Name Type Description Default
tab_name str

A comma separated list of paths of a //gui//tab e.g. helm,weapons

required

gui_add_console_type(path, display_name, description, label)

adds a tab definition

Parameters:

Name Type Description Default
id_or_obj agent

agent id or object

required
console str

Console name

required
tab_name str

Tab name

required
label label

Label to run when tab selected

required

gui_get_console_type(key)

Get the list of consoles defined by @console decorator labels

gui_get_console_type_list()

Get the list of consoles defined by @console decorator labels path is added as a value

gui_get_console_types()

Get the list of consoles defined by @console decorator labels

gui_remove_console_type(path, display_name, label)

adds a tab definition

Parameters:

Name Type Description Default
path str

Console path

required
display_name str

Display name

required
label label

Label to run when tab selected

required

gui_layout_widget(widget, style=None)

Place a specific engine widget at a fixed position in the layout.

Adds the named engine widget to the console widget list AND places a ConsoleWidget placeholder in the layout at the current position so the engine widget renders inside the defined area.

Parameters:

Name Type Description Default
widget str

Engine widget name, e.g. "2dview" or "helm_movement".

required
style str

Layout style for the PLACEHOLDER, as for any other widget - most usefully col-width. Defaults to None (the whole row).

None

DO NOT SHARE A ROW WITH MAST CONTROLS. The placeholder lays out correctly - measured: red_alert beside three checkboxes computes four clean quarters, and every rect is sent - but the ENGINE draws its widget at its own size, over the top of whatever MAST put beside it, so the controls simply vanish. Give an engine widget its own row (or its own section). col-width still shapes the rect the engine is GIVEN, which is worth having on its own; it just cannot stop the engine painting outside it.

Returns:

Name Type Description
ConsoleWidget

The layout placeholder item.

Example

gui_section(style="area:0,0,70,100;") gui_layout_widget("2dview")

sharing one row with a checkbox:

gui_checkbox("Follow", "col-width:90px;", var="follow_tag") gui_layout_widget("red_alert", "col-width:1fr;")

gui_update_widget_list(add_widgets=None, remove_widgets=None)

Add or remove widgets from the current client's active widget list.

Modifies the live widget list by taking the union of add_widgets and the current list, then subtracting remove_widgets. View widgets (2dview, 3dview, etc.) are always placed first.

Parameters:

Name Type Description Default
add_widgets str | None

^-separated widget names to add. Defaults to None (no additions).

None
remove_widgets str | None

^-separated widget names to remove. Defaults to None (no removals).

None
Example

gui_update_widget_list(add_widgets="shield_control", remove_widgets="radar_zoom_ctrl")

gui_update_widgets(add_widgets, remove_widgets)

Stage widget list changes on the pending widget list without sending.

Modifies page.pending_widgets rather than the live widget list. Changes are committed when the pending list is flushed to the engine.

Parameters:

Name Type Description Default
add_widgets str

^-separated widget names to add.

required
remove_widgets str

^-separated widget names to remove.

required
Example

gui_update_widgets("shield_control", "radar_zoom_ctrl")

gui_widget_list(console, widgets)

Set the engine console widget list for the current client.

Sends a widget list string directly to the engine, replacing the current widget layout. Widgets are ^-separated engine widget names.

Parameters:

Name Type Description Default
console str

Console type name, e.g. "normal_helm".

required
widgets str

^-separated list of engine widget names, e.g. "2dview^helm_movement^throttle".

required
Example

gui_widget_list("normal_helm", "2dview^helm_movement^throttle")

gui_widget_list_clear()

Clear all engine widgets from the current client's console.

Sends an empty widget list to the engine, removing all engine controls. The MAST GUI layout (sections, regions, etc.) is not affected.

Example

gui_widget_list_clear()

gui_widget_offscreen(widget, client_id=None)

Push an engine widget out of view.

The ONLY reliable way to be rid of an engine widget. It cannot be un-declared: the console's widget list is what the engine draws from, and the engine keeps what it has been given, so simply not asking for it is not always enough on a console that has already shown it. gui_hide() does even less - it clears _show on the layout placeholder while the engine carries on rendering.

So this does what gui_panel_widget_hide has always quietly done: sends the widget a rect at 100,100, off the visible area. Named, because "hide the waterfall" was attempted three different wrong ways before anyone found the one that works.

Parameters:

Name Type Description Default
widget str

engine widget name, e.g. "text_waterfall".

required
client_id int

defaults to the current client.

None

Tab panels

gui_info_panel(tab=0, tab_location=0, icon_size=0, var=None)

Create the standard info panel with a built-in ship-data tab.

Initialises a TabbedPanel pre-loaded with a "hide" tab (icon 121) and a "ship_data" tab (icon 140). Additional tabs can be appended with gui_info_panel_add. The panel object is stored in the GUI task under var so it can be retrieved and updated later.

Parameters:

Name Type Description Default
tab int

Initially active tab index. Defaults to 0.

0
tab_location int

Edge where tabs appear (0=left). Defaults to 0.

0
icon_size int

Icon size in pixels. Defaults to 0 (auto).

0
var str

Task variable name used to store the panel. Defaults to "__INFO_PANEL__".

None

Returns:

Name Type Description
TabbedPanel

The info panel layout object.

Example

tp = gui_info_panel() gui_info_panel_add("comms", 130, show_comms_tab)

gui_info_panel_add(path, icon_index, show, hide=None, tick=None, var=None)

Add a tab to an existing info panel.

If the panel is currently displayed, it is re-represented immediately.

Parameters:

Name Type Description Default
path str

Route name for this tab, used to switch to it programmatically.

required
icon_index int

Icon index displayed on the tab button.

required
show callable

show(cid, left, top, width, height) called when the tab becomes active.

required
hide callable

Called when the tab is deactivated. Defaults to None.

None
tick callable

Called each tick while the tab is active. Defaults to None.

None
var str

Task variable holding the panel (set by gui_info_panel). Defaults to "__INFO_PANEL__".

None

Returns:

Type Description

TabbedPanel | None: The panel, or None if not found.

Example

gui_info_panel_add("crew", 155, show_crew_tab, hide_crew_tab)

gui_info_panel_remove(path, var=None)

Remove a tab from an info panel by its path name.

If the panel is currently displayed and the tab was actually present, the panel is re-represented immediately.

Parameters:

Name Type Description Default
path str

Route name of the tab to remove (as passed to gui_info_panel_add).

required
var str

Task variable holding the panel. Defaults to "__INFO_PANEL__".

None

Returns:

Type Description

TabbedPanel | None: The panel, or None if not found.

Example

gui_info_panel_remove("crew")

gui_info_panel_send_message(client_id, message=None, message_color=None, path=None, title=None, title_color=None, banner=None, banner_color=None, face=None, icon_index=None, icon_color=None, button=None, history=True, time=-1, notify=None)

Send a message card to a client's info panel.

Every card is filed in the tab's log (readable any time on the log tab) unless history=False. A card only interrupts - taking over the panel's tab and auto-dismissing - when it needs an answer or the caller asks:

  • a card with a button ALWAYS interrupts. It is a progression gate: a mission awaiting the press deadlocks if the player never sees it.
  • otherwise pass notify=True to interrupt. The default is False: the card goes to the log and does not steal the tab, because the attention half of a notification belongs to an overlay now (see announce).

Parameters:

Name Type Description Default
client_id int | set

Client(s) to receive the message.

required
message str

Main body text.

None
message_color str

CSS color for the body text.

None
path str

Tab path to place the message in. Defaults to "message".

None
title str

Bold header line above the message.

None
title_color str

CSS color for the title.

None
banner str

Larger banner text shown above the title.

None
banner_color str

CSS color for the banner.

None
face str

Face/portrait key to display alongside the message.

None
icon_index int

Icon index to display alongside the message.

None
icon_color str

CSS color for the icon.

None
button str | list

Button label(s) to show. When set the function returns an awaitable Promise that resolves on button press.

None
history bool

File the card in the tab's log. Defaults to True.

True
time int

Auto-dismiss after this many seconds if no button is configured. Defaults to -1 (use panel default of 10 s).

-1
notify bool

Interrupt - show the card live and switch the panel to its tab. Defaults to None, meaning "only if it has a button". Pass True for a card that must be seen now.

None

Returns:

Type Description

Promise | None: Resolves when the button is pressed, or None if no button was specified.

Example

await gui_info_panel_send_message(CLIENT_ID, title="New Orders", message="Report to DS1 immediately.", face="captain")

gui_panel_ship_data_hide(cid, left, top, width, height)

Push ship data off screen when the tab is deactivated.

No longer moves text_waterfall with it - that widget is gone; see the note on gui_panel_ship_data_show.

gui_panel_ship_data_show(cid, left, top, width, height)

Ship data filling the panel.

It used to give the bottom four lines to text_waterfall and shrink ship_data to suit. That widget is gone (mkdocs build/messages.md) - it could not be styled from script - and positioning it here brought it BACK on any console showing this tab, whatever the console's widget list said. ship_data now gets the whole panel.

gui_tabbed_panel(items=None, style=None, tab=0, tab_location=0, icon_size=0)

Create a tabbed panel widget with icon-based tab navigation.

Each tab is defined by a dict with path, icon, show, and optionally hide and tick keys. The panel calls show when a tab is activated and hide when it is deactivated. Prefer gui_info_panel for the standard info panel; use this directly only when building a custom panel layout.

Parameters:

Name Type Description Default
items list[dict]

Tab descriptors. Each dict has: path (str) — route name for this tab; icon (int) — icon index displayed on the tab button; show (callable) — show(cid, left, top, width, height) called when the tab becomes active; hide (callable, optional) — called when the tab is hidden; tick (callable, optional) — called each tick while the tab is active. Defaults to None.

None
style str

CSS-like style string for the panel. Defaults to None.

None
tab int

Index of the initially active tab. Defaults to 0.

0
tab_location int

Edge where tabs appear (0=left). Defaults to 0.

0
icon_size int

Icon size in pixels. Defaults to 0 (auto).

0

Returns:

Name Type Description
TabbedPanel

The panel layout object.

Example

panels = [ {"path": "status", "icon": 140, "show": show_status, "hide": hide_status}, {"path": "map", "icon": 121, "show": show_map}, ] tp = gui_tabbed_panel(panels, tab=0)

Update and refreshing the GUI

gui_hide(layout_item)

Hide a visible layout item.

For sections, recalculates the layout after hiding. For individual items or rows, hides the element but does not re-layout — pair with gui_represent on the parent section if the layout needs updating.

Parameters:

Name Type Description Default
layout_item

The layout object to hide. No-op if already hidden or None.

required
Example

gui_hide(warning_row) gui_represent(my_section)

gui_rebuild(region)

Mark a section or region to rebuild its layout on the next present.

Clears the region's sub-layout so it is reconstructed from scratch the next time the region is rendered.

Parameters:

Name Type Description Default
region

A section or region layout item.

required

Returns:

Type Description

The same region object, for chaining.

Example

gui_rebuild(my_region) gui_represent(my_region)

gui_refresh(label)

Re-run an await gui() block at a given label on the current task.

Causes any scheduler running label to rebuild its GUI from scratch on the next tick.

Parameters:

Name Type Description Default
label

MAST label whose await gui() block should be refreshed. Pass None to refresh the current task's active label.

required
Example

gui_refresh(status_panel)

gui_represent(layout_item)

Redraw a layout item on the client screen.

For sections and regions, recalculates the entire sub-layout and redraws all children. For individual items or rows, redraws that element only.

Parameters:

Name Type Description Default
layout_item

The layout object to redraw.

required
Example

gui_represent(my_section)

gui_show(layout_item)

Make a hidden layout item visible.

For sections, recalculates the layout after showing. For individual items or rows, shows the element but does not re-layout — pair with gui_represent on the parent section if the layout needs updating.

Parameters:

Name Type Description Default
layout_item

The layout object to show. No-op if already visible or None.

required
Example

gui_show(warning_row) gui_represent(my_section)

gui_update(tag, props, shared=False, test=None)

Update the property string of an existing GUI element by tag.

Finds the element with the given tag on the current page (or all pages if shared=True) and updates its properties in-place without rebuilding the full layout.

The tag is a SCRIPT-SIDE name, not the string the engine knows the widget by. Set it with a tag: style (gui_text("hi", style="tag:status;")) and the page records it beside the engine's own tag, so naming a widget never disturbs the tag the engine, a listbox, or a click region depends on.

A name set inside a listbox item_template resolves too, but note two things: only rows that are currently ON SCREEN exist, so a tag naming a scrolled-away row finds nothing; and the name must be unique per row (put the item in it, e.g. f"tag:row-{item};") or only the last row drawn is reachable.

Parameters:

Name Type Description Default
tag str

The element name to find and update.

required
props str

New property string for the element, e.g. "$text:Firing!;color:red;".

required
shared bool

Apply the update to all client pages, not just the current one. Defaults to False.

False
test dict | None

Only apply the update when any variable in test has changed since the last update. Defaults to None (always update).

None

Returns:

Name Type Description
bool

True when a widget was found and updated. False is not an error --

an off-screen listbox row is the ordinary case -- but it lets a caller tell

a miss from a hit. Always False for shared=True, which fans out.

Example

gui_update(status_tag, "$text:OK;color:green;")

gui_update_shared(tag, props, test=None)

Update a GUI element by tag on all client pages.

Convenience wrapper for gui_update(tag, props, shared=True, test=test).

Parameters:

Name Type Description Default
tag str

The element tag to find and update.

required
props str

New property string for the element.

required
test dict | None

Only update when any variable in test has changed. Defaults to None.

None
Example

gui_update_shared(alert_tag, "$text:ALERT;color:red;")

gui_history_back()

Jump back to the previous navigation history entry.

Restores any variables stored with the entry and jumps to its label. No-op if there is no history.

Example
  • "Back" gui_history_back()

gui_history_clear()

Clear the navigation history for the current page.

Removes all back and forward history entries. Call this when entering a top-level screen where back-navigation should not be available.

Example

gui_history_clear()

gui_history_forward()

Jump forward to the next navigation history entry.

Restores any variables stored with the entry and jumps to its label. No-op if there is no forward history.

Example
  • "Forward" gui_history_forward()

gui_history_jump(to_label, back_name=None, back_label=None, back_data=None)

Jump to a new GUI label and record the current position in navigation history.

Appends the current position to the back-stack (clearing any forward history) then jumps to to_label. Call gui_history_back to return.

Parameters:

Name Type Description Default
to_label label

Label to navigate to.

required
back_name str | None

Display name for the back entry. Defaults to "BACK".

None
back_label label | None

Label to return to. Defaults to the currently active label.

None
back_data dict | None

Variables to restore when returning back. Defaults to None.

None

Returns:

Name Type Description
PollResults

Result of the jump.

Example

gui_history_jump(ship_detail_screen, back_name="Ship List")

gui_history_redirect(back_name=None, back_label=None, back_data=None)

Append to navigation history without jumping forward.

Adds a history entry so the current location can be returned to via gui_history_back, but does not change the active label. Use when you need to update the back-stack from within a label that was jumped to externally (e.g. from a route).

Parameters:

Name Type Description Default
back_name str | None

Display name for the history entry. Defaults to "BACK".

None
back_label label | None

Label to return to. Defaults to the currently active label.

None
back_data dict | None

Variables to restore when returning back. Defaults to None.

None

gui_history_store(back_text, back_label=None)

Record the current label as a history entry (back destination).

Stores the active label (or back_label) so that gui_history_back can return to it later. Use gui_history_jump instead when also navigating forward.

Parameters:

Name Type Description Default
back_text str

Display name for this history entry (shown in back buttons or breadcrumbs).

required
back_label label

Label to return to. Defaults to the currently active label.

None

gui_reroute_client(client_id, label, data=None)

Jump a specific client's GUI task to a new label immediately.

Finds the client's active page, optionally sets variables from data, then jumps the page's GUI task to label and ticks it in the current frame context.

Parameters:

Name Type Description Default
client_id int

The client to reroute.

required
label

MAST label to jump to.

required
data dict | None

Variables to set on the task before jumping. Defaults to None.

None
Example

gui_reroute_client(CLIENT_ID, briefing_screen)

gui_reroute_clients(label, data=None, exclude=None)

Jump all connected client GUI tasks to a new label.

Parameters:

Name Type Description Default
label

MAST label to jump to.

required
data dict | None

Variables to set on each task before jumping. Defaults to None.

None
exclude set | None

Set of client IDs to skip. Defaults to None (no exclusions).

None
Example

gui_reroute_clients(mission_end_screen, exclude={spectator_id})

gui_reroute_server(label, data=None)

Jump the server GUI task to a new label.

Parameters:

Name Type Description Default
label

MAST label to jump to.

required
data dict | None

Variables to set on the task before jumping. Defaults to None.

None
Example

gui_reroute_server(server_status_page)

page_gui_task_jump(page, label, activate_cmd=0, tick=False)

Queue a jump on a page's GUI task. The one place that does this.

Three callers steer a console's GUI task from outside it -- gui_task_jump, gui_reroute_client, and the await gui() promotion in gui.py (LM #714) -- and they used to each spell it out. They differ only in whether the jump runs in the CURRENT frame:

tick=False queue it; the next scheduler tick picks it up. tick=True run it now, under a FrameContextOverride, the way a repaint triggered by a click has to.

Returns True when the jump was queued.

Windows clipboard

gui_screenshot(image_path)

Capture the full desktop and save it as a BMP file.

Windows-only. Captures the entire desktop window (not just the Cosmos window) using GDI BitBlt. Useful for automated testing or recording mission state.

Parameters:

Name Type Description Default
image_path str

Absolute path to write the .bmp file.

required
Example

~~ gui_screenshot("C:/missions/debug/frame001.bmp") ~~

gui_clipboard_get()

Read the current text content of the Windows clipboard.

Windows-only. Returns None if the clipboard is empty or contains non-text data.

Returns:

Type Description

str | None: The clipboard text, or None if unavailable.

Example

text = gui_clipboard_get() if text is not None: gui_text("Pasted: {text}")

gui_clipboard_put(s)

Write a text string to the Windows clipboard.

Windows-only. Replaces whatever is currently on the clipboard. gui_clipboard_copy is an alias for this function.

Parameters:

Name Type Description Default
s str

The text to place on the clipboard.

required
Example

gui_clipboard_put("TSN Artemis — Mission Report")

Interacting with client side data

gui_request_client_string(client_id, key, timeout=None)

Request a text string from the player via a native OS input dialog.

Sends a request_client_string call to the engine for the given client. The engine shows an OS-level text input and returns the typed value as a client_string event. Suspends until the player submits or the timeout fires.

Parameters:

Name Type Description Default
client_id int

Client to prompt.

required
key str

Tag used to identify the response event (event.sub_tag).

required
timeout Promise

A promise that cancels the request if it resolves first. Defaults to None.

None

Returns:

Name Type Description
Promise

Resolves with the typed string as its result.

Example

result = await gui_request_client_string(CLIENT_ID, "ship_name") ~~ player_name = result.result ~~