> For the complete documentation index, see [llms.txt](https://docs.nursultan.fun/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nursultan.fun/game-data/inventory-and-items.md).

# Inventory and items

## Slots

A slot is the address of a cell, not the item in it. You build one like this:

```kotlin
Slot.hotbar(0)                  // first hotbar cell, 0..8
Slot.inventory(20)              // main inventory cell, 0..35
Slot.armor(ArmorSlot.HELMET)
Slot.offhand()
Slot.NONE                       // "nothing found"
```

Everything that searches for an item returns a slot, and it may come back empty:

```kotlin
val slot = inventory.find("minecraft:golden_apple")
if (!slot.found()) return

slot.inHotbar()
slot.hotbarIndex()
slot.isArmor()
slot.armorSlot()
```

## What is in there

```kotlin
inventory.held()                        // in hand
inventory.offhand()
inventory.item(Slot.hotbar(3))
inventory.armor(ArmorSlot.CHESTPLATE)
inventory.items()                       // the whole inventory as a list
inventory.selected()                    // the selected hotbar slot

inventory.count("minecraft:arrow")
inventory.wearing("minecraft:elytra")
inventory.full()
inventory.empty()
```

## Searching

```kotlin
inventory.find("minecraft:mace")                 // anywhere
inventory.findInHotbar("minecraft:mace")         // hotbar only
inventory.findByTag("swords")                    // by item tag
inventory.find { it.enchantmentLevel("sharpness") >= 4 }
inventory.findInHotbar { it.disablesBlocking() }
inventory.findUsable { it.food() }               // usable right now
inventory.findAll { it.damageable() }            // every match
```

You can drop the `minecraft:` prefix — `"mace"` works the same.

## An item

```kotlin
item.empty()                    // empty cell
item.id()                       // "minecraft:diamond_sword"
item.name()                     // its in-game name
item.count()  item.maxCount()
item.isA("diamond_sword")
item.hasTag("swords")

item.damage()  item.maxDamage()
item.damageable()
item.unbreakable()
item.stackable()

item.enchanted()
item.enchantments()             // all of them
item.enchantmentLevel("sharpness")

item.food()
item.nutrition()
item.saturation()

item.rarity()
item.onCooldown()               // the item is on cooldown
item.disablesBlocking()         // an axe can break a shield
```

Always check for empty: `inventory.item(...)` never returns `null`, it returns an empty item.

```kotlin
val held = inventory.held()
if (held.empty()) return
```

## Moving things around

```kotlin
inventory.click(slot, false)               // false is the left button
inventory.shiftClick(slot)
inventory.swap(slot, Slot.hotbar(8))
inventory.drop(slot, true)                 // true drops the whole stack
inventory.dropHeld(false)
```

When you need several actions, group them into one batch so the server is less likely to see a desync:

```kotlin
val hotbar = Slot.hotbar(8)

inventory.batch {
    it.swap(slot, hotbar)
    it.swap(Slot.armor(ArmorSlot.CHESTPLATE), hotbar)
    it.swap(slot, hotbar)
}
```

## Do not trip over yourself

`inventory.busy()` tells you the client is moving items right now — yours or someone else's. While it is `true`, stay out of the way:

```kotlin
on<PrePlayerTickEvent> {
    if (inventory.busy()) return@on
    // now it is safe to move things
}
```

Switching the held slot and picking the best armor are their own topic — see [Slots and armor](/actions/slots-and-armor.md).
