Skip to content

Game Icons

Scripts can draw the game's own art: ability icons, item and upgrade art, status icons, hero portraits and minimap markers. The art is read out of the game's own files at runtime. Nothing ships with TSUKI and nothing is downloaded.

These loaders return the same kind of handle as draw.load_image, and you draw them with the same draw.image. There is one image system, one budget and one lifetime.

FunctionReturnsDescription
draw.ability_icon(hero_name, slot)integer or nilIcon for one of a hero's four abilities. slot is 1 to 4
draw.item_icon(name, [px])integer or nilIcon for an item or upgrade by name
draw.load_game_image(path, [px])integer or nilAny image in the game's interface art, by path

draw.load_image is unchanged and still limited to a bare file name under C:\TSUKI\Deadlock\scripts\images\. The three functions here do not widen that; they read the game's own files, which are read only.

Ability icons

The one you usually want. Pass a hero name and a slot:

lua
function on_tick()
    local me = local_player()
    local hero = me and me:hero_name()
    if not hero then return end

    for slot = 1, 4 do
        local h = draw.ability_icon(hero, slot)
        if h then
            draw.image(h, 40 + (slot - 1) * 70, 300, 64, 64)
        end
    end
end

hero_name is a method, not a field. Call it.

Item icons

Pass the item or upgrade name, with or without the upgrade_ prefix:

lua
local h = draw.item_icon("counterspell")          -- same as "upgrade_counterspell"

The name is resolved through the game's own item table, so a rename or a new item follows automatically without a TSUKI update. nil means the name is unknown.

Loading by path

draw.load_game_image takes a path into the game's interface art. It accepts either the compiled path or the source path the game's own data files use, and normalises for you:

FormExample
Compiled pathpanorama/images/hud/abilities/astro/holliday_crackshot_psd.vtex_c
Source pathfile://{images}/hud/abilities/bebop/bebop_hook.psd
Source path, wrappedpanorama:"file://{images}/hud/abilities/haze/haze_sleep_dagger.psd"

If you are converting a source path by hand, the rule is: drop the wrapper and file://{images}/, put panorama/images/ in front, and turn the trailing .psd into _psd.vtex_c. The same applies to .svg.

Some art is stored as vector rather than a texture. Those are rasterized once for each size you ask for. px sets the longer side, from 16 to 512, and defaults to 128. Minimap markers live under materials/minimap/ and load the same way.

Useful starting points:

PathWhat it holds
panorama/images/hud/abilities/<hero>/Ability art, one folder per hero
panorama/images/hud/modifiers/Status and buff icons
panorama/images/heroes/Hero portrait art
panorama/images/minimap/Minimap markers
materials/minimap/Camp and crate markers

What it refuses

A refusal always returns nil rather than drawing something wrong.

InputResult
A path containing ..nil, logged once
A path outside the interface artnil. This is not a general file reader
A path that does not existnil
Art in a format that cannot be decodednil, never garbage pixels

Drawing them well

Most of this art is white and meant to be tinted. Drawn raw on a bright background it is invisible. Put something dark behind it and tint deliberately:

lua
local PLATE = draw.color(12, 14, 18, 200)

draw.rect_filled(x, y, 40, 40, PLATE, 3)                     -- plate first, the art is transparent
draw.image(h, x, y, 40, 40, draw.color(120, 220, 160))       -- arg 6 tints
draw.rect(x, y, 40, 40, draw.color(80, 220, 120, 230), 1.6, 3)

Sizes vary by file. Ability icons are mostly square but others are not. Call draw.image_size(h) if you need the real aspect ratio.

Do not shrink them far. These are large source images. A 20 px box throws away most of the detail. Draw at 28 px or more where you can.

nil means not yet, not no

The first call for a path usually returns nil while the art loads. Ask again next tick and keep the handle once it lands:

lua
local icon

function on_tick()
    icon = icon or draw.item_icon("counterspell")
    if icon then draw.image(icon, 40, 40, 32, 32) end
end

Limits

Handles64 in total, shared with draw.load_image
Largest side4096 px
DecodeOnce per path, then cached on disk between runs
When unusedNothing is opened until a script asks

Images do not draw in Enhanced mode

In Enhanced rendering mode, draw.image draws nothing. This applies to every image, not just game art, and a script cannot work around it. If your script needs images, either target Standard mode or fall back to draw.text and draw.rect. TSUKI's own ability ESP is not affected; it takes a different path.