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())
endcontainer
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 |
|---|---|
0 … storage() - 1 |
The container, so 54 slots for a six-row chest |
storage() … storage() + 26 |
Your main inventory rows |
storage() + 27 … size() - 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)