Skip to main content

Overview

Minestom provides a comprehensive inventory system for managing items in containers, player inventories, and custom GUIs.

Inventory

Represents an inventory that can be viewed by multiple players.

Creating Inventories

Inventory chest = new Inventory(InventoryType.CHEST_3_ROW, "My Chest");

// Set items
chest.setItemStack(0, ItemStack.of(Material.DIAMOND));
chest.setItemStack(1, ItemStack.of(Material.EMERALD, 64));

// Open for player
player.openInventory(chest);

Constructor

Inventory
Inventory
Creates a new inventory

Item Management

setItemStack
void
Sets an ItemStack at the specified slotAutomatically sends updates to all viewers
getItemStack
ItemStack
Gets the ItemStack at the specified slot
addItemStack
boolean
Adds an ItemStack to the inventoryReturns true if the item was successfully added
takeItemStack
boolean
Takes an ItemStack from the inventory
replaceItemStack
void
Replaces an ItemStack using an operator
clear
void
Clears all items from the inventory and updates viewers
getItemStacks
ItemStack[]
Gets a copy of all items in the inventory
copyContents
void
Copies items from an array into this inventory

Viewers

addViewer
boolean
Adds a viewer (does NOT open the inventory)Use player.openInventory(inventory) to actually open it
removeViewer
boolean
Removes a viewer (does NOT close the inventory)Use player.closeInventory() to close it
getViewers
Set<Player>
Gets all players currently viewing this inventory
update
void
Refreshes the inventory for all viewers

Properties

getInventoryType
InventoryType
Gets the inventory type
getTitle
Component
Gets the inventory title
setTitle
void
Changes the inventory titleRe-opens the inventory for all viewers
getSize
int
Gets the total size of the inventory (number of slots)
getWindowId
byte
Gets the window ID used by the client to identify this inventory

Click Handling

setClickProcessor
void
Sets a custom click processor for handling inventory clicks
addInventoryCondition
void
Adds a click condition/handler

PlayerInventory

Represents a player’s inventory (extends AbstractInventory).

Accessing Player Inventory

Player player = /* get player */;
PlayerInventory inventory = player.getInventory();

// Main hand
ItemStack mainHand = inventory.getItemInMainHand();
inventory.setItemInMainHand(ItemStack.of(Material.DIAMOND_SWORD));

// Armor
itemStack helmet = inventory.getHelmet();
inventory.setHelmet(ItemStack.of(Material.DIAMOND_HELMET));

Equipment Methods

getEquipment
ItemStack
Gets equipment in a specific slot
setEquipment
void
Sets equipment in a specific slot

Cursor Item

getCursorItem
ItemStack
Gets the item in the player’s cursor (what they’re dragging)
setCursorItem
void
Sets the cursor item

Constants

PlayerInventory.INVENTORY_SIZE
int
Total inventory size (46 slots)
PlayerInventory.INNER_INVENTORY_SIZE
int
Main inventory size excluding armor/offhand (36 slots)

InventoryType

Enum representing different inventory types.

Available Types

CHEST_1_ROW
InventoryType
9-slot chest (1 row)
CHEST_2_ROW
InventoryType
18-slot chest (2 rows)
CHEST_3_ROW
InventoryType
27-slot chest (3 rows)
CHEST_4_ROW
InventoryType
36-slot chest (4 rows)
CHEST_5_ROW
InventoryType
45-slot chest (5 rows)
CHEST_6_ROW
InventoryType
54-slot chest (6 rows)
HOPPER
InventoryType
5-slot hopper
FURNACE
InventoryType
3-slot furnace
CRAFTING
InventoryType
10-slot crafting table
ANVIL
InventoryType
3-slot anvil
ENCHANTMENT
InventoryType
2-slot enchanting table
BREWING_STAND
InventoryType
5-slot brewing stand
BEACON
InventoryType
1-slot beacon
SHULKER_BOX
InventoryType
27-slot shulker box
And more: BLAST_FURNACE, SMOKER, LOOM, GRINDSTONE, SMITHING, CARTOGRAPHY, STONE_CUTTER, etc.

Methods

getSize
int
Gets the number of slots in this inventory type
getWindowType
int
Gets the protocol window type ID

Usage Examples

Custom GUI Menu

Inventory menu = new Inventory(InventoryType.CHEST_3_ROW, "Choose an option");

// Set border
ItemStack border = ItemStack.of(Material.BLACK_STAINED_GLASS_PANE);
for (int i : new int[]{0,1,2,3,5,6,7,8,9,17,18,19,20,21,23,24,25,26}) {
    menu.setItemStack(i, border);
}

// Add options
menu.setItemStack(11, ItemStack.builder(Material.DIAMOND_SWORD)
    .displayName(Component.text("PvP Arena"))
    .build());
    
menu.setItemStack(13, ItemStack.builder(Material.GRASS_BLOCK)
    .displayName(Component.text("Build World"))
    .build());
    
menu.setItemStack(15, ItemStack.builder(Material.ENDER_PEARL)
    .displayName(Component.text("Hub"))
    .build());

// Handle clicks
menu.addInventoryCondition((player, slot, clickType, result) -> {
    result.setCancel(true); // Prevent taking items
    
    switch (slot) {
        case 11 -> player.sendMessage("Teleporting to PvP...");
        case 13 -> player.sendMessage("Teleporting to Build...");
        case 15 -> player.sendMessage("Teleporting to Hub...");
    }
    
    player.closeInventory();
});

player.openInventory(menu);

Paginated Inventory

public class PagedInventory {
    private final List<ItemStack> items;
    private int currentPage = 0;
    
    public Inventory createPage(int page) {
        Inventory inv = new Inventory(InventoryType.CHEST_6_ROW, "Page " + (page + 1));
        
        int startIdx = page * 45;
        int endIdx = Math.min(startIdx + 45, items.size());
        
        for (int i = startIdx; i < endIdx; i++) {
            inv.setItemStack(i - startIdx, items.get(i));
        }
        
        // Navigation
        if (page > 0) {
            inv.setItemStack(45, ItemStack.of(Material.ARROW)
                .withDisplayName(Component.text("Previous")));
        }
        if (endIdx < items.size()) {
            inv.setItemStack(53, ItemStack.of(Material.ARROW)
                .withDisplayName(Component.text("Next")));
        }
        
        return inv;
    }
}

Event Listening

Inventory shop = new Inventory(InventoryType.CHEST_3_ROW, "Shop");

// Listen to the inventory's event node
shop.eventNode().addListener(InventoryPreClickEvent.class, event -> {
    event.setCancelled(true); // Cancel all clicks
    
    Player player = event.getPlayer();
    int slot = event.getSlot();
    
    // Handle purchase logic
});

// Or use global event handler
MinecraftServer.getGlobalEventHandler()
    .addListener(InventoryPreClickEvent.class, event -> {
        if (event.getInventory() == shop) {
            // Handle shop clicks
        }
    });
Use player.openInventory(inventory) to open and player.closeInventory() to close inventories. Direct viewer management with addViewer/removeViewer does not send open/close packets.

Build docs developers (and LLMs) love