Skip to main content

Items & Inventory

session.itemState is an ItemStateTracker — the local inventories, open containers and forms, the item registry, and the controller that moves/drops items.

ItemStateTracker

MemberTypeDescription
controllerAbstractInventoryControllerMoves/drops/consumes items (see below).
openContainerAbstractDynamicInventory | nullThe currently open container/inventory, if any.
openFormForm | nullThe currently 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()voidSilently open the player inventory server-side (no-op if already open).
closeContainer()voidClose the currently open container.

AbstractInventoryController

itemState.controller. Every mutation goes through here — it produces the correct transaction packets for the current server-auth mode.

MemberSignatureDescription
moveItem(from, fromSlot, to, toSlot)voidMove/merge/swap items between container slots.
dropItem(container, slot, amount)voidDrop amount items from a slot.
dropItemStack(container, slot)voidDrop the entire stack in a slot (and swing).
consumeItem(container, slot, amount)voidReduce a slot's stack by amount and resync the client.
getLegacyRequestId()numberAllocate a decreasing legacy transaction request id.
isUsingItembooleanWhether the player is currently using/charging an item.
itemInUseDurationnumberTicks the current item has been in use.

The from/to/container arguments are AbstractInventoryContainers — i.e. localPlayer.inventory, .inventoryArmor, .inventoryOffhand, or a currently 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)[]Backing slot array. An empty slot is undefined.

Note — there is no isEmpty. A slot is empty exactly when content[slot] === undefined. Check for that rather than looking for an "air" item.

AbstractInventoryContainer (adds)

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

PlayerInventory

localPlayer.inventory — the hotbar + main inventory.

MemberSignatureDescription
selectedSlotnumberServer-side selected hotbar slot (0–8).
clientSelectedSlotnumberClient-side selected hotbar slot (0–8).
get/set handItemStack | undefinedThe item in the held hotbar slot.
setHotbarSlot(slot, toClient?)voidSwitch the held slot (optionally reflect to client).
sendMobEquipment(toClient?)voidResend equipment for the current slot.

PlayerInventoryArmor

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

PlayerInventoryOffhand

localPlayer.inventoryOffhandget offhand (ItemStack | undefined).

AbstractDynamicInventory

An opened container (e.g. a chest). This is the type of itemState.openContainer.

MemberSignatureDescription
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 currently hidden (silent).
canHide()booleanWhether it can be silent/hidden.
hide()voidHide (silence) the container; throws if it can't be.

ItemStack

An immutable item stack. There are no setters — you derive a new stack and reassign it (e.g. to inventory.hand).

MemberSignatureDescription
definitionItemDefinitionThe item's static definition.
amountnumberStack size. (Not count.)
metadatanumberItem metadata/damage value.
blockBlockState | undefinedAssociated block state, for placeable items.
nbt{ version, nbt } | undefinedRaw NBT payload, if any.
get simplifiedNbtItemNbt | undefinedLazily-simplified item NBT.
get nbtHashnumberHash of the item's NBT (0 if none).
get typeHashnumberIdentity hash for grouping "same" items.
get durabilitynumberCurrent damage taken (from NBT).
get customColorColor | undefinedCustom (dyed) color, if set.

Derivations (return a new stack):

MethodReturnsDescription
reduceAmount(amount)ItemStack | undefinedFewer items (undefined if depleted).
addAmount(amount)ItemStackMore items.
withAmount(amount)ItemStack | undefinedExact amount (undefined if ≤ 0).
withDamage(damage)ItemStack | undefinedGiven damage (undefined if it would break).
withStackId(stackId)ItemStackGiven network stack id.

Queries:

MethodReturnsDescription
canStackWith(other)booleanSame type/metadata/nbt as other.
isCorrectTool(block)booleanWhether this is the correct tool for block.
newDurability(block)numberDamage this would take from breaking block.
getDestroySpeed(block)numberBlock-breaking 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.
durabilitynumberMax damage before breaking.
maxStacknumberMax stack size.

Form

itemState.openForm — an open modal form:

MemberType
form_idnumber
datastring (raw JSON)