Skip to content

Screens

The open screen, and the slots of its handler in the indices click_slot takes.

screen

Function Does
screen.current() Returns {type, title, handled}, or nil when no screen is open
screen.close() Closes a handled screen the vanilla way

type is a stable name for the screens the client recognizes ("inventory", "generic_container", "anvil", "furnace", "merchant", "chat", "game_menu", "death", "sign", "book", …) and "other" for the rest. title is a text component. handled marks container screens, whose slots interaction.click_slot can click and container can read.

local s = screen.current()
if s and s.type == "generic_container" then
    print("looking at", s.title:string())
end

container

The slots of the open screen handler: chest, shulker, villager, a server’s custom menu. These are handler indices, the ones interaction.click_slot takes, not the player-screen slots inventory uses.

Function Returns
container.size() Slot count of the handler, container and player rows together
container.storage() How many leading slots belong to the container itself
container.revision() Server revision of the handler, 0 until the first content sync
container.item(slot) Live item handle, or nil
container.find(id[, from[, to]]) First slot holding that item, or nil
container.count(id[, from[, to]]) Total count of that item, optionally within a range
container.empty([from[, to]]) First free slot, or nil when the range is full

A container screen opens before the server has sent what’s inside: the slots read as empty for the first ticks. revision() flips from 0 once the full content sync arrives, so an automation that opens chests itself should wait for it before reading slots (the container_content packet carries the same signal as an event).

Slot layout

The container’s own slots come first, your inventory after:

Range Holds
0storage() - 1 The container, so 54 slots for a six-row chest
storage()storage() + 26 Your main inventory rows
storage() + 27size() - 1 Your hotbar

With no container open this is your own inventory handler, where storage() covers the crafting result and grid, and the armor slots count as inventory.

Moving a whole stack

click_slot with "quick_move" is a shift-click: one packet moves the entire stack to the other side of the handler.

module:event("tick", function()
    local open = screen.current()
    if not open or not open.handled or open.title:string() ~= "Sell" then return end

    local sync, storage = interaction.sync_id(), container.storage()
    for slot = storage, container.size() - 1 do
        local item = container.item(slot)
        if item and item:id() == "minecraft:cobblestone" then
            interaction.click_slot(sync, slot, 0, "quick_move")
        end
    end
end)
Navigation

Type to search…

↑↓ navigate↵ selectEsc close