Skip to main content

GUI API

Namespace: hexis.gui

Movement Restriction

GUI operations require the inventory/container to be OPEN. The player CANNOT move while interacting with GUIs. This is enforced automatically by the GUI Interaction Guard.


Automatic Safety (GUI Interaction Guard)

All GUI click operations are automatically protected against anti-cheat detection. You don't need to add manual delays — the system handles this for you.

What Happens Automatically

ProtectionBehaviorWhen
First-click delay200-500ms randomized delayBefore the FIRST click after a container opens
Inter-click delay100-150ms minimum gapBetween every consecutive click
Movement lockStops pathfinder, camera, and movement keysOn first GUI click, released when container closes
No Migration Needed

These protections are enforced at the Java API level. Existing scripts automatically benefit without any code changes.

Bypassing Inter-Click Delay

For minigame scripts (Harp, Chronomatron) where the server expects fast consecutive clicks, use unsafe = true to bypass the inter-click delay:

-- Normal scripts — safe by default (100-150ms between clicks)
hexis.gui.click(slot)

-- Minigame scripts — bypass inter-click delay
hexis.gui.click({ slot = slot_id, unsafe = true })
Only for Minigames

Only use unsafe = true for Hypixel minigames that require fast clicking. NPC menus, bazaar, auction house, and quest UIs should always use the default safe behavior.


Safe Mode (Legacy)

hexis.gui.safe_mode()

Manually stops ALL activity (combat, movement, camera) before GUI interaction.

Mostly Redundant

The GUI Interaction Guard now handles movement locking automatically on the first click. You only need safe_mode() if you want to stop movement before opening a container (e.g., to prevent walking into an NPC).

hexis.gui.safe_mode()  -- Optional: stop movement before opening
hexis.gui.open()

Opening/Closing

hexis.gui.open()

Opens player inventory.

hexis.gui.safe_mode()
hexis.gui.open()
hexis.wait(0.3)

hexis.gui.close()

Closes current GUI.

hexis.gui.close()

hexis.gui.wait_for(title, timeout)

Waits for a GUI with matching title to open.

hexis.gui.wait_for("Bazaar", 5)  -- Wait up to 5 seconds

State Checks

hexis.gui.is_open()

Returns true if any GUI screen is open.

if hexis.gui.is_open() then
hexis.log.info("GUI is open")
end

hexis.gui.get_title()

Returns current GUI title, or nil if none open.

local title = hexis.gui.get_title()
if title then
hexis.log.info("Current GUI: " .. title)
end

hexis.gui.has_title(pattern)

Returns true if current GUI title contains pattern.

if hexis.gui.has_title("Bazaar") then
hexis.log.info("Bazaar is open!")
end

hexis.gui.get_hovered_item()

Returns information about the item currently under the cursor, or nil if no item is hovered.

local item = hexis.gui.get_hovered_item()
if item then
hexis.log.info("Hovering: " .. item.name)
end

Finding Items

hexis.gui.click_item(options)

Recommended. Finds an item in the current GUI and clicks it in one call. This is the preferred way to interact with menu items.

-- Find and click by name
hexis.gui.click_item({name = "Sell Inventory"})

-- Find and click by lore
hexis.gui.click_item({lore = "Click to confirm"})

-- Combine criteria (AND logic)
hexis.gui.click_item({name = "Diamond", lore = "Click to buy"})

hexis.gui.click_item_by_lore(pattern)

Shorthand for finding and clicking an item by lore text.

hexis.gui.click_item_by_lore("Click to claim")

hexis.gui.find(options)

Not recommended for Lua scripts

gui.find is a legacy binding from the YAML scripting system. It may not return values directly in Lua. Use click_item() for combined find+click, or get_slots() for custom scanning logic.

Finds an item in current GUI by name, lore, type, or color.

-- Instead of gui.find, prefer these alternatives:

-- Option 1: Find and click in one step
hexis.gui.click_item({name = "Diamond", lore = "Click to buy"})

-- Option 2: Scan slots manually for custom logic
local slots = hexis.gui.get_slots(0, 53)
for _, slot in ipairs(slots) do
if not slot.empty and slot.name:find("Diamond") then
hexis.gui.click(slot.id)
break
end
end

hexis.gui.get_slot_info(slot)

Gets detailed information about a single slot.

Returns a table with: id, name, type, row, col, color, empty, lore, count, has_glint

FieldTypeDescription
idnumberSlot index
namestringItem display name
typestringItem type identifier
rownumberRow in container (0-indexed)
colnumberColumn in container (0-indexed)
colorstringDyed color name ("red", "blue", etc. or "none")
emptybooleanWhether slot is empty
countnumberStack size (0 if empty)
has_glintbooleanWhether item has enchantment glint (foil effect)
loretableArray of lore line strings
local info = hexis.gui.get_slot_info(5)
if info and not info.empty then
hexis.log.info("Slot 5: " .. info.name .. " x" .. info.count)
if info.has_glint then
hexis.log.info(" Has enchantment glint!")
end
end

hexis.gui.get_slots(from, to)

Bulk-scans a range of slots and returns an array of slot info tables. Each entry has the same fields as get_slot_info.

-- Scan all container slots (e.g., first 54 slots of a double chest)
local slots = hexis.gui.get_slots(0, 53)
for _, slot in ipairs(slots) do
if not slot.empty and slot.has_glint then
hexis.log.info("Glinting item at slot " .. slot.id .. ": " .. slot.name)
end
end

hexis.gui.get_container_size()

Returns the number of container slots (excluding player inventory). Useful to know the range for get_slots.

local size = hexis.gui.get_container_size()
local slots = hexis.gui.get_slots(0, size - 1)

Clicking

hexis.gui.click(slot) / hexis.gui.click(options)

Clicks a slot by index. Automatically enforces anti-cheat safety delays.

-- Simple syntax
hexis.gui.click(slot)

-- Table syntax with options
hexis.gui.click({ slot = 10, button = "right" })
hexis.gui.click({ slot = 10, action = "shift" })
hexis.gui.click({ slot = 10, hotbar = 0 }) -- Swap with hotbar

-- Minigame bypass (skip inter-click delay)
hexis.gui.click({ slot = slot_id, unsafe = true })
OptionTypeDescription
slotnumberSlot index to click
buttonstring"left" (default) or "right"
actionstring"shift" for shift-click, "right" for right-click
hotbarnumberHotbar slot (0-8) to swap with
unsafebooleanSkip inter-click delay (for minigames only)

hexis.gui.click_item(options)

Find and click an item in one step. Same safety delays apply automatically.

hexis.gui.click_item({
name = "Confirm",
required = true, -- Fail if not found
action = "shift", -- "shift" or "right"
delay = 0.2, -- Delay after click
unsafe = true -- Optional: skip inter-click delay
})

hexis.gui.click_item_by_lore(pattern)

Find and click item by lore text.

hexis.gui.click_item_by_lore("Click to sell")

Slot Watcher

Main-thread slot watcher for detecting item changes in real-time. Useful for games like Chronomatron where items change too fast for cross-thread polling to catch.

The watcher runs on the main client tick thread, detecting changes via both individual slot packets and bulk content packets. Changes are queued and consumed from Lua via poll_slot_changes().

hexis.gui.watch_slots(slot_ids)

Start watching specific slots for item changes.

ParameterTypeDescription
slot_idstableArray of slot indices to watch
-- Watch slots 12, 13, 14 and the control slot
hexis.gui.watch_slots({12, 13, 14, 49})

hexis.gui.poll_slot_changes()

Drains all pending slot change events from the watcher queue. Returns an array of change tables.

Each change table has:

FieldTypeDescription
slotnumberSlot index that changed
typestringItem type identifier
namestringItem display name
has_foilbooleanWhether item has enchantment glint
local changes = hexis.gui.poll_slot_changes()
for _, c in ipairs(changes) do
if c.has_foil then
hexis.log.info("Slot " .. c.slot .. " gained foil: " .. c.name)
end
end

hexis.gui.stop_watching()

Stops the slot watcher and clears all state.

hexis.gui.stop_watching()
When to Use

Use the slot watcher when you need to detect transient item changes that happen faster than your script's poll rate. For static reads, get_slot_info() is simpler and sufficient.


Hotbar

hexis.gui.switch_hotbar(slot)

Switches to hotbar slot (0-8).

hexis.gui.switch_hotbar(0)  -- Switch to first slot

Example Usage

Basic Container Navigation

-- Open bazaar and buy item (safe_mode optional, guard handles delays)
hexis.chat.command("/bz")
hexis.gui.wait_for("Bazaar", 5)

hexis.gui.click_item({name = "Buy Instantly"}) -- First click: 200-500ms delay auto-applied
hexis.wait(0.3) -- Wait for server response
hexis.gui.click_item({ -- Second click: 100-150ms inter-click delay
name = "Confirm",
required = true
})

hexis.gui.close()

Minigame Solver (Harp)

-- Watch for note changes and click reactively
hexis.gui.watch_slots(ALL_SLOTS)

while hexis.script.is_running() and hexis.gui.is_open() do
local changes = hexis.gui.poll_slot_changes()
for _, change in ipairs(changes) do
if change.type:find("quartz_block") then
hexis.wait(0.1)
hexis.gui.click({ slot = change.slot, unsafe = true }) -- Fast clicks OK
end
end
hexis.wait(0.02)
end

hexis.gui.stop_watching()