CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mineflayer

High-level JavaScript API for creating Minecraft bots with comprehensive world interaction, entity management, and gameplay automation

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

container-management.mddocs/

Container Management

Specialized interfaces for interacting with chests, furnaces, enchantment tables, villagers, and other container blocks with type-safe operations and automated management capabilities.

Capabilities

Chest Interaction

Open and interact with chests, trapped chests, and ender chests for storage management.

/**
 * Open a chest or chest-like container
 * @param chest - Chest block or entity to open
 * @param direction - Direction vector for interaction
 * @param cursorPos - Precise cursor position
 * @returns Promise resolving to Chest interface
 */
openChest(chest: Block | Entity, direction?: number, cursorPos?: Vec3): Promise<Chest>;

/**
 * Open any container (chest, dispenser, etc.)
 * @param container - Container block or entity
 * @param direction - Direction vector for interaction
 * @param cursorPos - Precise cursor position
 * @returns Promise resolving to container interface
 */
openContainer(chest: Block | Entity, direction?: Vec3, cursorPos?: Vec3): Promise<Chest | Dispenser>;

interface Chest extends Window<StorageEvents> {
  /** Close the chest */
  close(): void;
  
  /** Deposit items into chest */
  deposit(itemType: number, metadata: number | null, count: number | null): Promise<void>;
  
  /** Withdraw items from chest */
  withdraw(itemType: number, metadata: number | null, count: number | null): Promise<void>;
}

Usage Examples:

// Find and open nearest chest
const chest = bot.findBlock({
  matching: bot.registry.blocksByName.chest.id,
  maxDistance: 16
});

if (chest) {
  const chestWindow = await bot.openChest(chest);
  
  // Deposit cobblestone
  await chestWindow.deposit(
    bot.registry.itemsByName.cobblestone.id,
    null,
    64
  );
  
  // Withdraw diamonds
  await chestWindow.withdraw(
    bot.registry.itemsByName.diamond.id,
    null,
    5
  );
  
  chestWindow.close();
}

// Mass storage management
async function storeAllCobblestone() {
  const chest = await bot.openChest(chestBlock);
  const cobblestone = bot.inventory.items().filter(item => item.name === "cobblestone");
  
  for (const item of cobblestone) {
    await chest.deposit(item.type, item.metadata, item.count);
  }
  
  chest.close();
}

Furnace Operations

Interact with furnaces for smelting and cooking operations.

/**
 * Open a furnace for smelting operations
 * @param furnace - Furnace block to open
 * @returns Promise resolving to Furnace interface
 */
openFurnace(furnace: Block): Promise<Furnace>;

interface Furnace extends Window<FurnaceEvents> {
  /** Current fuel level (0-1) */
  fuel: number;
  /** Smelting progress (0-1) */
  progress: number;
  
  /** Close the furnace */
  close(): void;
  
  /** Take item from input slot */
  takeInput(): Promise<Item>;
  
  /** Take item from fuel slot */
  takeFuel(): Promise<Item>;
  
  /** Take item from output slot */
  takeOutput(): Promise<Item>;
  
  /** Put item in input slot */
  putInput(itemType: number, metadata: number | null, count: number): Promise<void>;
  
  /** Put item in fuel slot */
  putFuel(itemType: number, metadata: number | null, count: number): Promise<void>;
  
  /** Get current input item */
  inputItem(): Item;
  
  /** Get current fuel item */
  fuelItem(): Item;
  
  /** Get current output item */
  outputItem(): Item;
}

interface FurnaceEvents extends StorageEvents {
  /** Furnace state updated */
  update(): void;
}

Usage Examples:

// Automated smelting operation
const furnace = bot.findBlock({
  matching: bot.registry.blocksByName.furnace.id,
  maxDistance: 16
});

if (furnace) {
  const furnaceWindow = await bot.openFurnace(furnace);
  
  // Put iron ore in input
  await furnaceWindow.putInput(
    bot.registry.itemsByName.iron_ore.id,
    null,
    64
  );
  
  // Put coal as fuel
  await furnaceWindow.putFuel(
    bot.registry.itemsByName.coal.id,
    null,
    8
  );
  
  // Monitor smelting progress
  furnaceWindow.on("update", () => {
    console.log(`Fuel: ${(furnaceWindow.fuel * 100).toFixed(1)}%`);
    console.log(`Progress: ${(furnaceWindow.progress * 100).toFixed(1)}%`);
    
    // Take output when ready
    if (furnaceWindow.progress === 1 && furnaceWindow.outputItem()) {
      furnaceWindow.takeOutput().then(() => {
        console.log("Took smelted iron ingot!");
      });
    }
  });
}

// Batch smelting with automation
async function autoSmelt(inputItemType: number, fuelItemType: number, count: number) {
  const furnaceWindow = await bot.openFurnace(furnaceBlock);
  
  await furnaceWindow.putInput(inputItemType, null, count);
  await furnaceWindow.putFuel(fuelItemType, null, Math.ceil(count / 8));
  
  return new Promise<void>((resolve) => {
    let outputCount = 0;
    
    furnaceWindow.on("update", async () => {
      if (furnaceWindow.outputItem()) {
        await furnaceWindow.takeOutput();
        outputCount++;
        
        if (outputCount >= count) {
          furnaceWindow.close();
          resolve();
        }
      }
    });
  });
}

Dispenser and Dropper Management

Interact with dispensers and droppers for item distribution.

/**
 * Open a dispenser for item management
 * @param dispenser - Dispenser block to open
 * @returns Promise resolving to Dispenser interface
 */
openDispenser(dispenser: Block): Promise<Dispenser>;

interface Dispenser extends Window<StorageEvents> {
  /** Close the dispenser */
  close(): void;
  
  /** Deposit items into dispenser */
  deposit(itemType: number, metadata: number | null, count: number | null): Promise<void>;
  
  /** Withdraw items from dispenser */
  withdraw(itemType: number, metadata: number | null, count: number | null): Promise<void>;
}

Enchantment Table Operations

Use enchantment tables for enchanting items and managing lapis lazuli.

/**
 * Open an enchantment table for enchanting operations
 * @param enchantmentTable - Enchantment table block
 * @returns Promise resolving to EnchantmentTable interface
 */
openEnchantmentTable(enchantmentTable: Block): Promise<EnchantmentTable>;

interface EnchantmentTable extends Window<ConditionalStorageEvents> {
  /** Available enchantments */
  enchantments: Enchantment[];
  
  /** Close the enchantment table */
  close(): void;
  
  /** Get the target item being enchanted */
  targetItem(): Item;
  
  /** Apply enchantment by choice */
  enchant(choice: string | number): Promise<Item>;
  
  /** Take the target item */
  takeTargetItem(): Promise<Item>;
  
  /** Put item to enchant */
  putTargetItem(item: Item): Promise<Item>;
  
  /** Put lapis lazuli for enchanting */
  putLapis(item: Item): Promise<Item>;
}

interface ConditionalStorageEvents extends StorageEvents {
  /** Enchantment table is ready for use */
  ready(): void;
}

interface Enchantment {
  /** Required experience level */
  level: number;
  /** Expected enchantment result */
  expected: { enchant: number; level: number };
}

Usage Examples:

// Enchant a sword
const enchantmentTable = bot.findBlock({
  matching: bot.registry.blocksByName.enchanting_table.id,
  maxDistance: 16
});

if (enchantmentTable) {
  const table = await bot.openEnchantmentTable(enchantmentTable);
  
  // Wait for table to be ready
  await new Promise<void>((resolve) => {
    table.on("ready", resolve);
  });
  
  // Put sword to enchant
  const sword = bot.inventory.findItem("diamond_sword");
  if (sword) {
    await table.putTargetItem(sword);
    
    // Put lapis lazuli
    const lapis = bot.inventory.findItem("lapis_lazuli");
    if (lapis) {
      await table.putLapis(lapis);
      
      // Choose best enchantment
      if (table.enchantments.length > 0) {
        const bestEnchant = table.enchantments.reduce((best, current) => 
          current.level > best.level ? current : best
        );
        
        const enchantedItem = await table.enchant(bestEnchant.level);
        console.log(`Enchanted ${enchantedItem.name}!`);
      }
    }
  }
  
  table.close();
}

Anvil Operations

Use anvils for combining and renaming items.

/**
 * Open an anvil for item combination and renaming
 * @param anvil - Anvil block to open
 * @returns Promise resolving to Anvil interface
 */
openAnvil(anvil: Block): Promise<Anvil>;

interface Anvil {
  /** Combine two items */
  combine(itemOne: Item, itemTwo: Item, name?: string): Promise<void>;
  
  /** Rename an item */
  rename(item: Item, name?: string): Promise<void>;
}

Villager Trading

Trade with villagers using their trade offers.

/**
 * Open villager trading interface
 * @param villager - Villager entity to trade with
 * @returns Promise resolving to Villager interface
 */
openVillager(villager: Entity): Promise<Villager>;

/**
 * Execute a trade with a villager
 * @param villagerInstance - Villager trading window
 * @param tradeIndex - Trade offer index or ID
 * @param times - Number of times to execute trade
 * @returns Promise that resolves when trading completes
 */
trade(villagerInstance: Villager, tradeIndex: string | number, times?: number): Promise<void>;

interface Villager extends Window<ConditionalStorageEvents> {
  /** Available trade offers */
  trades: VillagerTrade[];
  
  /** Close trading interface */
  close(): void;
}

interface VillagerTrade {
  /** First input item required */
  inputItem1: Item;
  /** Output item offered */
  outputItem: Item;
  /** Second input item (optional) */
  inputItem2: Item | null;
  /** Whether second item is required */
  hasItem2: boolean;
  /** Whether this trade is disabled */
  tradeDisabled: boolean;
  /** Number of times trade has been used */
  nbTradeUses: number;
  /** Maximum number of times trade can be used */
  maximumNbTradeUses: number;
  /** Experience gained from trade */
  xp?: number;
  /** Special price adjustment */
  specialPrice?: number;
  /** Price multiplier */
  priceMultiplier?: number;
  /** Demand level */
  demand?: number;
  /** Real calculated price */
  realPrice?: number;
}

Usage Examples:

// Find and trade with librarian
const librarian = bot.nearestEntity(entity => 
  entity.name === "villager" && 
  entity.metadata[13] === 1 // Librarian profession
);

if (librarian) {
  const villagerWindow = await bot.openVillager(librarian);
  
  // Wait for trades to load
  await new Promise<void>((resolve) => {
    villagerWindow.on("ready", resolve);
  });
  
  // Find enchanted book trade
  const bookTrade = villagerWindow.trades.find(trade => 
    trade.outputItem.name === "enchanted_book"
  );
  
  if (bookTrade && !bookTrade.tradeDisabled) {
    // Check if we have required items
    const hasFirstItem = bot.inventory.count(bookTrade.inputItem1.type) >= bookTrade.inputItem1.count;
    const hasSecondItem = !bookTrade.hasItem2 || 
      bot.inventory.count(bookTrade.inputItem2!.type) >= bookTrade.inputItem2!.count;
    
    if (hasFirstItem && hasSecondItem) {
      await bot.trade(villagerWindow, 0, 1);
      console.log("Traded for enchanted book!");
    }
  }
  
  villagerWindow.close();
}

// Automated emerald farming with farmer
async function farmEmeralds() {
  const farmer = bot.nearestEntity(entity => 
    entity.name === "villager" && 
    entity.metadata[13] === 0 // Farmer profession
  );
  
  if (farmer) {
    const villagerWindow = await bot.openVillager(farmer);
    await new Promise<void>(resolve => villagerWindow.on("ready", resolve));
    
    // Find wheat -> emerald trade
    const wheatTrade = villagerWindow.trades.find(trade =>
      trade.inputItem1.name === "wheat" && trade.outputItem.name === "emerald"
    );
    
    if (wheatTrade) {
      const wheatCount = bot.inventory.count(bot.registry.itemsByName.wheat.id);
      const maxTrades = Math.min(
        Math.floor(wheatCount / wheatTrade.inputItem1.count),
        wheatTrade.maximumNbTradeUses - wheatTrade.nbTradeUses
      );
      
      if (maxTrades > 0) {
        await bot.trade(villagerWindow, 0, maxTrades);
        console.log(`Traded ${maxTrades} times for emeralds`);
      }
    }
    
    villagerWindow.close();
  }
}

Generic Container Operations

Open any type of container with automatic type detection.

/**
 * Open a block as a window/container
 * @param block - Block to open
 * @param direction - Interaction direction
 * @param cursorPos - Cursor position
 * @returns Promise resolving to Window interface
 */
openBlock(block: Block, direction?: Vec3, cursorPos?: Vec3): Promise<Window>;

/**
 * Open an entity as a window/container
 * @param entity - Entity to open
 * @param Class - Window class constructor
 * @returns Promise resolving to Window interface
 */
openEntity(entity: Entity, Class: new () => EventEmitter): Promise<Window>;

/**
 * Close any open window
 * @param window - Window to close
 */
closeWindow(window: Window): void;

Container Events

Monitor container interactions and state changes.

interface BotEvents {
  /** Container/window opened */
  windowOpen(window: Window): void;
  /** Container/window closed */
  windowClose(window: Window): void;
}

// Monitor all container operations
bot.on("windowOpen", (window) => {
  console.log(`Opened ${window.title} (${window.type})`);
});

bot.on("windowClose", (window) => {
  console.log(`Closed ${window.title}`);
});

docs

bot-management.md

communication.md

container-management.md

entity-management.md

game-mechanics.md

index.md

inventory-items.md

movement-physics.md

world-interaction.md

tile.json