Documentation: 0.5.0 (source: v0.5.0).
# Crafting

> Recipes, habs, and processes — turning inputs into outputs over time.

Markdown source of https://docs-v0-5-0.atlas-kit-docs.pages.dev/guides/crafting/ — see https://docs-v0-5-0.atlas-kit-docs.pages.dev/ai/ for the full machine-readable surface.

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](/guides/crafting-habs/).

:::game[Recipes run inside Crafting Habs]
A recipe is the plan for making something: it lists the materials needed, what
the job produces, and how long it normally takes. A Crafting Hab is the
workshop where that recipe runs. Its size and quality affect how much work it
can handle and how efficiently it works. While a job is running, its materials
and workshop space are tied up until the craft finishes or is cancelled.
:::

## Recipes

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

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

> **Runnable example — Read a recipe and crafting activity.** One recipe by id, plus the habs and processes a character runs. Run it in the browser at https://docs-v0-5-0.atlas-kit-docs.pages.dev/guides/crafting/.

## Habs and processes

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

```ts
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.

## Why processes need discovery

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](/concepts/bindings/) for the
broader pattern of accounts without derivable addresses.

## Gotchas

**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](/guides/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.

## Reference

- [`crafting`](/reference/crafting/) — every export in this entry
- [Crafting habs](/guides/crafting-habs/) — the facility itself
- [`starbases`](/guides/starbases/) — where habs live
- [`cargo`](/guides/cargo/) — the inputs and outputs
