Paint API

Paint API

Create and manage on-screen paint overlays with dynamic content.

Functions

builder

paint.builder() -> PaintBuilder

Create a new paint builder for constructing overlays. Use dot notation (not colon).

Returns:

  • PaintBuilder - Builder instance

Example:

local builder = paint.builder()
builder:add_labeled("Health", function()
    return combat:current_health() .. "/" .. combat:max_health()
end)
local paint_id = builder:build()

show

paint.show(id: string, visible: boolean) -> ()

Show or hide a paint overlay.

Parameters:

  • id (string) - Paint ID from build()
  • visible (boolean) - true to show, false to hide

remove

paint.remove(id: string) -> ()

Remove a paint overlay completely.

Parameters:

  • id (string) - Paint ID

flush

paint.flush() -> ()

Evaluate and render all Lua paints. Called by the engine each frame; scripts typically do not call this.


clear

paint.clear() -> ()

Clear all Lua paints from the manager (e.g. when resetting the script environment).


PaintBuilder Methods

Position and size

  • builder:position(x, y) – Set paint position in pixels. Returns builder for chaining.
  • builder:size(width, height) – Set minimum paint dimensions in pixels. Returns builder for chaining.
  • builder:bg_color(r, g, b, a) – Set background color (RGBA 0–255). Returns builder for chaining.
  • builder:text_color(r, g, b, a) – Set text color (RGBA 0–255). Returns builder for chaining.
  • builder:with_header(show) – Show or hide the script title/version header (default: true).
  • builder:header_text_size(size) – Set header font size.
  • builder:header_title_color(r, g, b, a) – Set header title color.
  • builder:header_title_alternate_color(r, g, b, a) – Set header title alternate color.
  • builder:header_version_color(r, g, b, a) – Set header version color.

add_static

builder:add_static(text: string) -> PaintBuilder

Add a static text row (no dynamic value).

Parameters:

  • text (string) - Text to display

Returns:

  • PaintBuilder - Self for chaining

add_dynamic

builder:add_dynamic(get_value_func: function) -> PaintBuilder

Add a dynamic text row with no label. The function is called at render time.

Parameters:

  • get_value_func (function) - Function that returns the current value as a string

Returns:

  • PaintBuilder - Self for chaining

add_labeled

builder:add_labeled(label: string, get_value_func: function) -> PaintBuilder

Add a labeled row with a dynamic value. The function is called at render time.

Parameters:

  • label (string) - Row label
  • get_value_func (function) - Function that returns the current value as a string

Returns:

  • PaintBuilder - Self for chaining

Example:

builder:add_labeled("Player", function()
    local p = players:local_player()
    return p and p:name() or "Unknown"
end)

add_shared_string

builder:add_shared_string(shared_string) -> PaintBuilder
builder:add_labeled_shared_string(label: string, shared_string) -> PaintBuilder

Add a row that displays a shared string (see shared.string(key)). Pass the shared string variable. The value is read from the shared store at render time, so it can update more than once per poll (e.g. when set from event handlers or other threads).

Parameters:

  • shared_string - The shared string from shared.string("key")
  • label (string) - Row label for add_labeled_shared_string

Returns:

  • PaintBuilder - Self for chaining

Example:

local status = shared.string("paint_status")
builder:add_shared_string(status)
builder:add_labeled_shared_string("Status:", status)

add_runtime

builder:add_runtime() -> PaintBuilder

Add a row that shows script runtime (elapsed time since script start). Returns builder for chaining.


track_skill

builder:track_skill(skill: string) -> PaintBuilder

Add skill XP tracker. Displays Exp gained, Levels gained, Exp/hr, TTNL, and a progress bar for the skill.

Parameters:

  • skill (string) - Skill name (e.g. "Mining", "Fletching", "Hitpoints")

Returns:

  • PaintBuilder - Self for chaining

track_item

builder:track_item(filter: ItemFilter, label: string, options?: table) -> PaintBuilder

Track quantity changes for items matching the filter. Subscribes to inventory change events and displays cumulative gain/loss.

Parameters:

  • filter (ItemFilter) - Item filter to match items (see Filters Guide)
  • label (string) - Display label for the tracker
  • options (table, optional) - Options: per_hour (boolean), invert (boolean), track_negative_changes (boolean)

Returns:

  • PaintBuilder - Self for chaining

Example:

-- Track logs with per-hour rate
builder:track_item({name = "Logs"}, "Logs", { per_hour = true })

-- Track all runes
builder:track_item({name_contains = "rune"}, "Runes", { per_hour = true })

-- Track specific item IDs
builder:track_item({ids = {995, 996}}, "Coins")

-- Track with options
builder:track_item({name_contains = "ore"}, "Ores", { per_hour = true, track_negative_changes = true })

build

builder:build() -> string

Build and register the paint overlay.

Returns:

  • string - Paint ID for later reference (e.g. for paint.show, paint.remove)

Common Patterns

Item tracking paint

local function create_item_tracking_paint()
    local builder = paint.builder()
    builder:position(10, 10)
    builder:track_item({name = "Logs"}, "Logs", { per_hour = true })
    builder:track_item({name_contains = "rune"}, "Runes", { per_hour = true })
    builder:track_item({name_contains = "ore"}, "Ores", { per_hour = true })
    return builder:build()
end

Script status paint

local function create_status_paint()
    local builder = paint.builder()
    builder:position(10, 10)
    builder:size(300, 150)
    builder:bg_color(0, 0, 0, 180)
    builder:text_color(255, 255, 255, 255)
    builder:add_runtime()
    builder:add_labeled("State:", function()
        return script.state or "Unknown"
    end)
    return builder:build()
end

local paint_id = create_status_paint()

Combat paint

local function create_combat_paint()
    local builder = paint.builder()
    builder:add_labeled("HP", function()
        return combat:current_health() .. "/" .. combat:max_health()
    end)
    builder:add_labeled("Prayer", function()
        return prayer:prayer_points() .. "/" .. prayer:max_prayer_points()
    end)
    builder:track_skill("Hitpoints")
    builder:position(10, 100)
    return builder:build()
end