Paint
Paint System
The Paint system allows scripts to create custom overlay windows that display runtime information, statistics, and progress tracking. These overlays appear on top of the game window and provide real-time feedback to users about script execution.
What is Paint?
Paint overlays are draggable, customizable windows that can display:
- Static text (script name, version)
- Dynamic text (current status, player health)
- Skill XP tracking (automatic XP gained and XP/hour)
- Item tracking (automatic item quantity changes)
- Counters (custom counters you update programmatically)
- Progress bars (visual progress indicators)
Basic Concepts
Builder Pattern
The Paint API uses a builder pattern, which allows you to chain method calls to configure your paint:
local builder = paint:new_builder()
local paint_id = builder
:with_position(10, 10)
:with_size(300, 200)
:add_string("My Script v1.0")
:track_skill("Mining")
:build()
Paint Lifecycle
- Create: Use
paint:new_builder()to start building - Configure: Chain methods to set position, size, colors, and content
- Build: Call
build()to create and register the paint (returns paint ID) - Update: Use paint management functions to update content during execution
- Remove: Call
paint:remove(id)when done
Common Use Cases
Displaying Script Status
Show users what the script is currently doing:
local paint_id = paint:new_builder()
:with_position(10, 10)
:add_string("Status", function()
if inventory:full() then
return "Banking..."
else
return "Mining..."
end
end)
:build()
Tracking Progress
Display skill XP and item gains:
local paint_id = paint:new_builder()
:track_skill("Mining") -- Shows: "Mining: +123 XP (456 XP/hr)"
:track_item({name = "Iron ore"}, "Iron ore", true) -- Shows: "Iron ore: +5 (120/hr)"
:build()
Visual Feedback
Use progress bars to show completion status:
local paint_id = paint:new_builder()
:add_string("Inventory", function()
local count = inventory:count()
return count .. "/28"
end)
:build()
For progress bars, see the Paint API Reference for add_progress_bar and add_counter with builder:update_counter().
Best Practices
Performance
- Don't update too frequently: Update paints every 1-2 seconds, not every tick
- Use dynamic functions: For frequently changing values, use functions in
add_string()rather than manually updating
-- Good: Function is called automatically
builder:add_string("HP", function()
return combat:current_health() .. "/" .. combat:max_health()
end)
-- Less efficient: Requires manual updates
builder:add_string("HP", "0/0")
-- Then manually: paint:update_rows(...)
Organization
- Group related information: Use multiple paints for different purposes (status, stats, debug)
- Consistent styling: Use the same colors and sizes across your paints
- Clear labels: Make sure all paint elements have descriptive labels
User Experience
- Default positions: Set sensible default positions that don't obstruct gameplay
- Allow customization: Don't disable dragging unless necessary
- Provide context: Include script name and version in your paint
Example: Complete Mining Script Paint
local paint_builder -- Store builder for counter updates
local paint_id
local function create_mining_paint()
paint_builder = paint:new_builder()
-- Position and appearance
paint_builder:with_position(10, 10)
paint_builder:with_size(350, 300)
paint_builder:with_anchor("top_left")
paint_builder:with_text_size(13.0)
paint_builder:with_background_color(15, 15, 15, 220)
paint_builder:with_text_color(220, 220, 220, 255)
-- Header
paint_builder:add_string("Mining Script v2.1")
paint_builder:add_string("") -- Blank line
-- Automatic tracking
paint_builder:track_skill("Mining")
paint_builder:track_item({name = "Iron ore"}, "Iron ore", true)
paint_builder:track_item({name = "Coal"}, "Coal", true)
-- Custom counters (use builder:update_counter() to update)
paint_builder:add_counter("Trips Completed", 0)
paint_builder:add_counter("Ores Mined", 0)
-- Dynamic values via functions (no manual updates needed)
paint_builder:add_string("Inventory", function()
local count = inventory:count()
return count .. "/28"
end)
paint_builder:add_string("Status", function()
if inventory:full() then
return "Banking..."
elseif movement:is_moving() then
return "Walking..."
else
return "Mining..."
end
end)
paint_id = paint_builder:build()
return paint_id
end
-- In your script
create_mining_paint()
function script:poll()
-- Update counters via builder
paint_builder:update_counter("Trips Completed", trip_count)
paint_builder:update_counter("Ores Mined", ore_count)
-- Your script logic...
sleep(50)
end
Next Steps
- Paint API Reference - Complete API documentation with all methods and parameters
- Filters Guide - Learn how to use filters with
track_item() - Logger API - Logging messages for debugging
- Stats API - Script statistics tracking