Component Type
Component
A Component represents a UI widget in the game interface. Components can be buttons, text labels, inventory slots, or any other UI element.
Methods
is_valid
component:is_valid() -> boolean
Checks if the component is still valid and exists.
Returns:
boolean: True if the component exists
Example:
local comp = components:get(149, 0)
if comp and comp:is_valid() then
logger:info("Component is valid")
end
group_id
component:group_id() -> number
Returns the group ID (widget ID) of this component.
Returns:
number: The group ID
Example:
local comp = components:get(149, 0)
if comp then
logger:info("Group ID: " .. comp:group_id())
end
component_id
component:component_id() -> number
Returns the component ID within the group.
Returns:
number: The component ID
Example:
local comp = components:get(149, 0)
if comp then
logger:info("Component ID: " .. comp:component_id())
end
path
component:path() -> table
Returns the full path of IDs to this component.
Returns:
table: Array of IDs representing the path
Example:
local comp = components:get(149, 0)
if comp then
local path = comp:path()
local path_str = table.concat(path, " -> ")
logger:info("Path: " .. path_str)
end
text
component:text() -> string
Returns the text content of this component.
Returns:
string: The component's text, or empty string if none
Example:
local comp = components:get(149, 0)
if comp then
local text = comp:text()
logger:info("Text: " .. text)
end
visible
component:visible() -> boolean
Checks if the component is visible.
Returns:
boolean: True if visible
Example:
local comp = components:get(149, 0)
if comp and comp:visible() then
logger:info("Component is visible")
end
hidden
component:hidden() -> boolean
Checks if the component is hidden.
Returns:
boolean: True if hidden
Example:
local comp = components:get(149, 0)
if comp and comp:hidden() then
logger:info("Component is hidden")
end
x
component:x() -> number
Returns the X position on screen.
Returns:
number: The X coordinate, or -1 if invalid
y
component:y() -> number
Returns the Y position on screen.
Returns:
number: The Y coordinate, or -1 if invalid
width
component:width() -> number
Returns the width in pixels.
Returns:
number: The width, or -1 if invalid
height
component:height() -> number
Returns the height in pixels.
Returns:
number: The height, or -1 if invalid
Example:
local comp = components:get(149, 0)
if comp then
local x = comp:x()
local y = comp:y()
local w = comp:width()
local h = comp:height()
logger:info("Bounds: " .. x .. "," .. y .. " " .. w .. "x" .. h)
end
content_type
component:content_type() -> number
Returns the content type of this component.
Returns:
number: The content type ID, or -1 if invalid
Example:
local comp = components:get(149, 0)
if comp then
logger:info("Content type: " .. comp:content_type())
end
parent_id
component:parent_id() -> number?
Returns the parent ID if this component has a parent.
Returns:
number?: The parent ID, or nil if no parent
Example:
local comp = components:get(149, 0)
if comp then
local parent = comp:parent_id()
if parent then
logger:info("Parent ID: " .. parent)
else
logger:info("No parent")
end
end
item_id
component:item_id() -> number
Returns the item ID if this component contains an item.
Returns:
number: The item ID, or -1 if no item
Example:
-- Check inventory slot
local slot = components:get(149, 0)
if slot then
local item_id = slot:item_id()
if item_id ~= -1 then
logger:info("Contains item: " .. item_id)
end
end
item_stack_size
component:item_stack_size() -> number
Returns the stack size if this component contains an item.
Returns:
number: The stack size, or -1 if no item
Example:
local slot = components:get(149, 0)
if slot then
local stack = slot:item_stack_size()
if stack > 1 then
logger:info("Stack size: " .. stack)
end
end
texture_id
component:texture_id() -> number
Returns the texture ID of this component. This can be used to identify components by their visual appearance.
Returns:
number: The texture ID, or -1 if invalid
Example:
local comp = components:get(149, 0)
if comp then
local texture = comp:texture_id()
if texture ~= -1 then
logger:info("Component texture ID: " .. texture)
end
end
click
component:click() -> boolean
Performs a left click on the component.
Returns:
boolean: True if successful
Example:
local button = components:get(149, 0)
if button and button:visible() then
button:click()
end
interact
component:interact(filter_input: table?) -> boolean
Right-clicks and selects a menu option by filters.
Parameters:
filter_input(table, optional): Optional menu item filters
Returns:
boolean: True if successful
Example:
local item_slot = components:get(149, 5)
if item_slot then
-- Right-click and select "Drop"
item_slot:interact({action = "Drop"})
end
-- You can also use action_contains for substring matching
local button = components:get(149, 0)
if button then
button:interact({action_contains = "Close"})
end
child
component:child(child_id: number) -> Component?
Gets a child component by its child ID. This is equivalent to calling components:get(group_id, component_id, child_id).
Parameters:
child_id(number): The child component ID to retrieve
Returns:
Component?: The child component, or nil if not found
Example:
-- Get parent component
local parent = components:get(465, 26)
if parent then
-- Get child component 34
local child = parent:child(34)
if child then
logger:info("Child text: " .. child:text())
end
end
-- Equivalent to:
local child = components:get(465, 26, 34)
Note: The components:get() method accepts an optional third parameter for retrieving child components directly.
base_point
component:base_point() -> (number, number)
Returns the base point on screen (x, y) for this component.
Returns:
(number, number): Tuple of (x, y) screen coordinates, or (-1, -1) if invalid
next_point
component:next_point() -> (number, number)
Returns a random point within the component's clickable area on screen.
Returns:
(number, number): Tuple of (x, y) screen coordinates, or (-1, -1) if invalid
move_mouse_to
component:move_mouse_to() -> boolean
Move the mouse to this component with human-like movement.
Returns:
boolean: True on success, false if the position is invalid or the move fails
Example:
local comp = components:get(149, 0)
if comp and comp:move_mouse_to() then
mouse:click()
end
track
component:track() -> boolean
Move the mouse to this component (one-shot; same as move_mouse_to()). Components do not support continuous tracking.
Returns:
boolean: True on success
Common Patterns
Checking Component Visibility
local function wait_for_component(group_id, component_id, timeout)
local start = os.time()
while os.time() - start < timeout do
local comp = components:get(group_id, component_id)
if comp and comp:is_valid() and comp:visible() then
return comp
end
sleep(100)
end
return nil
end
local dialog = wait_for_component(231, 4, 5)
if dialog then
logger:info("Dialog appeared!")
end
Reading Component Text
-- Read NPC dialog text
local function get_dialog_text()
local dialog = components:get(231, 5)
if dialog and dialog:visible() then
return dialog:text()
end
return nil
end
local text = get_dialog_text()
if text then
logger:info("NPC says: " .. text)
end
Clicking Buttons
local function click_continue_button()
local continue_button = components:get(231, 4)
if continue_button and continue_button:visible() then
local x = continue_button:x()
local y = continue_button:y()
local w = continue_button:width()
local h = continue_button:height()
-- Click center of button
mouse.move_to(x + w / 2, y + h / 2)
sleep(100)
mouse:click()
return true
end
return false
end
Finding Item Slots
local function find_inventory_slot_with_item(item_id)
-- Inventory slots are components 149:0 through 149:27
for i = 0, 27 do
local slot = components:get(149, i)
if slot and slot:item_id() == item_id then
return slot, i
end
end
return nil, -1
end
local slot, index = find_inventory_slot_with_item(995) -- Coins
if slot then
logger:info("Found coins in slot " .. index)
end
Component Bounds Rectangle
local function get_component_bounds(comp)
if not comp or not comp:is_valid() then
return nil
end
return Rectangle.new(
comp:x(),
comp:y(),
comp:width(),
comp:height()
)
end
local comp = components:get(149, 0)
if comp then
local bounds = get_component_bounds(comp)
if bounds then
local area = bounds:area()
logger:info("Component area: " .. area .. " pixels")
end
end
Validating Component State
local function is_component_clickable(comp)
if not comp then
return false, "Component is nil"
end
if not comp:is_valid() then
return false, "Component is not valid"
end
if comp:hidden() then
return false, "Component is hidden"
end
if not comp:visible() then
return false, "Component is not visible"
end
local w = comp:width()
local h = comp:height()
if w <= 0 or h <= 0 then
return false, "Component has invalid dimensions"
end
return true, "Component is clickable"
end
local button = components:get(149, 0)
local clickable, reason = is_component_clickable(button)
if clickable then
button:click()
else
logger:warn("Cannot click: " .. reason)
end
Iterating Child Components
-- Find all visible children of a parent component
local function find_visible_children(parent_group_id, max_children)
local visible = {}
for i = 0, max_children do
local child = components:get(parent_group_id, i)
if child and child:is_valid() and child:visible() then
table.insert(visible, child)
end
end
return visible
end
local children = find_visible_children(149, 27)
logger:info("Found " .. #children .. " visible inventory slots")
Smart Component Clicking
local function smart_click_component(group_id, component_id)
local comp = components:get(group_id, component_id)
if not comp or not comp:is_valid() then
logger:warn("Component not found")
return false
end
if not comp:visible() then
logger:warn("Component not visible")
return false
end
-- Get center point
local x = comp:x()
local y = comp:y()
local w = comp:width()
local h = comp:height()
-- Add small random offset for human-like clicking
local offset_x = math.random(-w * 0.2, w * 0.2)
local offset_y = math.random(-h * 0.2, h * 0.2)
local click_x = x + w / 2 + offset_x
local click_y = y + h / 2 + offset_y
mouse.move_to(click_x, click_y)
sleep(math.random(50, 150))
mouse:click()
return true
end
Monitoring Component Text Changes
local function wait_for_text_change(group_id, component_id, timeout)
local comp = components:get(group_id, component_id)
if not comp then return false end
local initial_text = comp:text()
local start = os.time()
while os.time() - start < timeout do
comp = components:get(group_id, component_id)
if comp then
local current_text = comp:text()
if current_text ~= initial_text then
return true, current_text
end
end
sleep(100)
end
return false, initial_text
end
local changed, new_text = wait_for_text_change(231, 5, 10)
if changed then
logger:info("Text changed to: " .. new_text)
end
Common Component IDs
Interface Components
-- Inventory
local INVENTORY_GROUP = 149
-- Bank
local BANK_GROUP = 12
-- Chatbox
local CHATBOX_GROUP = 162
-- Dialog
local DIALOG_GROUP = 231
-- Equipment
local EQUIPMENT_GROUP = 387
-- Spellbook
local SPELLBOOK_GROUP = 218
Using Component IDs
-- Check if inventory is open
local inventory_container = components:get(149, 0)
if inventory_container and inventory_container:visible() then
logger:info("Inventory is open")
end
-- Check if bank is open
local bank_container = components:get(12, 2)
if bank_container and bank_container:visible() then
logger:info("Bank is open")
end