Skip to content

The query module

Resolve and convert agent IDs, objects, and collections between formats.

Overview

All procedural API functions accept agents in multiple forms — raw integer IDs, Agent objects, CloseData (returned by closest), or SpawnData (returned by spawn calls). The query module provides the conversion functions that make this work.

The most commonly used functions:

  • to_id — extract an integer ID from anything.
  • to_object — resolve to an Agent object (returns None if destroyed).
  • to_agent_list — resolve a collection for a write, the server console included.
  • to_set — normalise any collection into a set[int] of IDs.
  • to_list — normalise any collection into a list.
  • object_exists — check if an object is still alive in the simulation.

The is_* functions test which ID category a value belongs to. This matters because clients, space objects, grid objects, and tasks all share the same ID space but use different high bits.

Quick example

== check_target ==
    enemy_id = to_id(closest_enemy)
    obj = to_object(enemy_id)
    if object_exists(enemy_id): target(ship_id, enemy_id)
from sbs_utils.procedural.query import (
    to_id, to_object, to_set, object_exists,
    is_space_object_id, is_client_id,
    get_comms_selection, set_science_selection,
)

enemy_id = to_id(spawn_data_or_agent_or_int)
obj = to_object(enemy_id)

if object_exists(enemy_id):
    target(ship_id, enemy_id)

comms_target = get_comms_selection(ship_id)
set_science_selection(ship_id, enemy_id)

ID type detection

Function True when
is_space_object_id(id) NPC, player ship, station, nebula, etc.
is_grid_object_id(id) Engineering-grid object
is_client_id(id) Player console / client
is_task_id(id) MAST task
is_story_id(id) Story agent (e.g. Fleets)

The two meanings of id 0

Id 0 is the server — its console, and the agent a mission hangs mission-wide state on. It is also the value a script uses to mean "no object". Both readings are correct, and which one applies is decided by what the caller does with the answer, not by the value:

id 0 resolves to Because
to_object / to_object_list None For a space object, 0 means "no target". ->END if to_object(target_id) is None is everywhere in MAST, and it has to keep working.
to_agent_list, to_client_object the server's agent A write has to be able to reach the server console.

So the state functions all take 0 to mean the server:

add_role(0, "console, mainscreen")
set_inventory_value(0, "CONSOLE_TYPE", "mainscreen")
set_timer(0, "mission_clock", minutes=20)
start_counter(0, "Mission_Elapsed_Time")
link(0, "watching", ship_id)

while to_object(0) stays None so an unset target id still reads as "nothing there".

Writers use to_agent_list

If you add a function that resolves a collection in order to write to it, resolve with to_agent_list, not to_object_list — otherwise it silently skips the server and the failure looks like "the feature just doesn't work on the server window". to_object_list is for space-object queries, where dropping 0 is the point.

Engine data-set (blob)

Space and grid objects have an engine-level data blob for engine-readable attributes (e.g. dock_state, system_damage). Use to_blob / to_data_set to get the blob, then call .get(key) / .set(key, value, index):

blob = to_blob(ship_id)
damage = blob.get("system_damage", 0)  # index defaults to 0
blob.set("dock_state", "docked", 0)

API

all_objects_exists(the_set)

Return whether every object in a collection exists in the simulation.

Parameters:

Name Type Description Default
the_set Agent | int | set[Agent | int] | list[Agent | int]

One or more agent IDs or objects.

required

Returns:

Name Type Description
bool

True if all objects exist; False if any is missing.

are_variables_defined(keys)

Return whether all named variables are defined in the current MAST task.

Parameters:

Name Type Description Default
keys str

Comma-separated variable names to check.

required

Returns:

Name Type Description
bool

True if every key is defined in the current task scope.

clear_data_set_value(id_or_obj, key)

Clear every index of a data-set (blob) key, on the server AND on every client.

data_set.clear_data(key) clears only the server's copy; the engine does not replicate it, so clients keep the old entries. This also calls sbs.clear_object_data_set_value_on_clients, which takes the host ship's id and the grid object's id - 0 for a space object - so a grid object is resolved to its host. Use this instead of calling clear_data directly.

Parameters:

Name Type Description Default
id_or_obj Agent | int

A space or grid object.

required
key str

The data-set key to clear.

required

dec_disable_client_selection(client_id, console_selected_UID)

Reverse an :func:inc_disable_client_selection call.

Parameters:

Name Type Description Default
client_id Agent | int

The console (client) to restore.

required
console_selected_UID str

The blob key for the console.

required

dec_disable_selection(id_or_obj, console_selected_UID)

Decrement the disable-count for a console selection.

Reverses an inc_disable_selection call. When the counter reaches zero the console is no longer suppressed.

Parameters:

Name Type Description Default
id_or_obj Agent | int

The player ship agent ID or object.

required
console_selected_UID str

The blob key for the console (e.g. "weapon_target_UID").

required

get_comms_selection(id_or_not)

Return the ID of the object currently selected on the comms console.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required

Returns:

Type Description

int | None: The selected agent ID, or None if unavailable.

get_crew(id_or_obj)

Get the crew string of a space object (defaults to the side from shipData).

Parameters:

Name Type Description Default
id_or_obj Agent | int

Agent ID or object.

required

Returns:

Name Type Description
str

The crew string, or "" if the object does not exist.

get_data_set_value(id_or_obj, key, index=0, default=None)

Get a value from the engine data-set (blob) of a space or grid object.

Parameters:

Name Type Description Default
id_or_obj Agent | int

The agent ID or object.

required
key str

The data-set key.

required
index int

The slot index within that key. Defaults to 0. This is an INDEX, not a fallback - the third positional argument is which slot to read (shield 0 vs shield 1), and passing a "default" there reads the wrong slot or fails outright.

0
default any

what to return when the field has never been set. The engine answers None for such a field, and a mission that then compares it (if fuel < 1000) raises on a real bridge while running clean against the mock's typed defaults - the bug behind LM's Florbin cargo-hold watcher and an earlier helm crash. Pass default=0 (or default="") and the caller gets something it can use. sbs lint flags the unguarded shape as blob-unguarded-none.

None

Returns:

Name Type Description
any

The stored value, default if the object or key is not found.

get_engine_data_set(id_or_obj)

Return the engine data-set (blob) for an agent.

Parameters:

Name Type Description Default
id_or_obj Agent | int | SpawnData

Agent ID, object, or SpawnData.

required

Returns:

Type Description

data_set | None: The engine data-set, or None if not found.

get_grid_selection(id_or_not)

Return the ID of the object currently selected on the engineering grid console.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required

Returns:

Type Description

int | None: The selected agent ID, or None if unavailable.

get_origin(id_or_obj)

Get the origin string of a space object (defaults to the side from shipData).

Parameters:

Name Type Description Default
id_or_obj Agent | int

Agent ID or object.

required

Returns:

Name Type Description
str

The origin string, or "" if the object does not exist.

get_race(id_or_obj)

Return the race string of a space object (defaults to side from shipData).

Parameters:

Name Type Description Default
id_or_obj Agent | int

Agent ID or object.

required

Returns:

Name Type Description
str

The race string, or "" if the object does not exist.

get_science_selection(id_or_not)

Return the ID of the object currently selected on the science console.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required

Returns:

Type Description

int | None: The selected agent ID, or None if unavailable.

get_side(id_or_obj)

Return the side string of an agent.

Parameters:

Name Type Description Default
id_or_obj Agent | int

Agent ID or object.

required

Returns:

Name Type Description
str

The side string, or "" if the object does not exist.

get_side_display(id_or_obj)

Return the display name of an agent's side.

Parameters:

Name Type Description Default
id_or_obj Agent | int

Agent ID or object.

required

Returns:

Name Type Description
str

The side display string, or "" if the object does not exist.

get_weapons_selection(id_or_not)

Return the ID of the object currently selected on the weapons console.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required

Returns:

Type Description

int | None: The selected agent ID, or None if unavailable.

inc_disable_client_selection(client_id, console_selected_UID)

Make ONE console take no part in a selection, without affecting the others.

The selection itself lives on the SHIP, so inc_disable_selection is all-or-nothing for every console looking at that ship: disable it so a second, display-only view cannot click and the console that is meant to be driving stops selecting too. This is the per-console form: the shared value is left exactly as it was, which is what a read-only second view of an interior needs.

It RESTORES rather than refuses, because refusing is too late. The ENGINE writes the ship's selection into the blob before the event reaches the script - measured by instrumenting do_select in a real run, where the blob already held the new value on entry - so declining to write leaves the engine's change standing. The dispatcher puts back approved_<console>, the last selection the library allowed.

KNOWN LIMITATION: this does not fully hold for a ship's INTERIOR view. On a real console a display-only second view still moves the grid highlight - the engine owns that selection and the write-back does not stick. Gate //point/grid on the client's role as well, which is what actually stops a display console driving anybody. The other surfaces are untested in the engine.

Pair with :func:dec_disable_client_selection; the count nests.

Parameters:

Name Type Description Default
client_id Agent | int

The console (client) that must not select.

required
console_selected_UID str

The blob key for the console (e.g. "grid_selected_UID").

required

inc_disable_selection(id_or_obj, console_selected_UID)

Increment the disable-count for a console selection and clear it.

Increments an internal counter tracking how many callers have suppressed the selection for this console, then zeroes the console's selected UID in the blob so the console has no active target.

Parameters:

Name Type Description Default
id_or_obj Agent | int

The player ship agent ID or object.

required
console_selected_UID str

The blob key for the console (e.g. "weapon_target_UID").

required

is_alt_ship_target(id)

Return whether an ID is safe to hand to assign_client_to_alt_ship.

0 means "clear the focus" and is always allowed. Anything else must be a SPACE-object id. A Fleet, side, task or grid id is script-only - the engine never created it - and pointing a console at one crashes the client: measured 5 runs out of 5 as either a modal vertexIndex < numVerts assert out of DX11PAXVertList.cpp or an access violation reading off the end of a vertex list. The engine takes the id as a ship, indexes a mesh it does not have, and reads whatever is there.

A dead-but-well-formed space id is deliberately still allowed: the engine handles a deleted ship cleanly (measured), and rejecting it here would drop legitimate focus changes on a target that is merely mid-teardown. This guards the class the engine cannot survive, not staleness. object_exists already applies the same reasoning before calling space_object_exists.

Parameters:

Name Type Description Default
id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the id is 0 or a space-object id.

is_client_id(id)

Return whether an ID belongs to a client (player console) agent.

Parameters:

Name Type Description Default
id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the client-console bit (0x8000…) is set.

is_grid_object_id(id)

Return whether an ID belongs to an engineering-grid object.

Parameters:

Name Type Description Default
id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the grid-object bit (0x2000…) is set.

is_space_object_id(id)

Return whether an ID belongs to a space object.

Parameters:

Name Type Description Default
id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the space-object bit (0x4000…) is set.

is_story_id(id)

Return whether an ID belongs to a story agent (not an engine object, e.g. Fleets).

Parameters:

Name Type Description Default
id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the ID has the story-object bit set.

is_task_id(id)

Return whether an ID belongs to a MAST task.

Parameters:

Name Type Description Default
id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the task-id bit (0x0080…) is set.

object_exists(so_id)

Return whether an object currently exists in the simulation.

Parameters:

Name Type Description Default
so_id Agent | int

Agent ID or object.

required

Returns:

Name Type Description
bool

True if the engine reports the object present.

random_id(the_set)

Return the ID of a randomly chosen element from a collection.

Parameters:

Name Type Description Default
the_set set[Agent | int]

A set or list of agent IDs or objects.

required

Returns:

Type Description

int | None: A random agent ID, or None if the collection is empty.

random_object(the_set)

Return a randomly chosen agent object from a collection.

Parameters:

Name Type Description Default
the_set set[Agent | int]

A set or list of agent IDs or objects.

required

Returns:

Type Description

Agent | None: A random agent, or None if the collection is empty.

random_object_list(the_set, count=1)

Return a list of randomly chosen agent objects from a collection.

Parameters:

Name Type Description Default
the_set set[Agent | int]

A set or list of agent IDs or objects.

required
count int

Number of objects to pick. Defaults to 1.

1

Returns:

Type Description

list[Agent]: Randomly selected agents (may contain duplicates).

safe_int(s, defa=0)

Convert a value to an integer, returning a default on failure.

Accepts strings (GUI typeins / loaded game codes arrive as strings) as well as values that are already int/float - a GUI property can be either depending on whether it was typed, defaulted, or loaded from settings, so callers must not assume a string. Non-numeric input yields defa.

A prefixed literal is also accepted: "0x1F" -> 31 (and 0o/0b). Decimal is tried first so leading-zero decimals still parse as base 10 ("007" -> 7). Bare hex without the 0x prefix is intentionally NOT accepted - "42" is valid hex too, so it would silently reinterpret ordinary decimal input.

Parameters:

Name Type Description Default
s str | int | float | any

The value to convert.

required
defa int

Value returned if s is not a valid integer. Defaults to 0.

0

Returns:

Name Type Description
int

The converted integer, or defa.

set_comms_selection(id_or_not, other_id_or_obj)

Set the selected object on the comms console of a player ship.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required
other_id_or_obj Agent | int

The object to select.

required

set_console_selection(id_or_not, other_id_or_obj, console)

Set the selected object for a named console on a player ship.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required
other_id_or_obj Agent | int

The object to select, or 0 to clear.

required
console str

The blob key for the console (e.g. "comms_target_UID").

required

set_data_set_value(to_update, key, value, index=0)

Set a value in the engine data-set (blob) for one or more space or grid objects.

If to_update is a set or list, the value is applied to each member.

Parameters:

Name Type Description Default
to_update Agent | int | set[Agent | int] | list[Agent | int]

The agent(s) to update.

required
key str

The data-set key.

required
value any

The value to store.

required
index int

The slot index within that key. Defaults to 0.

0

set_grid_selection(id_or_not, other_id_or_obj)

Set the selected object on the engineering grid console of a player ship.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required
other_id_or_obj Agent | int

The object to select.

required

set_science_selection(id_or_not, other_id_or_obj)

Set the selected object on the science console of a player ship.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required
other_id_or_obj Agent | int

The object to select.

required

set_weapons_selection(id_or_not, other_id_or_obj)

Set the selected object on the weapons console of a player ship.

Parameters:

Name Type Description Default
id_or_not Agent | int

The player ship agent ID or object.

required
other_id_or_obj Agent | int

The object to select.

required

to_agent_list(the_set)

Resolve to Agent objects for a WRITE, the SERVER CONSOLE included.

to_object refuses id 0 by design - 0 means "no object" for a space object - so every write built on :func:to_object_list silently skipped the server console. That is not a corner case: the server window is a console like any other, and add_role(client_id, "console, mainscreen") on it was a no-op, which is why an overlay narrowed with consoles="mainscreen" never reached the main screen when the main screen WAS the server.

The reads already knew better - get_inventory_value has carried an explicit Agent.get(0) branch for exactly this. This is that branch generalized, so a write can reach everything a read can see.

Space-object callers keep using to_object_list: id 0 there really does mean "no object", and this must not resurrect it for them.

Parameters:

Name Type Description Default
the_set set[Agent | int] | list[Agent | int] | Agent | int

what to resolve.

required

Returns:

Type Description

list[Agent]: resolved agents; unresolvable entries are dropped.

to_blob(id_or_obj)

Return the engine data-set (blob) for an agent. Same as to_data_set.

Parameters:

Name Type Description Default
id_or_obj Agent | int | SpawnData

Agent ID or object.

required

Returns:

Type Description

data_set | None: The engine data-set, or None if the object does not exist.

to_client_object(other)

Resolve a client/console ID or Agent to its Agent object.

Returns None when the ID is not a valid client ID or the agent no longer exists.

Parameters:

Name Type Description Default
other Agent | int

Client ID or agent to resolve.

required

Returns:

Type Description

Agent | None: The client agent, or None.

to_data_set(id_or_obj)

Return the engine data-set (blob) for an agent. Same as to_blob.

Parameters:

Name Type Description Default
id_or_obj Agent | int | SpawnData

Agent ID or object.

required

Returns:

Type Description

data_set | None: The engine data-set, or None if the object does not exist.

to_engine_object(id_or_obj)

Return the C++ engine-object pointer for an agent.

Parameters:

Name Type Description Default
id_or_obj Agent | int

Agent ID or object.

required

Returns:

Type Description

pointer | None: The underlying C++ engine-object, or None if the agent does not exist.

to_grid_object(other)

Resolve an ID or Agent to a GridObject agent.

Returns None when the ID is not a grid-object ID or the object no longer exists.

Parameters:

Name Type Description Default
other Agent | CloseData | int

ID or agent to resolve.

required

Returns:

Type Description

Agent | None: The grid-object agent, or None.

to_id(other)

Extract the integer ID from an agent, CloseData, SpawnData, or bare int.

Parameters:

Name Type Description Default
other Agent | CloseData | SpawnData | int

Value to convert.

required

Returns:

Name Type Description
int

The integer agent ID.

to_id_list(the_set)

Convert a set or list of agents/IDs to a list of integer IDs.

Parameters:

Name Type Description Default
the_set set[Agent | int] | list[Agent | int]

IDs or agent objects.

required

Returns:

Type Description

list[int]: Resolved integer IDs; unresolvable items are excluded.

to_list(other)

Normalize any agent-like value or collection into a list.

Parameters:

Name Type Description Default
other Agent | CloseData | int | set | list | None

Value to normalize.

required

Returns:

Name Type Description
list

A list containing whatever was passed in; None becomes [].

to_object(other)

Resolve an ID, CloseData, or SpawnData to its Agent object.

Returns None when the agent no longer exists.

Parameters:

Name Type Description Default
other Agent | CloseData | SpawnData | int

Value to resolve.

required

Returns:

Type Description

Agent | None: The agent, or None if it could not be resolved.

to_object_list(the_set)

Convert a set or list of IDs/agents to a list of Agent objects (excluding None).

Parameters:

Name Type Description Default
the_set set[Agent | int] | list[Agent | int]

IDs or agent objects.

required

Returns:

Type Description

list[Agent]: Resolved Agent objects; items that cannot be resolved are excluded.

to_py_object_list(the_set)

Convert a set of raw agent IDs to a list of Agent objects.

The odd one out of the list resolvers, and kept that way for compatibility:

  • IDs only. It indexes Agent.all directly, so an Agent / CloseData / SpawnData in the set resolves to None, not to itself.
  • None is kept, not dropped, so positions line up with the input - every other list resolver filters instead.
  • No liveness check, so a deleted agent's id yields None (it is out of Agent.all) while a stale Agent object yields None too, for the other reason.
  • id 0 resolves to the SERVER console, as Agent.get always has.

Prefer :func:to_object_list (space objects, drops what it cannot resolve) or :func:to_agent_list (the write side, keeps the server). See the resolver table in :func:to_object_list.

Parameters:

Name Type Description Default
the_set set[int]

A set of agent IDs.

required

Returns:

Type Description

list[Agent | None]: Agents resolved from the set, None where an id is not in Agent.all.

to_set(other)

Normalize any agent-like value or collection into a set of integer IDs.

Parameters:

Name Type Description Default
other Agent | CloseData | int | set | list | None

Value to normalize.

required

Returns:

Type Description

set[int]: A set of integer IDs; None becomes an empty set.

to_space_object(other)

Resolve an ID or Agent to a SpaceObject agent (NPC, player, or terrain).

Returns None when the ID is not a space-object ID or the object no longer exists.

Parameters:

Name Type Description Default
other Agent | CloseData | int

ID or agent to resolve.

required

Returns:

Type Description

Agent | None: The space-object agent, or None.

to_space_object_list(the_set)

Convert a set or list of IDs/agents to a list of SpaceObject agents (excluding None).

Parameters:

Name Type Description Default
the_set set[Agent | int] | list[Agent | int]

IDs or agent objects.

required

Returns:

Type Description

list[Agent]: Space-object agents only; grid/client IDs are excluded.