High-level JavaScript API for creating Minecraft bots with comprehensive world interaction, entity management, and gameplay automation
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Specialized interfaces for interacting with chests, furnaces, enchantment tables, villagers, and other container blocks with type-safe operations and automated management capabilities.
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();
}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();
}
}
});
});
}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>;
}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();
}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>;
}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();
}
}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;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}`);
});