> ## Documentation Index
> Fetch the complete documentation index at: https://docs.immutable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Crafting

Let players combine existing NFTs to create new ones—a core mechanic for progression and engagement in games.

## Why Use Crafting?

> [accordion] Player Engagement
>
> Crafting drives collection and trading behaviour. Players actively hunt for ingredients, creating demand across your economy.

> [accordion] Asset Sinks
>
> Burning inputs removes items from circulation, maintaining scarcity and value in your game economy.

> [accordion] Progression Depth
>
> Multi-step recipes create meaningful goals. Players feel invested when they craft rare items.

## How It Works

**1. Player Selects Items**

Player chooses NFTs to combine from their inventory

**2. Backend Validates**

Your server verifies ownership and recipe validity

**3. Burn Inputs**

Transfer input NFTs to burn address

**4. Mint Output**

Create new NFT for player via [Minting API](https://docs.immutable.com/docs/products/asset-contracts/minting-api.md)

## Recipe System

Define recipes that map inputs to outputs:

```typescript theme={null}
const recipes = [
  {
    id: 'iron_sword',
    inputs: [
      { contract: MATERIALS, trait: { type: 'Iron Ore' }, count: 2 },
      { contract: MATERIALS, trait: { type: 'Wood' }, count: 1 },
    ],
    output: {
      name: 'Iron Sword',
      attributes: [{ trait_type: 'Damage', value: 10 }],
    },
  },
  {
    id: 'steel_sword',
    inputs: [
      { contract: WEAPONS, trait: { type: 'Iron Sword' }, count: 1 },
      { contract: MATERIALS, trait: { type: 'Steel Ingot' }, count: 2 },
    ],
    output: {
      name: 'Steel Sword',
      attributes: [{ trait_type: 'Damage', value: 25 }],
    },
  },
];
```

## Implementation

```typescript theme={null}
const BURN_ADDRESS = '0x000000000000000000000000000000000000dEaD';

app.post('/craft', async (req, res) => {
  const { recipeId, inputTokenIds, playerAddress } = req.body;
  const recipe = recipes.find(r => r.id === recipeId);
  
  if (!recipe) {
    return res.status(400).json({ error: 'Invalid recipe' });
  }
  
  // Verify ownership of all inputs
  for (const tokenId of inputTokenIds) {
    const owner = await nftContract.ownerOf(tokenId);
    if (owner.toLowerCase() !== playerAddress.toLowerCase()) {
      return res.status(403).json({ error: 'Not owner of input' });
    }
  }
  
  // Verify inputs match recipe requirements
  // ... validation logic
  
  // Burn inputs
  for (const tokenId of inputTokenIds) {
    await nftContract.transferFrom(playerAddress, BURN_ADDRESS, tokenId);
  }
  
  // Mint output via Minting API
  const outputId = generateTokenId();
  await mintNFT(playerAddress, outputId, recipe.output);
  
  res.json({ success: true, outputId });
});
```

## Upgrades

Enhance existing items by burning materials:

```typescript theme={null}
async function upgradeItem(tokenId: string, materialsUsed: string[]) {
  const nft = await getNFT(tokenId);
  const level = nft.attributes.find(a => a.trait_type === 'Level')?.value || 1;
  
  // Burn material NFTs
  for (const materialId of materialsUsed) {
    await burnNFT(materialId);
  }
  
  // Update metadata via Minting API refresh
  await refreshMetadata(tokenId, {
    ...nft.metadata,
    attributes: nft.attributes.map(a => 
      a.trait_type === 'Level' ? { ...a, value: level + 1 } : a
    ),
  });
}
```

## Design Tips

| Pattern | Description |
| - | - |
| **Deterministic** | Same inputs always produce same output |
| **Probabilistic** | Random chance for rare outcomes |
| **Time-gated** | Crafting takes time to complete |
| **Progressive** | Multi-step recipes for advanced items |

> [!NOTE]
>
> Keep crafting server-side to prevent exploitation. Only mint outputs after verifying ownership and burning inputs.

## Next Steps

> [card] [Minting API](https://docs.immutable.com/docs/products/asset-contracts/minting-api.md)
>
> Learn about the Minting API

> [card] [ERC-721](https://docs.immutable.com/docs/products/asset-contracts/erc721.md)
>
> Deploy NFT contracts

> [card] [ERC-1155](https://docs.immutable.com/docs/products/asset-contracts/erc1155.md)
>
> Use multi-token contracts


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.