Skip to content

The spawn module

Create and delete space objects, NPCs, grid objects, and client agents.

Overview

The spawn module wraps the engine's object-creation calls and registers each new object with the Agent system so it can be queried, linked, and targeted by the rest of the procedural API.

Every spawn function returns either an Agent object or a SpawnData handle you can pass to to_id / to_object. Use delete_object to remove objects when no longer needed — the engine and agent registry are both cleaned up.

Key helpers:

  • spawn_npc — the most common call; creates an enemy or friendly ship.
  • spawn_player — creates a player ship for a client console.
  • grid_spawn — creates an engineering-grid object on a ship.
  • spawn_nebula / spawn_monster — terrain and special NPC variants.

Quick example

== spawn_enemies ==
e1 = spawn_npc("Hive Emperor", "tsc", 5000, 0, 3000, "Raider 01")
add_role(e1, "enemy")
brain_add(e1, patrol_label)
station = spawn_station("Generic Station", "tsn", 0, 0, 0, "Starbase Alpha")
from sbs_utils.procedural.spawn import spawn_npc, spawn_station, delete_object

enemy = spawn_npc("Hive Emperor", "tsc", 5000, 0, 3000, "Raider 01")
station = spawn_station("Generic Station", "tsn", 0, 0, 0, "Starbase Alpha")

# ... later ...
delete_object(enemy)

Spawn functions overview

Function Creates
spawn_npc NPC ship (enemy, friendly, neutral)
spawn_player Player-controlled ship
spawn_station Station / base
spawn_nebula Nebula terrain object
spawn_monster Monster / special NPC
spawn_generic Generic space object by art ID
grid_spawn Engineering-grid object on a ship
delete_object Removes any space object

Creating player ships more than once

Every spawn_* call makes a new object, so setup that runs twice builds everything twice. Player ships have a natural name — their slot — so they can be created safely:

Function Does
player_ensure(slot, x, y, z, ship_key, name, side) The ship for that slot, creating one only if the slot is empty
player_slot_id(slot) The live ship holding a slot, or None
player_slots() Every filled slot, as {slot: id}
players_reset() Delete all player ships, freeing every slot

player_ensure compares against the live game, not a "have I run before" flag, which is what keeps deliberate re-runs working: after players_reset() or a new simulation the ships are gone and the next call rebuilds them, a destroyed ship can be remade, and a late-joining crew's slot is filled without disturbing the others. An existing ship is returned untouched — use a2x_place_player to move or rename one in place.

See Signal routes for when to reach for this instead of a once route.

API

grid_spawn(id, name, tag, x, y, icon_index, color, roles)

Spawn a grid object (engineering component) onto a ship's grid.

Parameters:

Name Type Description Default
id Agent | int

The ship agent ID or object to attach the grid object to.

required
name str

Display name of the grid object.

required
tag str

Tag identifying the grid object's side or type.

required
x int

Column position on the engineering grid.

required
y int

Row position on the engineering grid.

required
icon_index int

Icon index for the grid display.

required
color str

Display color string.

required
roles str

Comma-separated roles to assign to the grid object.

required

Returns:

Name Type Description
GridObject

The newly created grid object.

npc_spawn(x, y, z, name, side, ship_key, behave_id)

Spawn a non-player (NPC) ship into the simulation.

Parameters:

Name Type Description Default
x float

X spawn coordinate.

required
y float

Y spawn coordinate.

required
z float

Z spawn coordinate.

required
name str

Display name, or None.

required
side str

Side the ship belongs to.

required
ship_key str

Ship template key from shipData.

required
behave_id str

Behavior type identifier.

required

Returns:

Name Type Description
SpawnData

Spawn data for the new NPC.

player_ensure(slot, x, y, z, ship_key, name=None, side='tsn')

Ensure a player ship occupies slot, spawning one only if it is empty.

Idempotent: returns the existing ship's ID if the slot is already filled, so an initialization route that gets emitted more than once creates nothing extra. Because the check is against the live world and not a did-I-run flag, a slot emptied by sim_create(), a deletion or a destroyed ship is refilled on the next call - which is what makes reset, respawn and late-joining crew work.

An existing ship is returned UNTOUCHED (not repositioned or renamed); use a2x_place_player to converge one in place. This mirrors side_ensure / side_create.

Parameters:

Name Type Description Default
slot int

Player slot, stable across re-runs.

required
x float

X spawn coordinate.

required
y float

Y spawn coordinate.

required
z float

Z spawn coordinate.

required
ship_key str

Ship template key from shipData.

required
name str

Display name.

None
side str

Side the ship belongs to. Comma tokens become roles.

'tsn'

Returns:

Type Description

int|None: The ship's ID, or None if the spawn failed.

player_slot_id(slot)

The live player ship holding slot, or None.

Parameters:

Name Type Description Default
slot int

The player slot.

required

Returns:

Type Description

int|None: The ship's ID, or None if the slot is empty.

player_slot_role(slot)

The role marking the ship that holds slot (e.g. player_slot_3).

A role, because role sets are the only O(1) keyed lookup available and they self-clean when the object is deleted (Agent._remove purges the registries), so a slot is freed by deleting its ship with no bookkeeping.

player_slots()

Every filled player slot as {slot: id}.

Returns:

Name Type Description
dict

Slot number -> ship ID, for live player ships carrying a slot.

player_spawn(x, y, z, name, side, ship_key)

Spawn a player ship into the simulation.

Parameters:

Name Type Description Default
x float

X spawn coordinate.

required
y float

Y spawn coordinate.

required
z float

Z spawn coordinate.

required
name str

Display name, or None.

required
side str

Side the ship belongs to.

required
ship_key str

Ship template key from shipData.

required

Returns:

Name Type Description
SpawnData

Spawn data for the new player ship.

players_reset()

Delete every player ship, freeing all slots.

The explicit path for an INTENTIONAL re-initialization (reset the scenario without reloading the mission): wipe, then re-emit the create signal and let player_ensure rebuild the roster. Slot roles are purged by the delete, so nothing else needs clearing.

Returns:

Name Type Description
int

How many ships were deleted.

terrain_spawn(x, y, z, name, side, ship_key, behave_id)

Spawn a passive terrain object into the simulation.

Parameters:

Name Type Description Default
x float

X spawn coordinate.

required
y float

Y spawn coordinate.

required
z float

Z spawn coordinate.

required
name str

Display name, or None.

required
side str

Side the object belongs to, or None.

required
ship_key str

Object template key from shipData.

required
behave_id str

Behavior type identifier.

required

Returns:

Name Type Description
SpawnData

Spawn data for the new terrain object.