Skip to content
Next — unreleased

Crafting habs

View as Markdown

A crafting hab is a player-owned production facility deployed at a starbase. Crafting covers the recipes and the processes that run; this guide covers the facility itself — what it is built into, how that setup changes production, and what keeps it alive.

Habs hang off their owner:

const habs = await sage.craftingHabs.byCharacter(characterAddress);
const tiers = habs.map((hab) => hab.definition.tier);

byProfile and byStarbasePlayer exist for the other directions. A hab snapshot carries its definition (name, tier, slots), its buildings, its state, its production, and its rent — the whole facility in one read.

Inspect Hab containers and their building definitions without fetching placed Habs:

import {
getCraftingHabDefinition,
listCraftingHabDefinitions,
getHabBuildingDefinition,
listHabBuildingDefinitions,
} from '@aephia/atlas-kit/crafting';
const containers = await listCraftingHabDefinitions(ctx);
const buildings = await listHabBuildingDefinitions(ctx);
const firstContainer = containers[0];
if (firstContainer !== undefined) {
const definition = await getCraftingHabDefinition(ctx, firstContainer.id);
console.log(definition.name, definition.slots, definition.cargoId);
}
const firstBuilding = buildings[0];
if (firstBuilding !== undefined) {
const definition = await getHabBuildingDefinition(ctx, firstBuilding.id);
console.log(definition.modifiers.speed.value, definition.jobCapacity);
console.log(definition.unlockedRecipeIds);
}

Each catalog shares immutable objects between its listing and by-id reads. The standalone container keeps its placement cargoId; a placed Hab’s definition summary includes resolved placementCargo. Building modifiers and job capacity are configuration values. Use a placed Hab for its aggregate modifiers, available job slots, and production state. Listing a definition does not prove that a player can build it in a particular Hab.

See Definition catalogs for loading both catalogs together, persistence, and section refresh behavior.

A hab starts as a plot; buildings are what make it produce. Each building in hab.buildings occupies slots, wants crew, and carries its own modifiers — and the hab’s aggregate modifiers are what actually apply to production:

const habs = await sage.craftingHabs.byCharacter(characterAddress);
const setups = habs.map((hab) => ({
buildings: hab.buildings.map((building) => building.definition.name),
speed: hab.modifiers.speed.value,
efficiency: hab.modifiers.efficiency.value,
}));

Two habs running the same recipe do not finish at the same time — the setup decides. speed, efficiency, fee, and crewCount are the four dials.

hab.availableJobSlots is the number this facility can still take on. A hab in the middle of its work answers differently from an idle one, so read it when scheduling rather than caching it with the definition.

Like a claim stake, a hab occupies land and pays for it: rentBalanceRaw is what remains, lastRentAtUnixSeconds is when it was last settled, and the definition’s eviction grace period says how much slack exists once the balance runs dry.

A hab in design is a plan, not a facility. Its state carries the proposed buildings; nothing produces until the design is finalized and the hab is active. The same three-state lifecycle as claim stakes applies: design, active, deactivated.

Construction takes time after placement. constructionRemainingSeconds is live state — a hab can exist, be active, and still be building itself.

Production is a rate, not a total. hab.production follows the same pattern as mining: net rates against a clock, with an inventory and a last-tick time — compute the current amount, do not expect a stored one.