Skip to main content

Items & Inventory

session.itemState is an ItemStateTracker. It holds your inventories, any open container or form, and the item registry. It also owns the controller you use to move and drop items.

ItemStateTracker​

MemberTypeDescription
controllerAbstractInventoryControllerMoves, drops and consumes items (below).
openContainerAbstractDynamicInventory | nullThe open container or inventory, if any.
openFormForm | nullThe open modal form, if any.
itemsMap<number, ItemDefinition>Item registry, keyed by network runtime id.
itemsByNameMap<string, ItemDefinition>Item registry, keyed by identifier (e.g. minecraft:diamond_sword).
simulateOpenInventory()voidQuietly open the player inventory on the server. Does nothing if it's already open.
closeContainer()voidClose the open container.

AbstractInventoryController​

itemState.controller. Every inventory change goes through here, and it sends the right transaction packets for the server's current auth mode.

MemberTypeDescription
moveItem(from, fromSlot, to, toSlot)voidMove, merge or swap items between container slots.
dropItem(container, slot, amount)voidDrop amount items from a slot.
dropItemStack(container, slot)voidDrop the whole stack in a slot, and swing.
consumeItem(container, slot, amount)voidRemove amount from a slot's stack and resync the client.
isUsingItembooleanWhether the player is using or charging an item.
itemInUseDurationnumberHow many ticks the current item has been in use.

The from, to and container arguments are AbstractInventoryContainers: localPlayer.inventory, .inventoryArmor, .inventoryOffhand, or an open container.

const { entityState, itemState } = ctx.session;
const inv = entityState.localPlayer.inventory;
const armor = entityState.localPlayer.inventoryArmor;

// move whatever is in inventory slot 9 into the helmet slot (slot 0)
itemState.controller.moveItem(inv, 9, armor, 0);

Inventory containers​

AbstractInventory // content: (ItemStack | undefined)[]
└── AbstractInventoryContainer // id, type, getSlotType(slot)
├── PlayerInventory // hotbar + main; hand, selectedSlot, ...
├── PlayerInventoryArmor // helmet/chestplate/leggings/boots
├── PlayerInventoryOffhand // offhand
└── AbstractDynamicInventory // opened chests/containers; coordinates, hide()...

AbstractInventory​

MemberTypeDescription
content(ItemStack | undefined)[]The slot array. An empty slot is undefined.
There is no isEmpty

A slot is empty exactly when content[slot] === undefined. Check for that instead of looking for an "air" item.

AbstractInventoryContainer (adds)​

MemberTypeDescription
idWindowIDWindow id of this container.
typeWindowTypeWindow type.
getSlotType(slot)FullContainerNameContainer-slot type for a slot index.

PlayerInventory​

localPlayer.inventory: the hotbar plus the main inventory.

MemberTypeDescription
selectedSlotnumberSelected hotbar slot on the server (0–8).
clientSelectedSlotnumberSelected hotbar slot on the client (0–8).
get/set handItemStack | undefinedThe item in the held hotbar slot.
setHotbarSlot(slot, toClient?)voidSwitch the held slot. Optionally show the change on the client too.
sendMobEquipment(toClient?)voidResend equipment for the current slot.

PlayerInventoryArmor​

localPlayer.inventoryArmor. Has four get/set accessors: helmet, chestplate, leggings and boots (each ItemStack | undefined).

PlayerInventoryOffhand​

localPlayer.inventoryOffhand. Has get offhand (ItemStack | undefined).

AbstractDynamicInventory​

An opened container, such as a chest. This is the type of itemState.openContainer.

MemberTypeDescription
coordinatesVector3World coordinates of the container block, if any.
createdDateWhen the container was opened.
get isInitializedbooleanWhether the container has been initialized.
initialize()voidMark it initialized.
get isHiddenbooleanWhether the container is hidden (silent).
canHide()booleanWhether it can be hidden (silent).
hide()voidHide (silence) the container. Throws if it can't be hidden.

ItemStack​

An immutable item stack. There are no setters: to change a stack, create a new one and assign it (e.g. to inventory.hand).

MemberTypeDescription
definitionItemDefinitionThe item's static definition.
amountnumberStack size. Not count.
metadatanumberItem metadata/damage value.
blockBlockState | undefinedMatching block state, for placeable items.
nbt{ version, nbt } | undefinedRaw NBT payload, if any.
get simplifiedNbtItemNbt | undefinedItem NBT, simplified on first access.
get nbtHashnumberHash of the item's NBT (0 if none).
get typeHashnumberIdentity hash for grouping "same" items.
get durabilitynumberDamage taken so far (from NBT).
get customColorColor | undefinedCustom (dyed) color, if set.

These methods return a new stack:

MethodReturnsDescription
reduceAmount(amount)ItemStack | undefinedFewer items. undefined if none are left.
addAmount(amount)ItemStackMore items.
withAmount(amount)ItemStack | undefinedAn exact amount. undefined if ≤ 0.
withDamage(damage)ItemStack | undefinedThe given damage. undefined if the item would break.
withStackId(stackId)ItemStackThe given network stack id.

These methods answer questions about the stack:

MethodReturnsDescription
canStackWith(other)booleanWhether it has the same type, metadata and NBT as other.
isCorrectTool(block)booleanWhether this is the correct tool for block.
newDurability(block)numberDamage this item would take from breaking block.
getDestroySpeed(block)numberBreaking speed against block.
const inv = ctx.session.entityState.localPlayer.inventory;
const held = inv.hand;
if (held) {
console.log(held.definition.name, "x", held.amount);
}

ItemDefinition​

MemberTypeDescription
runtimeIdnumberNetwork runtime id.
namestringIdentifier, e.g. minecraft:diamond_sword.
tagsSet<string>Item tags.
durabilitynumberMaximum damage before breaking.
maxStacknumberMaximum stack size.

Form​

itemState.openForm: an open modal form.

MemberType
form_idnumber
datastring (raw JSON)