draw
Draw text and shapes in screen-space with the overlay API.
Drawing reference
Drawing coordinates are pixels, measured from the top-left of the screen. Submit draw calls inside script.on_tick() for persistent content.
draw.color
Integer channels 0..255; alpha defaults to 255. Packed form is 0xAABBGGRR.
text
draw.color(r, g, b [, a])Returns: Packed unsigned 32-bit color
draw.screen
Current render dimensions; can initially be zero.
text
draw.screen()Returns: { width = number, height = number }
draw.text
White color and size 18 by default.
text
draw.text(x, y, text [, color [, size]])Returns: Nothing
draw.rect
Filled by default; false draws an outline.
text
draw.rect(x, y, width, height, color [, filled])Returns: Nothing
draw.line
Thickness defaults to 1; second pair is the endpoint, not width/height.
text
draw.line(x1, y1, x2, y2, color [, thickness])Returns: Nothing
draw.circle
Outline by default; true fills the circle.
text
draw.circle(x, y, radius, color [, filled])Returns: Nothing
Coordinates and rectangle dimensions must be finite with absolute values no greater than 100,000. Use positive rectangle dimensions. Circle radius must be positive and no greater than 100,000. Text size and line thickness must be finite, greater than zero, and no greater than 4,096. Text uses the standard 4,096-byte limit. Each script can submit 512 draw commands per update.
Draw commands are copied to the renderer; they do not persist indefinitely. The script's draw buffer is cleared before its observation/timer/completion callbacks are processed each update. Drawing from initial loading or a menu callback is therefore not a reliable way to display content: store state there and draw it from on_tick().
Both renderer backends consume the same Lua draw-command format through the background draw list. Text uses Harmony's regular font. A frame may be skipped while the renderer and script owner exchange snapshots. API v2 has no Lua draw.image, sprite, texture, weapon-image, font-selection, or text-measurement function.
Panel example
lua
local page = menu.root("Example panel")
local visible = true
local level = 3
local background = draw.color(18, 22, 30, 220)
local text = draw.color(240, 240, 245)
local active = draw.color(115, 210, 180)
local inactive = draw.color(60, 68, 80)
page:toggle("Visible", true, function(value)
visible = value
end)
page:number("Example level", level, 0, 5, 1, function(value)
level = value
end)
script.on_tick(function()
if not visible then
return
end
local screen = draw.screen()
if screen.width <= 0 or screen.height <= 0 then
return
end
local x, y = 32, 170
draw.rect(x, y, 290, 100, background)
draw.text(x + 16, y + 12, "Harmony panel", text, 20)
draw.text(x + 16, y + 56, "Level", text, 18)
for i = 1, 5 do
local color = i <= level and active or inactive
draw.rect(x + 105 + (i - 1) * 29, y + 60, 23, 12, color)
end
end)This example draws a custom illustrative value. It does not expose or claim to calculate weapon statistics.