Skip to content

Standby culling

Park distant objects out of the engine network by player proximity, without losing their script state.

Overview

sbs.push_to_standby_list_id removes an object from the engine sim and network replication while its py-side Agent (roles, links, inventory) persists — so distant, irrelevant objects stop costing the network without losing script state. This module drives that by player proximity: call standby_cull_step (or standby_cull_fleets) each tick, and any candidate with no __player__ within a radius is parked; it's retrieved the moment a player comes near.

A parked self-brained NPC has its brain paused while parked (and resumed on retrieve), so a non-simulated object isn't still being steered — which makes terrain and self-brained NPCs/POIs safe to cull. Fleets park as a unit: all of a fleet's ships and its one brain go dark together when no player is near any of them.

Side-agnostic — proximity is measured to every player. Extracted from the Open Universe's culler so any large-world mission can reuse it.

Quick example

== cull_loop ==
--- tick
    await delay_sim(1)
    standby_cull_step(role("__npc__") | role("terrain"), 30000)
    standby_cull_fleets("fleet", 30000)
    jump tick
from sbs_utils.procedural.standby import (
    standby_cull_step, standby_cull_fleets, standby_cull_clear)

# each tick: park loose objects and whole fleets past 30k units from all players
standby_cull_step(candidates, 30000)
standby_cull_fleets("fleet", 30000)

Clear before you despawn

Before clearing a system (e.g. on a jump), call standby_cull_clear() first. Delete-by-box only sees objects in normal space, not standby — so parked objects must be retrieved before the region is cleared, or they leak.

API

Engine-network culling by player proximity.

sbs.push_to_standby_list_id removes an object from the engine sim + network replication while its py-side Agent (roles/links/inventory) persists - so distant, irrelevant objects stop costing the network without losing script state. (physics/replication iterate sim.space_objects; standby pulls the object out of it.)

Brains are MAST tasks independent of the sim, so a parked NPC's brain would keep acting on a non-simulated object - so the culler pauses a parked object's brain (brain_pause) and resumes it on retrieve. That makes terrain AND self-brained NPCs/POIs safe to cull. A parked object isn't in normal space, so its position is cached here.

Cull the fighters, not the rocks. Standby only pays off for objects that cost the engine sim/network continuously - moving, brained, per-tick-replicating NPCs and fleets. It is a poor fit for terrain: * Engine tick cost of passive terrain is near-zero (measured: ~100k passive agents held real-time; see OpenUniverse/MULTI_SYSTEM_FEASIBILITY.md). * Terrain replicates to a client once, then only on a forced update - so there is no ongoing network cost for standby to save. * The py-side Agent persists while parked, so standby never shrinks the Python heap / GC pressure regardless. And it is net-negative for terrain: retrieve re-inserts the object into sim + network, so crossing the radius re-sends parked terrain to in-range clients (a network burst + pop-in hitch) that resident terrain never incurs. So although terrain is safe to cull, prefer to leave it resident and aim the culler at active content (standby_cull_fleets is the valuable path). Terrain standby is justified only as an engine-side memory measure for genuinely dormant, far, unlikely-to-be- visited systems - not as a per-tick or network optimization. (Caveat: the perf run that grounds "terrain is cheap" had NO connected clients, so it measured compute only - the NETWORK axis, which is standby's whole reason to exist, is unmeasured. The "terrain replicates once, then only on force" model and the retrieve-re-sends churn cost are reasoned, not measured. So the compute + heap legs of "leave terrain resident" are solid; the network leg is a hypothesis - verify with a client-connected run before relying on the churn-cost argument.)

Fleets are handled as a unit (standby_cull_fleets): a fleet's brain lives on the fleet agent, not its ships (linked via a "ship_list" role/link), so all a fleet's ships park/retrieve together and the one fleet brain pauses/resumes - the whole formation goes dark when no player is near any of its ships.

Extracted from the Open Universe's culler so any large-world mission can reuse it. Side-agnostic: proximity is measured to every __player__.

standby_cull_clear()

Retrieve everything parked and forget it - call before clearing a system on a jump, so parked terrain returns to normal space and gets despawned with the rest (delete-by-box only sees objects in normal space, not standby).

standby_cull_count()

How many objects are currently parked (diagnostics): loose objects + fleet ships.

standby_cull_fleets(fleet_role, radius)

Park/retrieve whole fleets by proximity. A fleet (an agent with fleet_role whose ships are linked under "ship_list") is parked when no player is within radius of ANY of its ships: every ship goes to standby and the fleet's brain is paused (it lives on the fleet agent). It is retrieved the moment a player comes near. Treating the formation as one unit keeps the fleet brain from steering non-simulated ships.

standby_cull_step(candidates, radius)

Park candidates with no player within radius (out of the engine network); retrieve parked ones once a player comes near. candidates is an iterable of Agents (e.g. a role set); non-space agents that share a role are skipped. A parked self-brained NPC has its brain paused while parked.