Starbases
A starbase is where fleets dock, cargo is stored, and crafting happens. The SDK splits it in two, and knowing which half you want saves confusion.
- The starbase itself — where it is, what level it is — is shared infrastructure and belongs to world.
- Your state at that starbase — your cargo, your escrowed ships, your upgrades — is yours, and lives here.
Reading your state at a starbase
Section titled “Reading your state at a starbase”const bases = await character.starbases.all();Or directly, when you know the system:
const base = await sage.starbases.forCharacterAtSystem( characterAddress, systemAddress,);A character can have state at many starbases, or none. A character who has never docked anywhere returns an empty array, which is a valid answer rather than a failed read.
What is in it
Section titled “What is in it”Cargo. What you have stored there, as StarbaseCargoInventory. This is
distinct from what a fleet is carrying — cargo moves between the two, and
reading one tells you nothing about the other.
Escrowed ships. Ships you own that are held at the starbase rather than assigned to a fleet.
Respawn state. Where destroyed ships come back.
Upgrades in progress. Starbase upgrades take real time, so an upgrade is a process with a lifecycle rather than an instant change:
const upgrades = await base.upgrades.all();Registering at a starbase
Section titled “Registering at a starbase”Your state at a starbase does not appear on its own: before a starbase can hold anything of yours, you register there once. That is a write — if it would be your first, read How Atlas Kit changes the game before continuing.
planRegisterStarbasePlayer plans that one-time registration for a system
with a starbase where you have no state yet:
import { planRegisterStarbasePlayer } from '@aephia/atlas-kit/starbases/actions';import { getStarSystemById } from '@aephia/atlas-kit/world';
const registered = new Set( (await character.starbases.all()).map((state) => state.system.address),);for (const connection of system.connections) { const destination = await getStarSystemById(ctx, connection.systemId); if (destination.starbase === undefined) continue; if (registered.has(destination.address)) continue; const plan = await planRegisterStarbasePlayer(ctx, character, destination, { funder: walletAddress, }); console.table(plan.describe()); break;}The funder is the address that pays the small one-time creation cost; using
the wallet that will later sign is the convenient choice, but the planner does
not require it. The planner refuses a system without a shared starbase, and
refuses to register where your state already exists — registration is once per
starbase, which is exactly why the snippet checks what you already have first.
The resulting Plan signs and executes like every other; see Warp & subwarp for that flow.
Gotchas
Section titled “Gotchas”Starbase cargo and fleet cargo are different accounts. Loading a fleet does not change what the starbase holds, and vice versa. If you are tracking totals, you need both.
A starbase you have never used has no player state. The starbase exists in the world; your state at it does not. That is why the read can legitimately come back empty.
Upgrade timing is derived. Completion times come from the process state plus the Game account’s definitions, not from a stored timestamp you can read directly.
Reference
Section titled “Reference”starbases— every export in this entrystarbases/actions— the registration plannerworld— the starbase as shared infrastructurecrafting— what happens at a starbase’s habs