or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bot-management.mdcommunication.mdcontainer-management.mdentity-management.mdgame-mechanics.mdindex.mdinventory-items.mdmovement-physics.mdworld-interaction.md

container-management.mddocs/

0

# Container Management

1

2

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

3

4

## Capabilities

5

6

### Chest Interaction

7

8

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

9

10

```typescript { .api }

11

/**

12

* Open a chest or chest-like container

13

* @param chest - Chest block or entity to open

14

* @param direction - Direction vector for interaction

15

* @param cursorPos - Precise cursor position

16

* @returns Promise resolving to Chest interface

17

*/

18

openChest(chest: Block | Entity, direction?: number, cursorPos?: Vec3): Promise<Chest>;

19

20

/**

21

* Open any container (chest, dispenser, etc.)

22

* @param container - Container block or entity

23

* @param direction - Direction vector for interaction

24

* @param cursorPos - Precise cursor position

25

* @returns Promise resolving to container interface

26

*/

27

openContainer(chest: Block | Entity, direction?: Vec3, cursorPos?: Vec3): Promise<Chest | Dispenser>;

28

29

interface Chest extends Window<StorageEvents> {

30

/** Close the chest */

31

close(): void;

32

33

/** Deposit items into chest */

34

deposit(itemType: number, metadata: number | null, count: number | null): Promise<void>;

35

36

/** Withdraw items from chest */

37

withdraw(itemType: number, metadata: number | null, count: number | null): Promise<void>;

38

}

39

```

40

41

**Usage Examples:**

42

43

```typescript

44

// Find and open nearest chest

45

const chest = bot.findBlock({

46

matching: bot.registry.blocksByName.chest.id,

47

maxDistance: 16

48

});

49

50

if (chest) {

51

const chestWindow = await bot.openChest(chest);

52

53

// Deposit cobblestone

54

await chestWindow.deposit(

55

bot.registry.itemsByName.cobblestone.id,

56

null,

57

64

58

);

59

60

// Withdraw diamonds

61

await chestWindow.withdraw(

62

bot.registry.itemsByName.diamond.id,

63

null,

64

5

65

);

66

67

chestWindow.close();

68

}

69

70

// Mass storage management

71

async function storeAllCobblestone() {

72

const chest = await bot.openChest(chestBlock);

73

const cobblestone = bot.inventory.items().filter(item => item.name === "cobblestone");

74

75

for (const item of cobblestone) {

76

await chest.deposit(item.type, item.metadata, item.count);

77

}

78

79

chest.close();

80

}

81

```

82

83

### Furnace Operations

84

85

Interact with furnaces for smelting and cooking operations.

86

87

```typescript { .api }

88

/**

89

* Open a furnace for smelting operations

90

* @param furnace - Furnace block to open

91

* @returns Promise resolving to Furnace interface

92

*/

93

openFurnace(furnace: Block): Promise<Furnace>;

94

95

interface Furnace extends Window<FurnaceEvents> {

96

/** Current fuel level (0-1) */

97

fuel: number;

98

/** Smelting progress (0-1) */

99

progress: number;

100

101

/** Close the furnace */

102

close(): void;

103

104

/** Take item from input slot */

105

takeInput(): Promise<Item>;

106

107

/** Take item from fuel slot */

108

takeFuel(): Promise<Item>;

109

110

/** Take item from output slot */

111

takeOutput(): Promise<Item>;

112

113

/** Put item in input slot */

114

putInput(itemType: number, metadata: number | null, count: number): Promise<void>;

115

116

/** Put item in fuel slot */

117

putFuel(itemType: number, metadata: number | null, count: number): Promise<void>;

118

119

/** Get current input item */

120

inputItem(): Item;

121

122

/** Get current fuel item */

123

fuelItem(): Item;

124

125

/** Get current output item */

126

outputItem(): Item;

127

}

128

129

interface FurnaceEvents extends StorageEvents {

130

/** Furnace state updated */

131

update(): void;

132

}

133

```

134

135

**Usage Examples:**

136

137

```typescript

138

// Automated smelting operation

139

const furnace = bot.findBlock({

140

matching: bot.registry.blocksByName.furnace.id,

141

maxDistance: 16

142

});

143

144

if (furnace) {

145

const furnaceWindow = await bot.openFurnace(furnace);

146

147

// Put iron ore in input

148

await furnaceWindow.putInput(

149

bot.registry.itemsByName.iron_ore.id,

150

null,

151

64

152

);

153

154

// Put coal as fuel

155

await furnaceWindow.putFuel(

156

bot.registry.itemsByName.coal.id,

157

null,

158

8

159

);

160

161

// Monitor smelting progress

162

furnaceWindow.on("update", () => {

163

console.log(`Fuel: ${(furnaceWindow.fuel * 100).toFixed(1)}%`);

164

console.log(`Progress: ${(furnaceWindow.progress * 100).toFixed(1)}%`);

165

166

// Take output when ready

167

if (furnaceWindow.progress === 1 && furnaceWindow.outputItem()) {

168

furnaceWindow.takeOutput().then(() => {

169

console.log("Took smelted iron ingot!");

170

});

171

}

172

});

173

}

174

175

// Batch smelting with automation

176

async function autoSmelt(inputItemType: number, fuelItemType: number, count: number) {

177

const furnaceWindow = await bot.openFurnace(furnaceBlock);

178

179

await furnaceWindow.putInput(inputItemType, null, count);

180

await furnaceWindow.putFuel(fuelItemType, null, Math.ceil(count / 8));

181

182

return new Promise<void>((resolve) => {

183

let outputCount = 0;

184

185

furnaceWindow.on("update", async () => {

186

if (furnaceWindow.outputItem()) {

187

await furnaceWindow.takeOutput();

188

outputCount++;

189

190

if (outputCount >= count) {

191

furnaceWindow.close();

192

resolve();

193

}

194

}

195

});

196

});

197

}

198

```

199

200

### Dispenser and Dropper Management

201

202

Interact with dispensers and droppers for item distribution.

203

204

```typescript { .api }

205

/**

206

* Open a dispenser for item management

207

* @param dispenser - Dispenser block to open

208

* @returns Promise resolving to Dispenser interface

209

*/

210

openDispenser(dispenser: Block): Promise<Dispenser>;

211

212

interface Dispenser extends Window<StorageEvents> {

213

/** Close the dispenser */

214

close(): void;

215

216

/** Deposit items into dispenser */

217

deposit(itemType: number, metadata: number | null, count: number | null): Promise<void>;

218

219

/** Withdraw items from dispenser */

220

withdraw(itemType: number, metadata: number | null, count: number | null): Promise<void>;

221

}

222

```

223

224

### Enchantment Table Operations

225

226

Use enchantment tables for enchanting items and managing lapis lazuli.

227

228

```typescript { .api }

229

/**

230

* Open an enchantment table for enchanting operations

231

* @param enchantmentTable - Enchantment table block

232

* @returns Promise resolving to EnchantmentTable interface

233

*/

234

openEnchantmentTable(enchantmentTable: Block): Promise<EnchantmentTable>;

235

236

interface EnchantmentTable extends Window<ConditionalStorageEvents> {

237

/** Available enchantments */

238

enchantments: Enchantment[];

239

240

/** Close the enchantment table */

241

close(): void;

242

243

/** Get the target item being enchanted */

244

targetItem(): Item;

245

246

/** Apply enchantment by choice */

247

enchant(choice: string | number): Promise<Item>;

248

249

/** Take the target item */

250

takeTargetItem(): Promise<Item>;

251

252

/** Put item to enchant */

253

putTargetItem(item: Item): Promise<Item>;

254

255

/** Put lapis lazuli for enchanting */

256

putLapis(item: Item): Promise<Item>;

257

}

258

259

interface ConditionalStorageEvents extends StorageEvents {

260

/** Enchantment table is ready for use */

261

ready(): void;

262

}

263

264

interface Enchantment {

265

/** Required experience level */

266

level: number;

267

/** Expected enchantment result */

268

expected: { enchant: number; level: number };

269

}

270

```

271

272

**Usage Examples:**

273

274

```typescript

275

// Enchant a sword

276

const enchantmentTable = bot.findBlock({

277

matching: bot.registry.blocksByName.enchanting_table.id,

278

maxDistance: 16

279

});

280

281

if (enchantmentTable) {

282

const table = await bot.openEnchantmentTable(enchantmentTable);

283

284

// Wait for table to be ready

285

await new Promise<void>((resolve) => {

286

table.on("ready", resolve);

287

});

288

289

// Put sword to enchant

290

const sword = bot.inventory.findItem("diamond_sword");

291

if (sword) {

292

await table.putTargetItem(sword);

293

294

// Put lapis lazuli

295

const lapis = bot.inventory.findItem("lapis_lazuli");

296

if (lapis) {

297

await table.putLapis(lapis);

298

299

// Choose best enchantment

300

if (table.enchantments.length > 0) {

301

const bestEnchant = table.enchantments.reduce((best, current) =>

302

current.level > best.level ? current : best

303

);

304

305

const enchantedItem = await table.enchant(bestEnchant.level);

306

console.log(`Enchanted ${enchantedItem.name}!`);

307

}

308

}

309

}

310

311

table.close();

312

}

313

```

314

315

### Anvil Operations

316

317

Use anvils for combining and renaming items.

318

319

```typescript { .api }

320

/**

321

* Open an anvil for item combination and renaming

322

* @param anvil - Anvil block to open

323

* @returns Promise resolving to Anvil interface

324

*/

325

openAnvil(anvil: Block): Promise<Anvil>;

326

327

interface Anvil {

328

/** Combine two items */

329

combine(itemOne: Item, itemTwo: Item, name?: string): Promise<void>;

330

331

/** Rename an item */

332

rename(item: Item, name?: string): Promise<void>;

333

}

334

```

335

336

### Villager Trading

337

338

Trade with villagers using their trade offers.

339

340

```typescript { .api }

341

/**

342

* Open villager trading interface

343

* @param villager - Villager entity to trade with

344

* @returns Promise resolving to Villager interface

345

*/

346

openVillager(villager: Entity): Promise<Villager>;

347

348

/**

349

* Execute a trade with a villager

350

* @param villagerInstance - Villager trading window

351

* @param tradeIndex - Trade offer index or ID

352

* @param times - Number of times to execute trade

353

* @returns Promise that resolves when trading completes

354

*/

355

trade(villagerInstance: Villager, tradeIndex: string | number, times?: number): Promise<void>;

356

357

interface Villager extends Window<ConditionalStorageEvents> {

358

/** Available trade offers */

359

trades: VillagerTrade[];

360

361

/** Close trading interface */

362

close(): void;

363

}

364

365

interface VillagerTrade {

366

/** First input item required */

367

inputItem1: Item;

368

/** Output item offered */

369

outputItem: Item;

370

/** Second input item (optional) */

371

inputItem2: Item | null;

372

/** Whether second item is required */

373

hasItem2: boolean;

374

/** Whether this trade is disabled */

375

tradeDisabled: boolean;

376

/** Number of times trade has been used */

377

nbTradeUses: number;

378

/** Maximum number of times trade can be used */

379

maximumNbTradeUses: number;

380

/** Experience gained from trade */

381

xp?: number;

382

/** Special price adjustment */

383

specialPrice?: number;

384

/** Price multiplier */

385

priceMultiplier?: number;

386

/** Demand level */

387

demand?: number;

388

/** Real calculated price */

389

realPrice?: number;

390

}

391

```

392

393

**Usage Examples:**

394

395

```typescript

396

// Find and trade with librarian

397

const librarian = bot.nearestEntity(entity =>

398

entity.name === "villager" &&

399

entity.metadata[13] === 1 // Librarian profession

400

);

401

402

if (librarian) {

403

const villagerWindow = await bot.openVillager(librarian);

404

405

// Wait for trades to load

406

await new Promise<void>((resolve) => {

407

villagerWindow.on("ready", resolve);

408

});

409

410

// Find enchanted book trade

411

const bookTrade = villagerWindow.trades.find(trade =>

412

trade.outputItem.name === "enchanted_book"

413

);

414

415

if (bookTrade && !bookTrade.tradeDisabled) {

416

// Check if we have required items

417

const hasFirstItem = bot.inventory.count(bookTrade.inputItem1.type) >= bookTrade.inputItem1.count;

418

const hasSecondItem = !bookTrade.hasItem2 ||

419

bot.inventory.count(bookTrade.inputItem2!.type) >= bookTrade.inputItem2!.count;

420

421

if (hasFirstItem && hasSecondItem) {

422

await bot.trade(villagerWindow, 0, 1);

423

console.log("Traded for enchanted book!");

424

}

425

}

426

427

villagerWindow.close();

428

}

429

430

// Automated emerald farming with farmer

431

async function farmEmeralds() {

432

const farmer = bot.nearestEntity(entity =>

433

entity.name === "villager" &&

434

entity.metadata[13] === 0 // Farmer profession

435

);

436

437

if (farmer) {

438

const villagerWindow = await bot.openVillager(farmer);

439

await new Promise<void>(resolve => villagerWindow.on("ready", resolve));

440

441

// Find wheat -> emerald trade

442

const wheatTrade = villagerWindow.trades.find(trade =>

443

trade.inputItem1.name === "wheat" && trade.outputItem.name === "emerald"

444

);

445

446

if (wheatTrade) {

447

const wheatCount = bot.inventory.count(bot.registry.itemsByName.wheat.id);

448

const maxTrades = Math.min(

449

Math.floor(wheatCount / wheatTrade.inputItem1.count),

450

wheatTrade.maximumNbTradeUses - wheatTrade.nbTradeUses

451

);

452

453

if (maxTrades > 0) {

454

await bot.trade(villagerWindow, 0, maxTrades);

455

console.log(`Traded ${maxTrades} times for emeralds`);

456

}

457

}

458

459

villagerWindow.close();

460

}

461

}

462

```

463

464

### Generic Container Operations

465

466

Open any type of container with automatic type detection.

467

468

```typescript { .api }

469

/**

470

* Open a block as a window/container

471

* @param block - Block to open

472

* @param direction - Interaction direction

473

* @param cursorPos - Cursor position

474

* @returns Promise resolving to Window interface

475

*/

476

openBlock(block: Block, direction?: Vec3, cursorPos?: Vec3): Promise<Window>;

477

478

/**

479

* Open an entity as a window/container

480

* @param entity - Entity to open

481

* @param Class - Window class constructor

482

* @returns Promise resolving to Window interface

483

*/

484

openEntity(entity: Entity, Class: new () => EventEmitter): Promise<Window>;

485

486

/**

487

* Close any open window

488

* @param window - Window to close

489

*/

490

closeWindow(window: Window): void;

491

```

492

493

### Container Events

494

495

Monitor container interactions and state changes.

496

497

```typescript { .api }

498

interface BotEvents {

499

/** Container/window opened */

500

windowOpen(window: Window): void;

501

/** Container/window closed */

502

windowClose(window: Window): void;

503

}

504

505

// Monitor all container operations

506

bot.on("windowOpen", (window) => {

507

console.log(`Opened ${window.title} (${window.type})`);

508

});

509

510

bot.on("windowClose", (window) => {

511

console.log(`Closed ${window.title}`);

512

});

513

```