Grid object system
Query, move, and theme engineering-grid objects on player ships.
Overview
Engineering-grid objects are the nodes visible on the damage-control console: system rooms (weapon, engine, sensor, shield), hallways, damcon-team crew, markers, and tools. Each is an Agent with a host ship ID and a position in a 2D grid coordinate space.
Common tasks:
grid_objects(ship_id)— get the set of all grid-object IDs on a ship. Combine withrole()to filter by type:grid_objects(ship_id) & role("engine").grid_objects_at(ship_id, x, y)— get objects at a specific cell.grid_closest(id, candidates)— find the nearest grid object to another.grid_move(id, x, y)— path the grid object to a target cell.grid_pos_data(id)— get current(x, y, path_length)of a moving object.
The theme system controls icon appearance. grid_get_grid_theme and grid_get_item_theme_data look up icon indices, colors, and damage colors by role, falling back to "default" entries.
Quick example
== repair_run ==
damaged = grid_objects(ship_id) & role("__damaged__")
if len(damaged) == 0: jump done
target_go = to_object(next(iter(damaged)))
x, y, _ = grid_pos_data(target_go.id)
grid_move(damcon_id, int(x), int(y))
from sbs_utils.procedural.grid import (
grid_objects, grid_objects_at, grid_closest,
grid_move, grid_pos_data, grid_get_grid_theme,
)
from sbs_utils.procedural.roles import role
damaged_engines = grid_objects(ship_id) & role("__damaged__") & role("engine")
grid_move(damcon_id, target_x, target_y)
curx, cury, path_len = grid_pos_data(damcon_id)
Grid roles
| Role | Objects |
|---|---|
"weapon" |
Weapon system nodes |
"engine" |
Engine system nodes |
"sensor" |
Sensor system nodes |
"shield" |
Shield system nodes |
"damcons" / "lifeform" |
Damcon crew members |
"marker" |
Position marker |
"rally_point" |
Damcon idle point |
"hallway" |
Damage-fire hallway markers |
"__undamaged__" / "__damaged__" |
Damage state |
API
get_open_grid_points(id_or_obj)
Gets a list of open grid locations
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
agent
|
agent id or object to check |
required |
Returns:
| Name | Type | Description |
|---|---|---|
set |
set[Vec3]
|
a set of Vec3 with x and y set |
grid_clear_detailed_status(id_or_obj)
Clear the detailed status (info text) of a grid object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
Agent ID or object. |
required |
grid_clear_speech_bubble(id_or_obj)
Clear the speech bubble for a grid object
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
agent id or object of the grid object |
required |
grid_clear_target(grid_obj_or_set)
Clear the movement target of a grid object, stopping it in place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_obj_or_set
|
Agent | int | set
|
Agent, ID, or set of grid object(s) to stop. |
required |
grid_close_list(grid_obj, the_set, max_dist=None, filter_func=None)
Find and target the closest object matching the criteria
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_obj
|
Agent | int
|
The agent or id |
required |
the_set
|
set[Agent]
|
The items to test. Defaults to None. |
required |
max_dist
|
float
|
max distance. Defaults to None. |
None
|
filter_func
|
Callable
|
additional filer function. Defaults to None. |
None
|
Returns:
| Type | Description |
|---|---|
list[CloseData]
|
list[CloseData]: The gird close data of the closest objects |
grid_closest(grid_obj, target_set=None, max_dist=None, filter_func=None)
Find and target the closest object matching the criteria
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_obj
|
Agent | int
|
The agent or id |
required |
target_set
|
set[Agent]
|
The items to test. Defaults to None. |
None
|
max_dist
|
float
|
max distance. Defaults to None. |
None
|
filter_func
|
Callable
|
additional filer function. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
CloseData |
CloseData
|
The gird close data of the closest object |
grid_data_is_loaded()
Reset-ledger probe: 1 while grid data (possibly mod-merged) is held, else 0.
grid_delete_object(host_id_or_obj, id_or_obj)
Delete a single grid object, deferring the native free.
Tombstones the grid agent now (dropped from Agent.all/roles, so
object_exists()/to_object() report it gone this instant) and enqueues
the native sbs.delete_grid_object(host_id, id) to run at the end of the
event handler. Mirrors SpaceObject.delete_object for grid objects, closing
the same-tick use-after-free window. See DeleteQueue.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
host_id_or_obj
|
Agent | int
|
The host ship the grid object lives on. |
required |
id_or_obj
|
Agent | int
|
The grid object (or its id) to delete. |
required |
grid_delete_objects(ship_id_or_obj)
Delete all grid objects belonging to a ship.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ship_id_or_obj
|
Agent | int
|
Agent or ID of the ship whose grid objects should be removed. |
required |
grid_detailed_status(id_or_obj, status, color=None)
Set the detailed status (info text) of a grid object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
Agent ID or object. |
required |
status
|
str
|
Status string to display. |
required |
color
|
str
|
Text color. |
None
|
grid_get_damcons(ship_key, layout=None)
The damcon-team declaration for a hull (or one of its layouts), or None.
None - which is what every hull that says nothing returns, and that is nearly all
of them - means "three teams, wherever the engine puts them", exactly as before. That
sentinel is what keeps the shipped floor plans and every third-party hull working
unchanged.
Otherwise {"count": int, "posts": [[x, y], ...]}: how many damage-control teams
this interior has, and where they are stationed. Fewer posts than teams is fine - the
rest are engine-placed. A post is also the team's permanent rally point, because the
prefab spawns the rally marker on the cell it is given, so posting a team by the
nacelles is all it takes to keep it there.
Read as a sibling of grid_objects/theme, at the entry level or inside a named
layout, most specific winning - the same shape :func:grid_get_theme_name uses. A
layout expressed as a bare list has nowhere to hold one and falls back to the entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ship_key
|
str
|
Ship key as defined in shipData. |
required |
layout
|
str
|
Layout name. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
|
dict | None: Normalized declaration, or |
grid_get_grid_current_theme()
Get the currently active grid theme data.
Returns:
| Name | Type | Description |
|---|---|---|
dict |
Theme dict with keys such as |
grid_get_grid_data()
Get the grid data from all the grid_data.json files
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
a dictionary of grid data objects. |
dict
|
|
|
dict
|
|
grid_get_grid_named_theme(name)
Get a grid theme by name, falling back to the current theme if not found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str | None
|
Theme name to look up (case-insensitive), or
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
dict |
Theme dict with keys such as |
grid_get_grid_theme()
Get the grid data from all the grid_data.json files
Returns:
| Name | Type | Description |
|---|---|---|
dict |
a dictionary of grid theme data |
|
|
||
|
grid_get_item_theme_data(roles, name=None)
Get icon, scale, color, and damage color for a set of roles from the grid theme.
Roles are matched in reverse priority order so the last role in the list
takes precedence. Falls back to "default" entries when no role matches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
roles
|
str
|
Comma-separated role names. |
required |
name
|
str | None
|
Theme name to use. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
RetVal |
Object with |
grid_get_layout(ship_key, layout=None)
The grid-object list for one hull's layout.
A hull has N named LAYOUTS, not one interior - a full authored interior, a cheap
systems-only one, a jump-drive refit of the same hull. grid_objects at the top
level is still read as the default, so every existing entry keeps working::
{"tsn_light_cruiser": {"grid_objects": [...]}} # still valid
{"pirate_brigantine": {"layouts": {"default": {...},
"systems": {...}}}}
A layout may be either {"grid_objects": [...]} or a bare list.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ship_key
|
str
|
Ship key as defined in shipData. |
required |
layout
|
str
|
Layout name. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
|
list | None: The grid object dicts, or |
grid_get_mod(ship_key)
The mod that supplied a hull's interior, or None for built-in data.
grid_get_theme_name(ship_key, layout=None)
The theme a hull (or one of its layouts) asks for, or None for the current one.
Theme selection used to be a single module-level index - a whole-game setting - which made per-race themes impossible. A hull, or a single layout of it, can now name its own: a captured TSN hull refitted by pirates is the same mesh with a different interior AND a different vocabulary.
grid_merge_ascii(content, mod=None, ship_key=None)
Merge one ASCII floor plan (see :mod:grid_ascii) into the grid data.
The one-line form an addon's __init__.mast uses::
grid_merge_ascii(media_read_relative_file("tsn_light_cruiser.grid"), "interiors_tsn")
A plan naming a layout: other than default is merged INTO the hull's existing
entry as a named layout rather than replacing it, so a hull's variants can arrive from
separate files - and, later, from separate mods.
Returns the entry that was merged, or None if the text could not be read (which is
logged, not raised: one unreadable floor plan should not take a mission down).
grid_merge_mod_data(content, mod=None)
Merge grid data supplied as a JSON/YAML string into the grid data cache.
The counterpart of :func:sbs_utils.procedural.ship_data.merge_mod_ship_yaml, and the
one change that lets an ADDON ship ship interiors. grid_get_grid_data reads only
two places - the engine's grid_data.json and the mission directory's
extra_grid_data.json - so an addon inside a .mastlib could not contribute at
all. Pair it with media_read_relative_file, which reads from the addon's zip when
it is packaged and from its folder in dev::
grid_merge_mod_data(media_read_relative_file("extra_grid_data.json"), "PirateMod")
Unlike ship data, this needs no build step: grid objects are not engine content -
grid_rebuild_grid_objects creates every one at runtime through grid_spawn - so
the engine never has to pre-know an interior. See SHIP_MOD_PLAN.md s3.
Merging is whole-entry replace, matching the |= the mission file has always
used: a mod supplies a hull's whole interior and cannot add a room to someone else's.
Layout variants are how one hull legitimately has more than one interior.
Two mods claiming the same hull is reported by name. It is a warning rather than an error because failing here would take down a mission at load over a cosmetic clash, but silent last-writer-wins is how interiors start feeling haunted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
str
|
JSON or YAML text (YAML is a JSON superset, so both parse). |
required |
mod
|
str
|
Name of the mod these entries come from; stamped on each
entry as |
None
|
Returns:
| Type | Description |
|---|---|
|
dict | None: The updated grid data, or |
grid_merge_mod_theme(content)
Append themes supplied as a JSON/YAML string, so an addon can ship its own.
Companion to :func:grid_merge_mod_data; same reason it exists - the built-in reader
only looks in the engine data dir and the mission dir, so a .mastlib addon had no
way in. A race mod's room VOCABULARY lives here: new room names need theme icon
entries or they fall back to the generic icon 120.
A theme with a name that already exists REPLACES it, so a mod can re-skin a built-in theme rather than only adding beside it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
str
|
JSON or YAML text - one theme dict, or a list of them. |
required |
Returns:
| Type | Description |
|---|---|
|
list | None: The updated theme list, or |
grid_object_valid(id_or_obj)
Return whether a grid object still has a valid backing space object.
Returns False once the host ship is destroyed, even though the grid
object's Agent may still resolve. See :func:grid_valid_blob.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
Agent id or object. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
|
grid_objects(so_id)
Get a set of agent ids of the grid objects on the specified ship
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
so_id
|
Agent | int
|
agent id or object |
required |
Returns:
| Type | Description |
|---|---|
set[int]
|
set[int]: a set of agent ids |
grid_objects_at(so_id, x, y)
Get a set of agent ids of the grid objects on the specified ship, at the location specified
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
so_id
|
Agent | int
|
agent id or object |
required |
x
|
int
|
The x grid location |
required |
y
|
int
|
The y grid location |
required |
Returns:
| Type | Description |
|---|---|
set[int]
|
set[int]: A set of agent ids |
grid_pos_data(id)
Return the current position and path length of a grid object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id
|
Agent | int
|
Agent ID or object. |
required |
Returns:
| Type | Description |
|---|---|
|
tuple[float, float, float]: |
grid_remove_move_role(event)
Remove the _moving_ role when a grid object finishes its path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
Engine event; only acts when |
required |
grid_reset_caches()
Drop the loaded grid data and themes at a mission boundary.
_grid_data merges the mission's extra_grid_data.json (and, once mods can
contribute, every enabled mod's interiors) into the base table, and _grid_theme
does the same for themes - so both are PER-MISSION state wearing the clothes of a
module-level cache. Left alone, the next mission inherits the previous one's
interiors and its theme index.
The engine forks a fresh process per mission and hides this; cosmos_dev reuses
one interpreter and does not. Registered in the reset ledger.
grid_set_grid_current_theme(i)
Set the active grid theme by index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
i
|
int
|
Index into the loaded grid theme list. |
required |
grid_set_grid_named_theme(name)
Set the active grid theme by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Theme name (case-insensitive), e.g. |
required |
grid_short_status(id_or_obj, status, color=None, seconds=0, minutes=0)
Set the tooltip and speech bubble text of a grid object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
Agent ID or object. |
required |
status
|
str
|
Status string for both the tooltip and speech bubble. |
required |
color
|
str
|
Text color. |
None
|
seconds
|
int
|
Duration for the speech bubble. Defaults to 0 (permanent). |
0
|
minutes
|
int
|
Additional minutes for the bubble duration. Defaults to 0. |
0
|
grid_speech_bubble(id_or_obj, status, color=None, seconds=0, minutes=0)
Sets the speech bubble text of a grid object. The text will disappear if the seconds/minutes are set
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
Agent id or object |
required |
status
|
str
|
The detailed status string |
required |
color
|
str
|
change the color of the detailed status text. None does not change the current value |
None
|
seconds
|
int
|
The seconds for the speech bubble |
0
|
minutes
|
(int): The minutes for the speech bubble |
0
|
grid_target(grid_obj_or_set, target_id, speed=0.01)
Set a grid object to target the location of another grid object
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_obj_or_set
|
Agent | int | set[Agent | int]
|
an id, object or set of agent(s) |
required |
target_id
|
Agent
|
an agent id or object |
required |
speed
|
float
|
the speed to move. Defaults to 0.01. |
0.01
|
grid_target_closest(grid_obj_or_set, target_set=None, max_dist=None, filter_func=None)
Find and target the closest object matching the criteria
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_obj_or_set
|
Agent | int | set[Agent | int]
|
The agent or set |
required |
target_set
|
set[Agent]
|
The items to test. Defaults to None. |
None
|
max_dist
|
float
|
max distance. Defaults to None. |
None
|
filter_func
|
Callable
|
additional filer function. Defaults to None. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
GridCloseData |
CloseData
|
The gird close data of the closest object |
grid_target_pos(grid_obj_or_set, x, y, speed=0.01)
Set a grid object to move toward a specific grid coordinate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_obj_or_set
|
Agent | int | set
|
Agent, ID, or set of grid object(s) to move. |
required |
x
|
float
|
Target x grid coordinate. |
required |
y
|
float
|
Target y grid coordinate. |
required |
speed
|
float
|
Movement speed. Defaults to 0.01. |
0.01
|
grid_theme_current_index()
Reset-ledger probe: the selected theme index, which must be back to 0 (default).
Not a container - a setting. A mission that selected theme 1 would silently hand it to the next mission, which is a whole game re-skinned for no reason anyone could see.
grid_theme_is_loaded()
Reset-ledger probe: 1 while theme data is held, else 0.
grid_valid_blob(id_or_obj)
Return a grid object's engine blob only if its backing space object is
still valid, otherwise None.
A destroyed host ship leaves the grid object's Agent and its cached blob
wrapper in place, so to_blob still returns a non-None wrapper -- but
the engine raises ValueError: invalid space object on any get/set
of that wrapper. This probes cheaply so callers can guard the dead-object
case with a plain is None check, the same as a missing object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id_or_obj
|
Agent | int
|
Agent id or object. |
required |
Returns:
| Type | Description |
|---|---|
|
data_set | None: The live blob, or |