Drawing

gfx and gfx3d

Drawing overlays on the screen and in the world.

gfx draws on the screen, in pixels. gfx3d draws in the world, in game coordinates, so a circle around a monster follows it as the camera moves. Both only work in on_render, and both draw over the game, not inside a window.

function on_render()
    local me = agents.local_player()
    if not me then return end

    gfx3d.circle(me, 600, Color.CYAN, 2, 64)

    local t = agents.selected()
    if t then
        gfx3d.line(me, t, Color(255, 80, 80, 200), 2)
        gfx3d.text_centered(t:name() or "?", t, Color.WHITE)
    end

    gfx.text("Hello", Vec2(20, 200), Color.YELLOW, 18)
end

Colors are Color values; positions are Vec2 (screen) or Vec3 (world) values, and a world position can also be an Agent. Thickness and size are in pixels.

gfx

Text with its top-left at pos.
Text centered on pos horizontally.
How big a text is drawn.
A rectangle fading from one color to another, left to right or top to bottom.
A filled triangle: one color, or one per corner.
An image with its top-left at pos, at its own size by default.
An image centered on pos horizontally.
Where a world position is on screen; nil when it's behind the camera.

Images

Images come from the game (item:icon(), skill.icon, game.profession_icon(...)) or from PNG files in your plugin's folder.

An image from the bytes of a PNG file (8 bits per channel, up to 4096 by 4096). Load it once, not every frame.
An image's size in pixels.
local logo = gfx.image_from_png(files.read("logo.png"))

function on_render()
    gfx.image(logo, Vec2(20, 20), 64, 64)
end

gfx3d

A line split into pieces, so long lines that go behind the camera still draw.
A filled rectangle on the ground.
A filled four-sided shape.
A cone outline on the ground, like an attack's area.
An arc from one point to another, height high in the middle.
Text at a world position.
Text centered on a world position.
A wireframe of triangles: vertices is a list of Vec3, indices a list of vertex numbers (from 1), three per triangle.