ServicesItem

Crafting, Durability, and Collections

The lifecycle half of the Item service: blueprints turn ingredients into products, durability wears products out, salvage recycles them, and collections reward completing a set.

Blueprints

A blueprint names its inputs (definitions and quantities), its outputs (with drop chances), and whether it is static or discoverable. Catalog role required, body from a file like definitions:

cat > iron_sword_bp.json <<'EOF'
{
  "name": "Forge Iron Sword",
  "type": "static",
  "inputs": [{"match": "definition_id", "value": "FdtUrUxXVxaAxUqNCLZv", "quantity": 3}],
  "outputs": [{"definition_id": "jxrfNfxMQYHtquatFgLA", "quantity": 1, "chance": 1.0}]
}
EOF
snug item blueprints create --domain docs4-forge --file iron_sword_bp.json

Each output rolls its chance independently, and can set initial_durability_pct to produce pre-worn items.

Crafting

Craft debits the inputs from a source container, rolls the outputs into a target container (both must belong to the same owner), and reports what happened - in one atomic operation:

snug --output json item craft --domain docs4-forge --container cont_XtmDHBhEAZwK \
  --blueprint jLaQettEgjCaTBCKbKgb --target-container cont_XtmDHBhEAZwK
{
  "blueprint_id": "jLaQettEgjCaTBCKbKgb",
  "consumed": [{ "definition_id": "FdtUrUxXVxaAxUqNCLZv", "quantity": 3 }],
  "produced": [
    {
      "item_id": "item_GvrxXGGctGsZ",
      "definition_id": "jxrfNfxMQYHtquatFgLA",
      "quantity": 1,
      "durability": { "current": 10.0, "max": 10.0, "broken_behavior": "unusable", ... },
      ...
    }
  ],
  "tier_events": [
    {
      "collection_id": "snSrXLfCsunXRPupwWpv",
      "required": 2,
      "bonus_event": "set_complete",
      "global_first": true
    }
  ],
  "global_first": false
}

Omit --blueprint for discovery crafting: the server scans the domain's blueprints for one whose inputs the source container satisfies and crafts it. With no satisfiable recipe (verified after the ingots ran out) the call fails with 400 no_matching_blueprint - the same error a named blueprint gives when ingredients are short. The top-level global_first flags the first craft of a discoverable blueprint domain-wide.

Durability

Definitions opt in via default_durability (max, a curve label, a broken_behavior, optionally downgrade_to). Wear is applied explicitly: use subtracts the amount you send (default 1) - the curve is stored on the instance but no time-based decay runs server-side.

snug item use    --domain docs4-forge --item item_GvrxXGGctGsZ --amount 4   # 10.0 -> 6.0
snug item use    --domain docs4-forge --item item_GvrxXGGctGsZ --amount 6   # 0.0, state "broken"
snug item repair --domain docs4-forge --item item_GvrxXGGctGsZ              # back to max, "normal"

What happens at zero depends on broken_behavior:

  • unusable - state flips to broken; further use calls fail with 400 item_unusable until repaired.
  • destroy - the item is removed from its container entirely (the response echoes its final state; subsequent reads 404).
  • downgrade - the instance's definition_id is swapped to downgrade_to and durability resets to max, still normal.

repair restores --amount durability (omit it to restore to max) and clears the broken state. Items without durability reject both use and repair with 400 item has no durability.

Salvage destroys an item and pays out its definition's salvage_outputs (each with quantity and chance) into the same container - stackable outputs merge into existing stacks:

snug item salvage --domain docs4-forge --item item_GvrxXGGctGsZ
# granted: 2 Iron Ingots, merged into the existing stack

Collections

A collection is a set of member definitions with reward tiers. Ownership is tracked per user, ticked automatically whenever a user receives a member definition - by grant, craft, or transfer:

cat > blacksmith_set.json <<'EOF'
{
  "name": "Blacksmith Set",
  "members": ["FdtUrUxXVxaAxUqNCLZv", "jxrfNfxMQYHtquatFgLA"],
  "tiers": [{"required": 2, "bonus_event": "set_complete"}],
  "duplicate_policy": "count"
}
EOF
snug item collections create --domain docs4-forge --file blacksmith_set.json    # catalog role
snug --output json item collections progress --domain docs4-forge \
  --collection snSrXLfCsunXRPupwWpv --user docs-wave
{
  "collection_id": "snSrXLfCsunXRPupwWpv",
  "user_id": "docs-wave",
  "owned": ["FdtUrUxXVxaAxUqNCLZv", "jxrfNfxMQYHtquatFgLA"],
  "owned_count": 2,
  "total_members": 2,
  "completed": true,
  "tiers_reached": [2],
  "duplicate_counts": { "FdtUrUxXVxaAxUqNCLZv": 1 }
}

A tier fires exactly once, at the moment owned_count reaches required - the craft above returned the set_complete tier event with "global_first": true because that user was the first in the domain to complete the set. Receiving a member you already own counts into duplicate_counts when the policy is count (with ignore, duplicates are dropped silently). Progress is private: asking for another user's progress without an admin token fails with 403 insufficient_permissions.

On this page