Skip to content
0.5.0 — latest

Crafting

View as Markdown

Crafting has three moving parts, and separating them makes the API obvious:

  • a recipe is the rule: these inputs become that output, taking this long;
  • a hab is the place: a plot at a starbase where crafting can happen;
  • a process is the run: one recipe executing in one hab, right now.

This guide covers recipes and processes. The hab as a facility — its buildings, modifiers, capacity, and rent — has its own guide.

Recipes are static definitions from the Game account, so they are the same for everyone and cheap to read:

const recipe = await sage.recipes.byId(recipeId);

Both hang off whoever owns them, which is usually a character or their state at a starbase:

const habs = await sage.craftingHabs.byCharacter(characterAddress);
const running = await sage.craftingProcesses.byCharacter(characterAddress);

A process is a lifecycle, not a boolean. It has a start, a duration derived from its recipe, and an end — which is why crafting occupies a hab for a period rather than completing instantly.

Crafting processes have no derivable address. You cannot compute where one lives from the character or the recipe; it is assigned when the process is created.

That is why the reads above are byCharacter, byProfile, and byStarbasePlayer rather than a single get(address) — each encodes a verified way of finding processes, rather than pretending you can calculate where they are. See the bindings escape hatch for the broader pattern of accounts without derivable addresses.

A finished process still exists. Completion is a state, not a deletion. Read the lifecycle rather than assuming presence means “in progress”.

Hab capacity is finite. A hab holds a limited number of concurrent processes, so “can this character craft” is not answerable from the recipe alone — crafting habs covers reading the free slots.

Recipe inputs are raw amounts. Like all quantities, they are bigint and need the cargo definitions to render as names and decimals.