Skip to content

HUD

Needs the internal running and needs_internal = true in script_info.

hud.class_count(name) -> number | nil

Returns how many interface panels currently carry the CSS class name. Deadlock draws its whole HUD as web-style panels, so the game's own decisions show up there as classes appearing and disappearing. Spell the class exactly as the game does.

Why use it

Take Bebop's bomb or Seven's Static Charge. To know whether you can cast on the enemy in front of you, you would normally need a visibility check, a distance check and a field of view check, and each ability has its own range and shape. The game already does all of that: when you are holding the ability and it has a valid target, it shows the target indicator. Count that indicator and cast when it is above 0.

Deadlock's unit target indicator on Abrams: a diamond outline, the Static Charge icon and a left mouse button prompt

That is the indicator, drawn on Abrams while Static Charge is held: a diamond outline, the ability icon inside it, and a mouse icon for the left button. Each of those is a panel with a class on it.

Returns

ValueMeaning
a numberPanels carrying the class right now. 0 means the class is tracked and nothing has it
nilCould not read. Not the same as 0

Treat 0 and nil differently. If you fold nil into "no target", a feed that is not working looks like standing around aiming at nothing.

Returns nil when

  • The internal is not running.
  • needs_internal = true is missing from script_info. One line goes to tsuki.log, once per script.
  • It is the first call or two for a new class. The first call registers the name; the count lands on a later frame. Poll it every tick, do not read it once.
  • 16 classes are already being tracked. That limit is shared by every loaded script.
  • The interface could not be read this session.

Limits

  • 16 classes at a time across all scripts. Two scripts watching ten each starve each other.
  • A class nobody has asked about for 10 seconds is dropped. Asking again re-registers it, with another frame or two of nil. Calling it every tick keeps it alive.
  • Do not cache the result across frames. It changes with the interface.
  • Do not use it for player data. Health, souls, names and positions come from the Player object and are exact. HUD text is drawn for humans.

Class names

Seen while building the Seven autocast. When a unit target ability has a valid target under the crosshair, these six appear and vanish together:

ClassNotes
unit_target_instanceThe one to check. The game's unit target element
target_shape
diamond
diamond_inner
button_hint
stack_count

When a cast is not valid:

ClassNotes
cast_failed
invalid_cast_line

Example

Casts Static Charge only while the game is showing the target indicator:

lua
script_info = {
    name           = "Seven Autocast",
    description    = "Casts Static Charge on whoever you are looking at.",
    needs_internal = true,
}
id = hero_id.seven

local INDICATOR = "unit_target_instance"
local warned = false

function on_tick()
    local me = local_player()
    if not me or not me:is_alive() then return end
    if is_in_menu() then return end

    -- the indicator shows for any unit target ability, so check we are holding ours
    local sel = me:get_selected_ability()
    if not sel or sel.slot ~= slot.ability2 then return end
    if not me:is_ability_ready(slot.ability2) then return end

    local shown = hud.class_count(INDICATOR)
    if shown == nil then
        if not warned then
            warned = true
            print("hud.class_count returned nil, not casting")
        end
        return
    end
    warned = false

    if shown < 1 then return end
    input.press_key(0x01)
end