Inventory System Overview
Inventory System Overview
Section titled “Inventory System Overview”The Inventory System manages items, item stacks, and containers for players and other entities. It provides a flexible, transaction-based approach to item manipulation.
Package Location
Section titled “Package Location”- ItemStack:
com.hypixel.hytale.server.core.inventory.ItemStack - Containers:
com.hypixel.hytale.server.core.inventory.container - Transactions:
com.hypixel.hytale.server.core.inventory.transaction - Filters:
com.hypixel.hytale.server.core.inventory.container.filter
Core Classes
Section titled “Core Classes”| Class | Description |
|---|---|
ItemStack | Represents a stack of items |
ItemContainer | Abstract base class for item storage |
SimpleItemContainer | Basic fixed-size container implementation |
CombinedItemContainer | Combines multiple containers into one virtual view |
Transaction | Interface for inventory operation results |
Inventory | Player inventory with multiple sections |
ItemStack
Section titled “ItemStack”ItemStack represents one or more items of the same type. ItemStacks are effectively immutable for most purposes — methods like withQuantity() and withDurability() return new instances rather than mutating.
Creating Item Stacks
Section titled “Creating Item Stacks”// single itemItemStack sword = new ItemStack("Sword_Iron");
// stack of itemsItemStack arrows = new ItemStack("Arrow_Standard", 64);
// with metadataBsonDocument metadata = new BsonDocument();metadata.put("enchantment", new BsonString("fire"));ItemStack enchantedSword = new ItemStack("Sword_Iron", 1, metadata);
// with durabilityItemStack damagedSword = new ItemStack( "Sword_Iron", // item ID 1, // quantity 50.0, // current durability 100.0, // max durability null // metadata);ItemStack Properties
Section titled “ItemStack Properties”| Property | Type | Description |
|---|---|---|
itemId | String | Item type identifier |
quantity | int | Number of items in stack |
durability | double | Current durability |
maxDurability | double | Maximum durability |
metadata | BsonDocument | Custom item data (nullable) |
ItemStack Methods
Section titled “ItemStack Methods”// get propertiesString itemId = stack.getItemId();int quantity = stack.getQuantity();double durability = stack.getDurability();double maxDurability = stack.getMaxDurability();
// get item definitionItem item = stack.getItem();
// check stateboolean empty = stack.isEmpty();boolean broken = stack.isBroken();boolean unbreakable = stack.isUnbreakable();
// check if can stack with another (same type, durability, metadata)boolean stackable = stack.isStackableWith(otherStack);
// check if same type (ignores durability differences)boolean equivalent = stack.isEquivalentType(otherStack);
// get block key (for placeable items)String blockKey = stack.getBlockKey();
// create modified copies (immutable pattern)ItemStack moreDamaged = stack.withDurability(25.0);ItemStack increased = stack.withIncreasedDurability(10.0);ItemStack restored = stack.withRestoredDurability(100.0);ItemStack halfStack = stack.withQuantity(32);ItemStack withMeta = stack.withMetadata(newMetadata);ItemStack variant = stack.withState("Filled_Water");Empty ItemStack
Section titled “Empty ItemStack”// the empty item stack singletonItemStack empty = ItemStack.EMPTY;
// check if emptyif (stack.isEmpty()) { // no items}
// static null-safe checkboolean isEmpty = ItemStack.isEmpty(stack);Metadata Access
Section titled “Metadata Access”// read metadata valuesBsonDocument meta = stack.getMetadata();String value = stack.getFromMetadataOrNull("key", Codec.STRING);
// create stack with modified metadataItemStack updated = stack.withMetadata("key", new BsonString("value"));ItemStack updated2 = stack.withMetadata("key", Codec.STRING, "value");ItemContainer
Section titled “ItemContainer”ItemContainer is the abstract base class for all item storage. All modification operations return transaction objects.
Container Types
Section titled “Container Types”| Type | Description |
|---|---|
SimpleItemContainer | Basic fixed-size container with slot filters |
ItemStackItemContainer | Single-slot container |
CombinedItemContainer | Multiple containers viewed as one |
DelegateItemContainer | Wraps another container |
EmptyItemContainer | No storage (always empty) |
Reading Slots
Section titled “Reading Slots”// get capacityshort capacity = container.getCapacity();
// get slot contents (null if empty)ItemStack item = container.getItemStack(slot);
// check if container is emptyboolean empty = container.isEmpty();Adding Items
Section titled “Adding Items”// add item stack to any available slotItemStackTransaction tx = container.addItemStack(itemStack);ItemStack remainder = tx.getRemainder();
// with full optionscontainer.addItemStack( itemStack, false, // allOrNothing - if true, fails if can't add all false, // fullStacks - if true, only fills new slots (no merging) true // filter - respect slot filters);
// add to specific slotItemStackSlotTransaction slotTx = container.addItemStackToSlot(slot, itemStack);
// add multiple stacks at onceListTransaction<ItemStackTransaction> tx = container.addItemStacks(itemStackList);
// check if items can be added before tryingboolean canAdd = container.canAddItemStack(itemStack);boolean canAddToSlot = container.canAddItemStackToSlot(slot, itemStack, false, true);Setting / Replacing Slots
Section titled “Setting / Replacing Slots”// set a specific slot's contentsItemStackSlotTransaction tx = container.setItemStackForSlot(slot, itemStack);
// replace item in slot (verifies expected item is there)ItemStackSlotTransaction tx = container.replaceItemStackInSlot(slot, expectedItem, newItem);Removing Items
Section titled “Removing Items”// remove from slot (entire stack)SlotTransaction tx = container.removeItemStackFromSlot(slot);
// remove specific quantity from slotItemStackSlotTransaction tx = container.removeItemStackFromSlot(slot, quantity);
// remove a matching item stack from anywhere in containerItemStackTransaction tx = container.removeItemStack(itemStack);
// remove by materialMaterialTransaction materialTx = container.removeMaterial(materialQuantity);
// remove by tag indexTagTransaction tagTx = container.removeTag(tagIndex, quantity);
// remove by resourceResourceTransaction resourceTx = container.removeResource(resourceQuantity);
// remove all itemsList<ItemStack> removed = container.removeAllItemStacks();
// drop all items (respects drop filters)List<ItemStack> dropped = container.dropAllItemStacks();
// clear all slotsClearTransaction cleared = container.clear();Checking Contents
Section titled “Checking Contents”// check if can remove itemboolean canRemove = container.canRemoveItemStack(itemStack);
// check if can remove materialboolean canRemoveMat = container.canRemoveMaterial(materialQuantity);
// check if can remove tagboolean canRemoveTag = container.canRemoveTag(tagIndex, quantity);
// count items matching a predicateint count = container.countItemStacks(itemStack -> itemStack.getItemId().equals("Arrow_Standard"));
// check for stackable itemsboolean hasStackable = container.containsItemStacksStackableWith(itemStack);
// iterate non-empty slotscontainer.forEach((slot, itemStack) -> { // process each non-empty slot});Container Filters
Section titled “Container Filters”Filters control what items can go in which slots:
// set global filter (allow all, deny all, input only, output only)container.setGlobalFilter(FilterType.ALLOW_ALL);
// set slot-specific filtercontainer.setSlotFilter(FilterActionType.ADD, slot, slotFilter);container.setSlotFilter(FilterActionType.REMOVE, slot, slotFilter);container.setSlotFilter(FilterActionType.DROP, slot, slotFilter);Built-in Filters
Section titled “Built-in Filters”| Filter | Description |
|---|---|
ArmorSlotAddFilter | Restricts slot to matching armor type |
NoDuplicateFilter | Prevents duplicate items in container |
SlotFilter.DENY | Denies all operations on the slot |
Container Events
Section titled “Container Events”// register for change eventscontainer.registerChangeEvent(event -> { Transaction transaction = event.transaction(); ItemContainer source = event.container();});
// with prioritycontainer.registerChangeEvent(EventPriority.NORMAL, event -> { // handle changes});Cloning Containers
Section titled “Cloning Containers”clone() is defined on ItemContainer and implemented by SimpleItemContainer. It creates a deep copy of the container with the same items and filters.
// clone a SimpleItemContainerSimpleItemContainer copy = simpleContainer.clone();Transactions
Section titled “Transactions”All inventory operations return a transaction object describing what happened. Check succeeded() to see if the operation worked.
Transaction Types
Section titled “Transaction Types”| Transaction | Description |
|---|---|
ItemStackTransaction | Add/remove item stack result |
ItemStackSlotTransaction | Slot-specific item operation result |
MaterialTransaction | Material-based operation result |
TagTransaction | Tag-based operation result |
ResourceTransaction | Resource-based operation result |
MoveTransaction | Move between containers result |
ClearTransaction | Clear container result |
ListTransaction | Wraps a list of sub-transactions |
SlotTransaction | Single slot modification result |
Transaction Results
Section titled “Transaction Results”// item stack transactionItemStackTransaction tx = container.addItemStack(itemStack);boolean success = tx.succeeded();ItemStack remainder = tx.getRemainder();List<ItemStackSlotTransaction> slots = tx.getSlotTransactions();
// check if everything was addedif (ItemStack.isEmpty(tx.getRemainder())) { // all items were added}Moving Items
Section titled “Moving Items”Between Containers
Section titled “Between Containers”The main method for moving items is moveItemStackFromSlot:
// move entire stack from a slot to another containerMoveTransaction<ItemStackTransaction> move = sourceContainer.moveItemStackFromSlot( slot, // source slot targetContainer // destination);
// move specific quantityMoveTransaction<ItemStackTransaction> move = sourceContainer.moveItemStackFromSlot( slot, // source slot quantity, // how many to move targetContainer // destination);
// move from slot to specific slot in targetMoveTransaction<SlotTransaction> move = sourceContainer.moveItemStackFromSlotToSlot( fromSlot, quantity, targetContainer, toSlot);Move All Items
Section titled “Move All Items”// move all items to target container(s)ListTransaction<MoveTransaction<ItemStackTransaction>> tx = sourceContainer.moveAllItemStacksTo(targetContainerA, targetContainerB);
// quick-stack: only move items that already exist in the targetListTransaction<MoveTransaction<ItemStackTransaction>> tx = sourceContainer.quickStackTo(targetContainer);Swap Container Slots
Section titled “Swap Container Slots”// swap a range of slots between containersListTransaction<MoveTransaction<SlotTransaction>> tx = containerA.swapItems( srcPos, // source start slot containerB, // other container destPos, // destination start slot length // number of slots to swap);Sorting
Section titled “Sorting”// sort container itemscontainer.sortItems(SortType.NAME);Sort Types
Section titled “Sort Types”| Sort Type | Description |
|---|---|
SortType.NAME | Alphabetical by translation key |
SortType.TYPE | By item type (weapon, armor, tool, item, special) |
SortType.RARITY | By quality tier (highest first), then by name |
Sorting also consolidates partial stacks of the same item into full stacks where possible.
Player Inventory
Section titled “Player Inventory”The player inventory is split into multiple sections:
// access from player entityInventory inventory = player.getInventory();
// inventory sectionsItemContainer hotbar = inventory.getHotbar();ItemContainer storage = inventory.getStorage();ItemContainer armor = inventory.getArmor();ItemContainer utility = inventory.getUtility();ItemContainer tools = inventory.getTools();ItemContainer backpack = inventory.getBackpack();
// active slotbyte activeSlot = inventory.getActiveHotbarSlot();ItemStack heldItem = inventory.getItemInHand();ItemStack utilityItem = inventory.getUtilityItem();Section Capacities
Section titled “Section Capacities”| Section | Default Capacity |
|---|---|
| Hotbar | 9 |
| Storage | 36 (4 rows x 9 columns) |
| Armor | 5 (head, chest, hands, legs + extra) |
| Utility | 4 |
| Tools | 23 |
Combined Containers
Section titled “Combined Containers”The inventory provides pre-built CombinedItemContainer views for common multi-section operations:
// hotbar + storage (hotbar first priority)CombinedItemContainer hotbarFirst = inventory.getCombinedHotbarFirst();
// storage + hotbar (storage first priority)CombinedItemContainer storageFirst = inventory.getCombinedStorageFirst();
// all sections combinedCombinedItemContainer everything = inventory.getCombinedEverything();Sorting Player Storage
Section titled “Sorting Player Storage”inventory.sortStorage(SortType.NAME);Item Context
Section titled “Item Context”ItemContext bundles a container, slot, and item stack together for passing around item operation context:
// create contextItemContext context = new ItemContext(container, slot, itemStack);
// get context infoItemContainer container = context.getContainer();short slot = context.getSlot();ItemStack item = context.getItemStack();Serialization
Section titled “Serialization”// codec for persistenceBuilderCodec<ItemStack> codec = ItemStack.CODEC;
// convert to network packetItemWithAllMetadata packet = itemStack.toPacket();
// container to protocolMap<Integer, ItemWithAllMetadata> protocolMap = container.toProtocolMap();InventorySection section = container.toPacket();Best Practices
Section titled “Best Practices”- Use transactions: Always check
succeeded()andgetRemainder()to handle partial operations - Respect filters: Pass
filter=trueunless you intentionally need to bypass restrictions - Immutable ItemStacks: Use
withQuantity(),withDurability(), etc. to create modified copies instead of trying to mutate - Handle empty stacks: Always check for
isEmpty()or use the null-safeItemStack.isEmpty(stack)
Related
Section titled “Related”- Item Assets - Item type definitions
- Entity System - Player inventory access
- Events - Container events