---
name: set-crafting
title: Set World Crafting Guide
description: A guide for game developers and agents on how to use the Set World crafting and economy APIs. Covers the orb currency, rejection-sampling to target tiers, best-of-N lotteries, salvage, monster drops, and how to compose these into a progression loop for your game.
homepage: https://set.world
spec: https://set.world/api/spec
license: MIT
version: 1
methods: [GET]
auth: none
cors: open
content_type: application/json
canonical_paths:
  - https://set.world/craft-guide
  - https://set.world/craft-guide.md
  - https://set.world/api/craft-guide
---

# Set World Crafting Guide

This guide teaches you how to use the Set World crafting and economy APIs to build item progression into your game. The economy is denominated in a single currency, orbs, and every cost is deterministic and verifiable.

## A Note for Builders

Let it be understood that every orb cost and every crafting formula herein is guidance and not mandate. The act of crafting an item, spending orbs, or pricing a fight belongs to the game developer on their own server. We provide the reference formulas and the APIs that compute them, but you are free to multiply, divide, ignore, or invent entirely new use cases from these primitives. Build what your creativity demands.

## The Orb Economy

Orbs are the universal currency. Players earn them from monster drops and spend them on crafting. The cost curve is exponential, creating a natural progression wall that rewards sustained play without hard-gating content.

| System | Formula | Range |
| --- | --- | --- |
| Crafting | `5^(tier - 1)` | 1 / 5 / 25 / 125 / 625 / 3,125 / 15,625 |
| Monster drops | `round((avgStat - 6)^2 / 4) × classMultiplier × variance` | Scales with enemy strength |
| Salvage | fixed refund by grade | F–C: 0 · B: 2 · A: 40 · S: 200 |

## Crafting: Two Modes

### Mode 1: Rejection-sample to a target grade

Pay a fixed orb cost, receive an item guaranteed to be at or above the target material grade. The server rolls until the material hits the requested tier or the budget runs out.

```sh
# Check the price
curl 'https://set.world/api/craft/cost?tier=5'
# Response: { tier: 5, orbs: 625, defaultBudget: 62500 }

# Craft a Grade B item
curl 'https://set.world/api/craft?tier=5'
# Response: { mode: "tier", item: {...}, tier: 5, tierGrade: "B", tierName: "Grade B", material: {...}, attempts: 42, capped: false }
```

**Key fields:**
- `tier=1..7` maps to Grade F through Grade S
- `capped: true` means the budget ran out before hitting the target (effectively impossible with current weights — even Grade S expects only ~679 attempts against a 1,000,000 budget — but the field is the honest answer if weights ever change)
- `seed=N` makes the result reproducible — same seed always produces the same item

**Cost table:**

| Grade | Tier | Orb Cost | Budget (max attempts) |
| --- | --- | --- | --- |
| F | 1 | 1 | 100 |
| E | 2 | 5 | 500 |
| D | 3 | 25 | 2,500 |
| C | 4 | 125 | 12,500 |
| B | 5 | 625 | 62,500 |
| A | 6 | 3,125 | 312,500 |
| S | 7 | 15,625 | 1,000,000 |

### Mode 2: Best-of-N lottery

Spend N orbs, roll N items, keep the best one. No grade guarantee — you get the highest-tier item that luck provides.

```sh
# Spend 125 orbs on a lottery
curl 'https://set.world/api/craft?orbs=125'
# Response: { mode: "orbs", item: {...}, tier: 5, tierGrade: "B", rolls: 125, rollsExpected: { medianTier: 5, medianScore: 10.88, ... } }
```

**Expected outcomes (measured medians):**

| Orbs spent | Median tier | Median score |
| --- | --- | --- |
| 1 | 3 (Grade D) | 5.21 |
| 5 | 4 (Grade C) | 6.36 |
| 25 | 5 (Grade B) | 7.85 |
| 125 | 6 (Grade A) | 8.59 |
| 625 | 7 (Grade S) | 8.40 |
| 3,125 | 7 (Grade S) | 9.63 |
| 15,625 | 7 (Grade S) | 11.72 |

Every 5× spend steps the median up one full grade until the scale tops out at Grade S around 625 orbs; past that, more orbs buy a higher-scoring S. The `rollsExpected` field in the response gives percentile bands so your UI can show players whether they got lucky or unlucky.

## Salvage (Turning Items Back Into Orbs)

Disassembling an item destroys it and refunds orbs by grade:

```sh
# Appraise an item you hold (by its 19-number index vector)
curl 'https://set.world/api/salvage?indexes=<19-numbers>'
# Or ask by grade, or fetch the whole schedule
curl 'https://set.world/api/salvage?tier=6'
curl 'https://set.world/api/salvage'
```

| Grade | F | E | D | C | B | A | S |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Salvage | 0 | 0 | 0 | 0 | 2 | 40 | 200 |

The numbers look harsh at low grades on purpose. A 1-orb lottery craft is a fair single roll, so any schedule where the expected refund per roll reaches 1 orb turns craft → disassemble → craft into an orb printer. Under this schedule the expectation is ≈ 0.70 orbs per roll — a ~30% sink on the tightest possible loop (the endpoint reports the live number as `expectedSalvagePerRoll`). The feel it produces: F–C items are disassembly fodder you clear by the armful, a Grade B always pays a little, an A is a 40-orb jackpot chime, and salvaging a Grade S is a 200-orb event you do on purpose.

Salvage is grading, not prescription: we score the item, and whether disassembly exists in your game is your call. Use the `guaranteedTier` drop override to inject salvage-worthy items into a zone without touching the invariant — it now yields an actual crafted item (with its salvage value) rather than just a floor.

## Monster Drops (Earning Orbs)

Monsters drop orbs based on their average stat and encounter class. This is how players fund crafting.

```sh
# Check encounter classes and multipliers
curl 'https://set.world/api/drop/classes'
# Response: { classes: [{name: "trash", multiplier: 1}, {name: "veteran", multiplier: 3}, ...] }

# Price a kill
curl 'https://set.world/api/drop?stats=12-14-10-11-13-16-12-14-11&class=elite'
# Response: { avgStat: 12.556, baseDrop: 11, classMultiplier: 10, rolledVariance: 1.0234, orbs: 112, ... }
```

**Encounter classes:**

| Class | Multiplier | Use for |
| --- | --- | --- |
| trash | 1x | Fodder mobs, abundant |
| veteran | 3x | Mini-bosses, rare spawns |
| elite | 10x | Dungeon guardians, named enemies |
| boss | 50x | End-of-zone bosses |
| world-boss | 250x | Server-wide events, raid targets |

**Optional overrides** (passed as URL-encoded JSON in the `override` query param):
- `flat`: fixed orb amount (bypasses formula)
- `multiplier`: additional multiplier on top of class
- `guaranteedTier` (1..7): returns a `guaranteedItem` — a full enriched item crafted at that material grade on a derived seed (reproducible, doesn't disturb the orb roll), bundled with its `salvage` value. This is the sanctioned way to feed the salvage loop.
- `bonusOrbs`: `{ min, max }` range of extra orbs added

## Leveling Is Yours

Set has no level system — levels are meaningless to the API, on purpose. Your game decides how many stat points a level grants (or whether levels exist at all), and `/api/drop` prices whatever stat blocks result. The curves compose safely with any scheme: drop income is quadratic in enemy stats while craft prices are geometric and boost prices cubic, so farming always lags growth no matter how fast your game levels. If you want a starting point, the stat space holds 144 grantable points (9 stats, each 8–24) — a flat 8 points per level reaches a maxed, world-boss-tier enemy after 18 level-ups; slower schedules stretch the same journey. To mint an opposing force, pick one seed and expand it into per-soul seeds with `deriveSeed(seed, i)` — one `/api/roll/character?seed=<derived>` call per soul — or bring your own stat blocks straight to `/api/drop`. Enemy threat is your math too: stat blocks live in the 8–24 domain, and encounter multipliers scale the drop, not the stat block, so a 10,000-HP boss is a number your game assigns, not one the API hands you.

## Building a Progression Loop

Here's how to compose these APIs into a complete gameplay loop:

### 1. Generate a starting character

```sh
curl https://set.world/api/roll/character
```

The character arrives with random equipment (mostly Grade F-D) and base stats (8-24).

### 2. Fight monsters to earn orbs

Use the character's `modifiedStats` to determine what tier of enemy they can handle. Price fights with `/api/drop`.

### 3. Spend orbs on crafting

Target a specific grade for a specific slot. Replace the worst item first for the highest orb-value gain. As equipment improves, the character's derived attributes rise with it.

### 4. Scale enemy difficulty

As the character's average stat rises, `baseDrop` increases quadratically. Move from trash to veteran to elite encounters. The orb income curve naturally matches the exponential craft costs.

### 5. Close the loop with salvage

Old gear goes back into the pot: `/api/salvage` prices every replaced item, and because the schedule is a strict sink the loop tightens instead of inflating. On permadeath (if your game has it), the fallen character's fifteen slots become the next run's starting orbs.

### 6. End-game

- A guaranteed Grade S craft costs 15,625 orbs; the lottery reaches a median Grade S around 625 orbs if you can stomach the variance
- These walls create aspirational goals without hard gates

### The same loop at any scale

Nothing above assumes a single hero. The API is stateless and every formula is per-entity, so the loop runs identically for a roster or an army:

- **Mass battles**: mint forty characters a side from one seed — expand it with `deriveSeed(seed, i)` and call `/api/roll/character?seed=<derived>` once per soul — then match the sides on total `equipmentOrbValue` or summed `powerRating` (a salary cap — economically fair by construction), and price every fallen enemy with `/api/drop`. The army is fully described by its seed and soul-count, so anyone can re-mint it. A defeated army of forty veterans at average stat 12 pours out roughly 1,080 orbs — about two guaranteed Grade B crafts.
- **Roguelikes**: one `seed=` per run gives you daily-challenge dungeons and verifiable leaderboards — creation is seeded too, so the run's characters, items, crafts, and drops all replay from the same integer; on permadeath, the fallen hero's equipment becomes the orb stake for the next run via `/api/salvage`.

## Grading a Whole Character

```sh
curl 'https://set.world/api/power?stats=14-12-10-11-13-16-12-14-11&skills=2'
```

`powerRating = level × 100 + (str + int + dex + agi + vit) × 10 + (wis + per + res) × 5 + luck × 2 + skills × 25`, read off the reconciled stat block. Every `/api/roll/character` response already carries `powerRating` and `powerRatingMax`; the standalone endpoint re-grades characters you store yourself. Use the sum across a roster as a salary cap; the matchmaking rule stays yours.

## Item Power Budgets

Items never ship resolved stat modifiers — what a point of power buys inside your combat math is exactly the dial your game must tune for itself. What Set grades is the budget and the theme:

```sh
curl 'https://set.world/api/modifiers?indexes=<19-numbers>'
curl 'https://set.world/api/modifiers/spec'
```

| Grade | F | E | D | C | B | A | S |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Budget | 0 | 1 | 2 | 4 | 8 | 16 | 32 |

The budget doubles per grade while the craft price grows 5× — so gear power stays sub-linear in price and the Grade S wall stays a story rather than a stat cliff. Each name factor (prefix, quality, material, gear, suffix) also hash-derives a themed channel — one of the 23 derived attributes or 8 elemental channels — by the same pinned FNV-1a spec traits use, so "burning" means the same channel in every game. Assign the concrete modifiers and magnitudes yourself; two games honoring the same Grade A item at different magnitudes are both correct.

## Calculating Derived Stats

Every character has 9 base stats, but combat and movement are governed by 23 derived attributes computed from the 5 primary stats (strength, dexterity, agility, intelligence, vitality). Use these endpoints to calculate and inspect them.

```sh
# Derive all 23 attributes from a stat array
curl 'https://set.world/api/attributes?stats=14-12-10-11-13-16-12-14-11'

# See the full formula table (base, coefficients, which stats feed each attribute)
curl 'https://set.world/api/attributes/spec'

# Confirm canonical stat order and bounds before calling
curl 'https://set.world/api/stats'
```

The formula for each attribute is `base + primaryCoef × (primary - 8) + secondaryCoef × (secondary - 8)`. The spec endpoint returns every coefficient so your client can recompute attributes locally without calling the API on every stat change.

## Status Effects

The world provides 48 status effects that items and combat may inflict. Each effect carries a prose description of its mechanical consequence. Use these as your combat status system, buff and debuff layer, or item enchantment pool.

```sh
# Get all status effects
curl 'https://set.world/api/effects'
```

Effects include conditions such as Burn, Poison, Bleed, Frozen, Charmed, Silenced, Haste, Berserk, Invisible, and many others. Each entry has a `name` and `description` written in the voice of the world. The mechanical interpretation belongs to you as the game developer. Apply them as damage-over-time, crowd control, buffs, debuffs, or any system your game requires.

## Reproducibility

Pass `seed=N` to `/api/craft`, `/api/drop`, or any `/api/roll/*` endpoint for deterministic results. Each request forges exactly one soul; requests are never bundled. To expand one seed into an army, derive a per-soul seed with `deriveSeed(seed, i) = (seed + i × 0x9E3779B9) >>> 0` and make one call per soul — each derived seed is independently re-fetchable on its own. Every seeded response also carries a `contentVersion` string; same seed *and* same `contentVersion` means byte-identical output forever, and a changed value means a content update shifted the roll stream. Use this for:
- Tournament fairness (all players get the same rolls)
- Replay systems (store seeds instead of full item data)
- Daily challenges (everyone crafts and rolls with today's seed)
- Verifiable battle reports (an army is its seed plus its number of souls)
- Testing (pin outcomes in your test suite)

## Item Scoring

Every crafted item comes back with a full envelope you can display:

```json
{
  "item": { "name": "...", "slot": "tool", "indexes": [...] },
  "score": 10.28,
  "tier": 5,
  "tierGrade": "B",
  "tierName": "Grade B",
  "material": { "name": "obsidian", "materialRank": 17, "tier": 5, "tierGrade": "B", "tierName": "Grade B" }
}
```

To re-score any item later (e.g., from a stored index vector):

```sh
curl 'https://set.world/api/rarity?indexes=0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18'
```

## Source

Full source and architecture: <https://github.com/jimmylee/set>. MIT licensed.
