Inventory and Items System
The Hytale inventory system provides comprehensive APIs for managing player inventories, item containers, and item manipulation.
Architecture
Section titled “Architecture”Inventory (Player inventory manager)├── ItemContainer (Storage, Hotbar, Armor, Utility, Backpack)│ └── ItemStack (Individual item instances)├── HotbarManager (Saved hotbar presets)└── Equipment (Visual equipment slots)
ItemModule (Item registration and utilities)├── Item (Asset definition)│ ├── ItemWeapon│ ├── ItemArmor│ ├── ItemTool│ └── ItemUtility└── ItemContext (Item interaction context)Inventory Class
Section titled “Inventory Class”The Inventory class manages a living entity’s complete inventory system with multiple sections.
Inventory Sections
Section titled “Inventory Sections”| Section | ID Constant | Capacity | Description |
|---|---|---|---|
| Hotbar | HOTBAR_SECTION_ID (-1) | 9 | Quick-access slots |
| Storage | STORAGE_SECTION_ID (-2) | 36 | Main inventory (4x9 grid) |
| Armor | ARMOR_SECTION_ID (-3) | 4 | Equipment slots |
| Utility | UTILITY_SECTION_ID (-5) | 4 | Utility item slots |
| Tools | TOOLS_SECTION_ID (-8) | 23 | Tool slots (deprecated) |
| Backpack | BACKPACK_SECTION_ID (-9) | Variable | Extra storage |
Accessing Inventory
Section titled “Accessing Inventory”import com.hypixel.hytale.server.core.inventory.Inventory;import com.hypixel.hytale.server.core.inventory.ItemStack;import com.hypixel.hytale.server.core.inventory.container.ItemContainer;import com.hypixel.hytale.server.core.entity.entities.Player;
// Get player's inventoryPlayer player = // ... obtain player referenceInventory inventory = player.getInventory();
// Access individual sectionsItemContainer hotbar = inventory.getHotbar();ItemContainer storage = inventory.getStorage();ItemContainer armor = inventory.getArmor();ItemContainer utility = inventory.getUtility();ItemContainer backpack = inventory.getBackpack();
// Get section by ID (useful for window/container interactions)ItemContainer section = inventory.getSectionById(Inventory.HOTBAR_SECTION_ID);Active Slot Management
Section titled “Active Slot Management”// Get/set active hotbar slot (0-8)byte activeSlot = inventory.getActiveHotbarSlot();inventory.setActiveHotbarSlot((byte) 3);
// Get item currently in handItemStack itemInHand = inventory.getItemInHand();ItemStack activeHotbarItem = inventory.getActiveHotbarItem();
// Utility slot managementbyte utilitySlot = inventory.getActiveUtilitySlot();inventory.setActiveUtilitySlot((byte) 1);ItemStack utilityItem = inventory.getUtilityItem();Moving Items
Section titled “Moving Items”// Move item between sectionsinventory.moveItem( Inventory.STORAGE_SECTION_ID, // From section 5, // From slot 32, // Quantity Inventory.HOTBAR_SECTION_ID, // To section 0 // To slot);
// Smart move (auto-equip armor, merge stacks)inventory.smartMoveItem( Inventory.STORAGE_SECTION_ID, 10, 1, SmartMoveType.EquipOrMergeStack);
// Take all items from a container windowinventory.takeAll(windowSectionId);
// Quick stack matching items to containerinventory.quickStack(windowSectionId);Inventory Operations
Section titled “Inventory Operations”// Clear all inventory sectionsinventory.clear();
// Drop all items (returns list of dropped ItemStacks)List<ItemStack> droppedItems = inventory.dropAllItemStacks();
// Sort storage inventoryinventory.sortStorage(SortType.NAME);
// Check for broken itemsboolean hasBroken = inventory.containsBrokenItem();
// Resize backpack (overflow goes to remainder list)List<ItemStack> remainder = new ArrayList<>();inventory.resizeBackpack((short) 27, remainder);Combined Containers
Section titled “Combined Containers”The inventory provides pre-built combined containers for efficient item operations:
// Hotbar first, then storage (for pickups)CombinedItemContainer hotbarFirst = inventory.getCombinedHotbarFirst();
// Storage first, then hotbarCombinedItemContainer storageFirst = inventory.getCombinedStorageFirst();
// All inventory sections combinedCombinedItemContainer everything = inventory.getCombinedEverything();
// Get appropriate container for item pickup based on player settingsItemContainer pickupContainer = inventory.getContainerForItemPickup(item, playerSettings);ItemStack
Section titled “ItemStack”ItemStack represents a stack of items with quantity, durability, and metadata.
Creating ItemStacks
Section titled “Creating ItemStacks”import com.hypixel.hytale.server.core.inventory.ItemStack;
// Basic creationItemStack stack = new ItemStack("Stone");ItemStack stackWithQuantity = new ItemStack("Stone", 64);
// With metadataBsonDocument metadata = new BsonDocument();metadata.put("CustomData", new BsonString("value"));ItemStack stackWithMeta = new ItemStack("Stone", 64, metadata);
// With full parametersItemStack fullStack = new ItemStack( "DiamondSword", // Item ID 1, // Quantity 100.0, // Current durability 100.0, // Max durability metadata // Metadata);
// Empty stack constantItemStack empty = ItemStack.EMPTY;ItemStack Properties
Section titled “ItemStack Properties”// Basic propertiesString itemId = stack.getItemId();int quantity = stack.getQuantity();Item item = stack.getItem();
// Durabilitydouble durability = stack.getDurability();double maxDurability = stack.getMaxDurability();boolean isBroken = stack.isBroken();boolean isUnbreakable = stack.isUnbreakable();
// Validationboolean isEmpty = stack.isEmpty();boolean isValid = stack.isValid();
// Get associated block (for placeable items)String blockKey = stack.getBlockKey();Immutable Modification
Section titled “Immutable Modification”ItemStack is immutable - modification methods return new instances:
// Modify quantity (returns null if quantity would be 0)ItemStack modified = stack.withQuantity(32);
// Modify durabilityItemStack damaged = stack.withDurability(50.0);ItemStack repaired = stack.withIncreasedDurability(25.0);ItemStack fullyRepaired = stack.withRestoredDurability(100.0);ItemStack upgraded = stack.withMaxDurability(150.0);
// Change item stateItemStack newState = stack.withState("activated");
// Modify metadataItemStack withMeta = stack.withMetadata(metadata);ItemStack withKeyedMeta = stack.withMetadata("CustomKey", Codec.STRING, "value");Stacking and Comparison
Section titled “Stacking and Comparison”// Check if items can stack togetherboolean canStack = stack1.isStackableWith(stack2);
// Check if same item type (ignoring quantity/durability)boolean sameType = stack1.isEquivalentType(stack2);
// Static utility methodsboolean isEmpty = ItemStack.isEmpty(stack);boolean stackable = ItemStack.isStackableWith(stack1, stack2);boolean equivalent = ItemStack.isEquivalentType(stack1, stack2);boolean sameItem = ItemStack.isSameItemType(stack1, stack2);Metadata Access
Section titled “Metadata Access”// Read metadataString value = stack.getFromMetadataOrNull("CustomKey", Codec.STRING);MyData data = stack.getFromMetadataOrDefault("DataKey", MyData.CODEC);
// Using keyed codecKeyedCodec<String> KEY = new KeyedCodec<>("CustomKey", Codec.STRING);String keyedValue = stack.getFromMetadataOrNull(KEY);ItemContainer
Section titled “ItemContainer”ItemContainer is the base class for all inventory storage systems.
Basic Operations
Section titled “Basic Operations”import com.hypixel.hytale.server.core.inventory.container.ItemContainer;import com.hypixel.hytale.server.core.inventory.container.SimpleItemContainer;import com.hypixel.hytale.server.core.inventory.transaction.*;
// Create a containerItemContainer container = new SimpleItemContainer((short) 27);
// Get capacityshort capacity = container.getCapacity();
// Check if emptyboolean isEmpty = container.isEmpty();
// Clear all itemsClearTransaction clearTx = container.clear();Slot Operations
Section titled “Slot Operations”// Get item from slotItemStack item = container.getItemStack((short) 5);
// Set item in slotItemStackSlotTransaction setTx = container.setItemStackForSlot((short) 5, itemStack);
// Remove item from slotSlotTransaction removeTx = container.removeItemStackFromSlot((short) 5);
// Remove specific quantityItemStackSlotTransaction removeTx = container.removeItemStackFromSlot( (short) 5, // Slot 16, // Quantity true, // All or nothing true // Apply filters);Adding Items
Section titled “Adding Items”// Add item to first available slotItemStackTransaction addTx = container.addItemStack(itemStack);
// Add with optionsItemStackTransaction addTx = container.addItemStack( itemStack, false, // allOrNothing - if true, fails if can't add all false, // fullStacks - if true, only creates new stacks true // filter - apply slot filters);
// Add to specific slotItemStackSlotTransaction slotTx = container.addItemStackToSlot( (short) 0, // Slot itemStack, false, // allOrNothing true // filter);
// Check if item can be addedboolean canAdd = container.canAddItemStack(itemStack);boolean canAddAll = container.canAddItemStack(itemStack, false, true);
// Add multiple itemsList<ItemStack> items = List.of(stack1, stack2, stack3);ListTransaction<ItemStackTransaction> addAllTx = container.addItemStacks(items);Removing Items
Section titled “Removing Items”// Remove matching item stackItemStackTransaction removeTx = container.removeItemStack(itemStack);
// Remove with optionsItemStackTransaction removeTx = container.removeItemStack( itemStack, true, // allOrNothing true // filter);
// Check if item can be removedboolean canRemove = container.canRemoveItemStack(itemStack);
// Remove all items (returns removed stacks)List<ItemStack> removed = container.removeAllItemStacks();
// Drop all items (respects drop filters)List<ItemStack> dropped = container.dropAllItemStacks();Moving Items Between Containers
Section titled “Moving Items Between Containers”// Move item from one container to anotherMoveTransaction<ItemStackTransaction> moveTx = container.moveItemStackFromSlot( (short) 5, // From slot otherContainer // To container);
// Move specific quantityMoveTransaction<ItemStackTransaction> moveTx = container.moveItemStackFromSlot( (short) 5, // From slot 32, // Quantity otherContainer, // To container false, // allOrNothing true // filter);
// Move to specific slotMoveTransaction<SlotTransaction> moveTx = container.moveItemStackFromSlotToSlot( (short) 5, // From slot 32, // Quantity otherContainer, // To container (short) 0 // To slot);
// Move all itemsListTransaction<MoveTransaction<ItemStackTransaction>> moveAllTx = container.moveAllItemStacksTo(otherContainer);
// Quick stack (only matching items)container.quickStackTo(otherContainer);
// Swap items between containerscontainer.swapItems((short) 0, otherContainer, (short) 0, (short) 9);Sorting and Iteration
Section titled “Sorting and Iteration”// Sort itemsListTransaction<SlotTransaction> sortTx = container.sortItems(SortType.NAME);
// Iterate over itemscontainer.forEach((slot, itemStack) -> { System.out.println("Slot " + slot + ": " + itemStack.getItemId());});
// Count items matching predicateint count = container.countItemStacks(stack -> stack.getItemId().equals("Stone"));
// Check if contains stackable itemsboolean hasStackable = container.containsItemStacksStackableWith(itemStack);Change Events
Section titled “Change Events”import com.hypixel.hytale.event.EventRegistration;import com.hypixel.hytale.server.core.inventory.container.ItemContainer.ItemContainerChangeEvent;
// Register change listenerEventRegistration reg = container.registerChangeEvent(event -> { ItemContainer changedContainer = event.container(); Transaction transaction = event.transaction();
if (transaction.succeeded()) { // Handle successful change }});
// With priorityEventRegistration reg = container.registerChangeEvent( EventPriority.EARLY, this::onContainerChange);
// Unregister when donereg.close();MaterialQuantity and ResourceQuantity
Section titled “MaterialQuantity and ResourceQuantity”These classes represent crafting ingredients and resource requirements.
MaterialQuantity
Section titled “MaterialQuantity”import com.hypixel.hytale.server.core.inventory.MaterialQuantity;
// Create by item IDMaterialQuantity material = new MaterialQuantity( "Stone", // Item ID (or null) null, // Resource type ID (or null) null, // Tag (or null) 5, // Quantity null // Metadata);
// Create by resource typeMaterialQuantity resource = new MaterialQuantity( null, "Wood", // Resource type null, 10, null);
// Create by tagMaterialQuantity tagged = new MaterialQuantity( null, null, "ore", // Item tag 3, null);
// Convert to ItemStackItemStack stack = material.toItemStack();
// Convert to ResourceQuantityResourceQuantity res = material.toResource();
// Check and remove from containerif (container.canRemoveMaterial(material)) { MaterialTransaction tx = container.removeMaterial(material);}
// Remove multiple materialsList<MaterialQuantity> materials = List.of(material1, material2);if (container.canRemoveMaterials(materials)) { ListTransaction<MaterialTransaction> tx = container.removeMaterials(materials);}ResourceQuantity
Section titled “ResourceQuantity”import com.hypixel.hytale.server.core.inventory.ResourceQuantity;
// Create resource requirementResourceQuantity resource = new ResourceQuantity("Wood", 10);
// PropertiesString resourceId = resource.getResourceId();int quantity = resource.getQuantity();
// Clone with different quantityResourceQuantity doubled = resource.clone(20);
// Remove from containerif (container.canRemoveResource(resource)) { ResourceTransaction tx = container.removeResource(resource);}ItemContext
Section titled “ItemContext”ItemContext provides context about an item’s location in an inventory.
import com.hypixel.hytale.server.core.inventory.ItemContext;
// Create contextItemContext context = new ItemContext(container, (short) 5, itemStack);
// Access propertiesItemContainer container = context.getContainer();short slot = context.getSlot();ItemStack item = context.getItemStack();Item Asset Configuration
Section titled “Item Asset Configuration”Items are defined as assets with various properties and behaviors.
Item Properties
Section titled “Item Properties”import com.hypixel.hytale.server.core.asset.type.item.config.Item;
// Get item from asset registryItem item = Item.getAssetMap().getAsset("DiamondSword");
// Basic propertiesString id = item.getId();String icon = item.getIcon();int maxStack = item.getMaxStack();double maxDurability = item.getMaxDurability();boolean isConsumable = item.isConsumable();boolean isVariant = item.isVariant();
// CategoriesString[] categories = item.getCategories();
// Block association (for placeable items)boolean hasBlock = item.hasBlockType();String blockId = item.getBlockId();
// Translation keysString nameKey = item.getTranslationKey();String descKey = item.getDescriptionTranslationKey();Item Type Properties
Section titled “Item Type Properties”// Weapon propertiesItemWeapon weapon = item.getWeapon();if (weapon != null) { Int2ObjectMap<StaticModifier[]> statMods = weapon.getStatModifiers(); boolean renderDualWielded = weapon.renderDualWielded;}
// Armor propertiesItemArmor armor = item.getArmor();if (armor != null) { ItemArmorSlot slot = armor.getArmorSlot(); double baseResistance = armor.getBaseDamageResistance(); Int2ObjectMap<StaticModifier[]> statMods = armor.getStatModifiers();}
// Tool propertiesItemTool tool = item.getTool();if (tool != null) { ItemToolSpec[] specs = tool.getSpecs(); float speed = tool.getSpeed();}
// Utility propertiesItemUtility utility = item.getUtility();boolean isUsable = utility.isUsable();boolean isCompatible = utility.isCompatible();
// Glider propertiesItemGlider glider = item.getGlider();Armor Slots
Section titled “Armor Slots”import com.hypixel.hytale.protocol.ItemArmorSlot;
// Available armor slotsItemArmorSlot.Head; // 0 - HelmetItemArmorSlot.Chest; // 1 - ChestplateItemArmorSlot.Hands; // 2 - GlovesItemArmorSlot.Legs; // 3 - Leggings
// Get slot from valueItemArmorSlot slot = ItemArmorSlot.fromValue(0); // Head
// All slotsItemArmorSlot[] allSlots = ItemArmorSlot.VALUES;HotbarManager
Section titled “HotbarManager”Manages saved hotbar presets for creative mode.
import com.hypixel.hytale.server.core.entity.entities.player.HotbarManager;
// Maximum saved hotbarsint maxHotbars = HotbarManager.HOTBARS_MAX; // 10
// Save current hotbar (creative mode only)hotbarManager.saveHotbar(playerRef, (short) 0, componentAccessor);
// Load saved hotbar (creative mode only)hotbarManager.loadHotbar(playerRef, (short) 0, componentAccessor);
// Get current hotbar indexint currentIndex = hotbarManager.getCurrentHotbarIndex();
// Check if currently loadingboolean isLoading = hotbarManager.getIsCurrentlyLoadingHotbar();Equipment
Section titled “Equipment”Equipment represents the visually rendered items on an entity.
import com.hypixel.hytale.protocol.Equipment;
// Equipment contains// - armorIds[] - IDs of equipped armor// - rightHandItemId - Item in right hand// - leftHandItemId - Item in left handInventory Events
Section titled “Inventory Events”LivingEntityInventoryChangeEvent
Section titled “LivingEntityInventoryChangeEvent”Fired when any inventory section changes.
import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent;
getEventRegistry().register( LivingEntityInventoryChangeEvent.class, worldName, event -> { LivingEntity entity = event.getEntity(); ItemContainer container = event.getItemContainer(); Transaction transaction = event.getTransaction();
if (transaction.succeeded()) { // Handle inventory change } });DropItemEvent
Section titled “DropItemEvent”Fired when an item is dropped.
import com.hypixel.hytale.server.core.event.events.ecs.DropItemEvent;
// Handle drop request from playergetEventRegistry().register(DropItemEvent.PlayerRequest.class, event -> { int sectionId = event.getInventorySectionId(); short slotId = event.getSlotId();
// Cancel to prevent drop event.setCancelled(true);});
// Handle actual item dropgetEventRegistry().register(DropItemEvent.Drop.class, event -> { ItemStack dropped = event.getItemStack(); float throwSpeed = event.getThrowSpeed();
// Modify throw speed event.setThrowSpeed(2.0f);
// Modify dropped item event.setItemStack(dropped.withQuantity(1));});InteractivelyPickupItemEvent
Section titled “InteractivelyPickupItemEvent”Fired when a player interactively picks up an item.
import com.hypixel.hytale.server.core.event.events.ecs.InteractivelyPickupItemEvent;
getEventRegistry().register(InteractivelyPickupItemEvent.class, event -> { ItemStack item = event.getItemStack();
// Modify the picked up item event.setItemStack(item.withQuantity(item.getQuantity() * 2));
// Or cancel pickup event.setCancelled(true);});ItemModule
Section titled “ItemModule”The ItemModule provides item registration and utility functions.
import com.hypixel.hytale.server.core.modules.item.ItemModule;
// Get module instanceItemModule itemModule = ItemModule.get();
// Check if item existsboolean exists = ItemModule.exists("Stone");
// Get flat list of item categoriesList<String> categories = itemModule.getFlatItemCategoryList();
// Generate random drops from drop listList<ItemStack> drops = itemModule.getRandomItemDrops("DropListId");Transactions
Section titled “Transactions”All container operations return transaction objects for tracking success/failure.
Transaction Types
Section titled “Transaction Types”| Transaction | Description |
|---|---|
Transaction | Base transaction with success status |
SlotTransaction | Single slot operation |
ItemStackTransaction | Item stack add/remove |
ItemStackSlotTransaction | Item stack slot operation |
MoveTransaction | Item movement between containers |
ListTransaction | Multiple operations |
MaterialTransaction | Material removal |
ResourceTransaction | Resource removal |
ClearTransaction | Clear operation |
Using Transactions
Section titled “Using Transactions”// Check successItemStackTransaction tx = container.addItemStack(itemStack);if (tx.succeeded()) { ItemStack remainder = tx.getRemainder(); if (!ItemStack.isEmpty(remainder)) { // Some items couldn't be added }}
// Slot transactionsItemStackSlotTransaction slotTx = container.setItemStackForSlot((short) 0, itemStack);ItemStack before = slotTx.getSlotBefore();ItemStack after = slotTx.getSlotAfter();short slot = slotTx.getSlot();
// Move transactionsMoveTransaction<ItemStackTransaction> moveTx = container.moveItemStackFromSlot((short) 0, other);Transaction fromTx = moveTx.getRemoveTransaction();ItemStackTransaction addTx = moveTx.getAddTransaction();ItemContainer otherContainer = moveTx.getOtherContainer();
// List transactionsListTransaction<ItemStackTransaction> listTx = container.addItemStacks(items);List<ItemStackTransaction> transactions = listTx.getList();Best Practices
Section titled “Best Practices”- Check capacity before adding - Use
canAddItemStack()beforeaddItemStack() - Handle remainders - Check transaction remainders for items that couldn’t be placed
- Use appropriate containers - Use combined containers for pickup operations
- Respect filters - Pass
filter=trueto respect slot type restrictions - Listen to events - Register change events to sync custom UI or logic
- Use transactions - Always check transaction success before assuming operation completed
- Immutable ItemStacks - Remember ItemStack modification methods return new instances
- Clean up registrations - Unregister event listeners when no longer needed