Minecraft Scripting API

Please note: Some examples on this page may be outdated or may not work as expected.

Items & Inventory

Items are the objects players collect, hold, and use - from swords and tools to food and custom items. Managing inventory is essential for any add-on with gear progression, economies, or loot systems. Understanding how to create, modify, and track items unlocks powerful gameplay mechanics.

Understanding Items & Inventory

An ItemStack is a single stack of items (like 64 diamonds in one slot). Every ItemStack has:

  • Type: What kind of item it is (diamond_sword, golden_apple, etc.)
  • Amount: How many of this item in the stack (1-64 usually)
  • Enchantments: Magic upgrades on the item
  • Lore: Custom text that displays when you hover over the item
  • NameTag: The custom display name

Why this matters: Items drive progression, rewards, and crafting. A leveling system gives items as rewards, an economy trades items for currency, a PvP arena drops loot when players die.

How It Works

The player's container is their inventory. When you want to give items:

  1. Create an ItemStack with the item type and amount
  2. Optionally add enchantments, names, or lore
  3. Add it to the player's container

The container automatically handles inventory mechanics - stacking items, rejecting items if full, etc.

import { world } from "@minecraft/server";

// Create a simple item
const item = new ItemStack("diamond_sword", 1);
player.container.addItem(item);

// Customize the item
const magicalApple = new ItemStack("golden_apple", 1);
magicalApple.nameTag = "§6Magical Apple";  // Gold-colored name
magicalApple.lore = ["§7Restores 2 hearts", "§7Use wisely"];  // Hover text

// Add enchantment
const enchantedSword = new ItemStack("diamond_sword", 1);
enchantedSword.enchantments.addEnchantment("sharpness", 3); // Sharpness III
enchantedSword.nameTag = "§cLegendary Blade";

// Try to add item - might fail if inventory is full
const success = player.container.addItem(enchantedSword);
if (!success) {
  player.sendMessage("§cYour inventory is full!");
}

Inventory Management

// **Count** how many of an item type a player has
function countItem(player, itemType) {
  let count = 0;
  for (let i = 0; i < player.container.size; i++) {
    const item = player.container.getItem(i);
    // item is null if slot is empty, use optional chaining (?.)
    if (item?.typeId === itemType) {
      count += item.amount; // Stack size (1-64)
    }
  }
  return count;
}

// **Remove** items from inventory (e.g., for a shop that charges currency)
function removeItems(player, itemType, amount) {
  let remaining = amount;
  
  // Loop through each inventory slot
  for (let i = 0; i < player.container.size && remaining > 0; i++) {
    const item = player.container.getItem(i);
    if (item?.typeId === itemType) {
      // Remove up to the stack size (or whatever we need)
      const toRemove = Math.min(item.amount, remaining);
      item.amount -= toRemove;
      remaining -= toRemove;
      
      // If stack is empty, clear the slot
      if (item.amount <= 0) {
        player.container.setItem(i, null);
      }
    }
  }
  
  return remaining === 0; // true if we removed enough, false if not enough items
}

// **Get all items of a type** (useful for merging stacks)
function getItemStacks(player, itemType) {
  const stacks = [];
  for (let i = 0; i < player.container.size; i++) {
    const item = player.container.getItem(i);
    if (item?.typeId === itemType) {
      stacks.push({ index: i, item });
    }
  }
  return stacks;
}

Item Events

// When a player uses an item (right-click with it)
world.afterEvents.itemUse.subscribe((event) => {
  const player = event.source;
  const item = event.itemStack;
  
  // Check if it's a special item
  if (item.nameTag?.includes("Magical")) {
    player.sendMessage(`§aYou used a magical item!`);
    // Could trigger effects, teleport, heal, etc.
  }
});

// When a player equips different armor
world.afterEvents.playerSpawn.subscribe((event) => {
  const player = event.player;
  const equippable = player.getComponent("equippable");
  
  if (equippable) {
    const helmet = equippable.getEquipment(EquipmentSlot.Head);
    if (helmet?.typeId === "diamond_helmet") {
      player.sendMessage("§bYou look fancy!");
    }
  }
});

Practical Examples

// Custom shop that charges currency (items as payment)
function buyItem(player, cost, itemToGive) {
  const diamondsNeeded = cost;
  const diamondCount = countItem(player, "diamond");
  
  if (diamondCount < diamondsNeeded) {
    player.sendMessage(`§cNeed ${diamondsNeeded} diamonds, you have ${diamondCount}`);
    return false;
  }
  
  // Remove payment
  removeItems(player, "diamond", diamondsNeeded);
  
  // Give item
  const item = new ItemStack(itemToGive, 1);
  player.container.addItem(item);
  player.sendMessage(`§aPurchased ${itemToGive}!`);
  return true;
}

// Loot drop when entity dies (like a boss)
world.afterEvents.entityDie.subscribe((event) => {
  const entity = event.deadEntity;
  
  if (entity.typeId === "minecraft:zombie") {
    const loot = new ItemStack("rotten_flesh", 2);
    const rare = Math.random() < 0.1; // 10% chance
    
    if (rare) {
      const rareItem = new ItemStack("diamond", 1);
      rareItem.nameTag = "§6Rare Drop";
      entity.dimension.spawnItem(rareItem, entity.location);
    } else {
      entity.dimension.spawnItem(loot, entity.location);
    }
  }
});

// Gift system (send items to other players)
function giftItem(giver, recipient, itemType, amount) {
  // Check giver has the item
  if (countItem(giver, itemType) < amount) {
    giver.sendMessage(`§cYou don't have enough!`);
    return false;
  }
  
  // Remove from giver
  removeItems(giver, itemType, amount);
  
  // Add to recipient
  const gift = new ItemStack(itemType, amount);
  recipient.container.addItem(gift);
  
  giver.sendMessage(`§aGifted ${amount}x ${itemType}`);
  recipient.sendMessage(`§a${giver.nameTag} gifted you ${amount}x ${itemType}!`);
  return true;
}

Best Practices

  • Check container has space before giving items - addItem() returns false if full
  • Use optional chaining (item?.property) when accessing items - slots can be null/undefined
  • Stack sizes matter - most items max at 64, but some (like tools) are 1
  • Always save to database if items should persist across server restarts
  • Validate amounts - check before removing items to prevent negative counts
Navigation