Skip to content

Powerup ESP ​

Draws color-coded ESP labels on every pickup entity in range: powerups from bridge spawn points (survival, casting, movement, gun), permanent stat modifiers from breakable props (hp, wp, cd, spirit, firerate, ammo), gold boxes, and health pickups. Each pickup category has a distinct color.

What this shows ​

  • One loop for all four pickup types. The script calls get_world_entities(type) for powerup, pickup_modifier, pickup_gold and pickup_health in turn.
  • The active filter removes duplicates. Each powerup spawn point has four entities stacked at the same position, one per buff variant. Without the active filter, the script would draw four overlapping labels at every powerup location.
  • pickup_key names each pickup. Gold and health pickups go by type, the four powerups by their subclass token, and the rest by game.token_name(e.subclass). get_label_and_color matches parts of that name and returns a label and a category color.
  • Distance label. A faint distance in meters sits below each pickup label.

Script ​

lua
-- powerup_esp.lua
-- Shows active powerup and pickup entities with their type labels.

local colors = {
    survival  = draw.color(90, 210, 170),
    casting   = draw.color(180, 100, 255),
    movement  = draw.color(100, 200, 255),
    gun       = draw.color(255, 160, 50),
    hp        = draw.color(50, 255, 50),
    wp        = draw.color(200, 200, 255),
    cd        = draw.color(255, 255, 100),
    spirit    = draw.color(200, 100, 255),
    firerate  = draw.color(255, 100, 100),
    ammo      = draw.color(255, 180, 50),
    gold      = draw.color(255, 215, 0),
    health    = draw.color(50, 255, 100),
    fallback  = draw.color(200, 200, 200),
    dist      = draw.color(160, 160, 160),
}

local function get_label_and_color(name)
    if not name or name == "" then return "PICKUP", colors.fallback end
    name = name:lower()
    if name:find("survival") then return "SURVIVAL", colors.survival end
    if name:find("casting") then return "CASTING", colors.casting end
    if name:find("movement") then return "MOVEMENT", colors.movement end
    if name:find("gun") then return "GUN", colors.gun end
    if name:find("firerate") then return "FIRE RATE", colors.firerate end
    if name:find("ammo") then return "AMMO", colors.ammo end
    if name:find("spirit") then return "SPIRIT", colors.spirit end
    if name:find("wp_") then return "WEAPON", colors.wp end
    if name:find("hp_") then return "HEALTH+", colors.hp end
    if name:find("cd_") then return "COOLDOWN", colors.cd end
    if name:find("gold") then return "GOLD", colors.gold end
    if name:find("health") then return "HEALTH", colors.health end
    return name:gsub("_pickup.*", ""):upper(), colors.fallback
end

-- The four powerups are told apart by their subclass token
local BUFFS = {}
for _, n in ipairs({ "survival", "casting", "movement", "gun" }) do
    BUFFS[game.token(n .. "_powerup_pickup")] = n
end

-- A name for get_label_and_color: the type for gold and health,
-- the buff for a powerup, else the name behind the subclass token (or nil)
local function pickup_key(e)
    if e.type == "pickup_gold" then return "gold" end
    if e.type == "pickup_health" then return "health" end
    return BUFFS[e.subclass] or game.token_name(e.subclass)
end

function on_tick()
    local types = {"powerup", "pickup_modifier", "pickup_gold", "pickup_health"}
    for _, t in ipairs(types) do
        local ents = get_world_entities(t)
        for _, e in ipairs(ents) do
            if e.active and e.distance < 200 then
                local sp = draw.world_to_screen(vec3(e.x, e.y, e.z))
                if sp then
                    local label, color = get_label_and_color(pickup_key(e))
                    draw.text(sp.x, sp.y, label, color)
                    draw.text(sp.x, sp.y + 14, string.format("%.0fm", e.distance), colors.dist)
                end
            end
        end
    end
end

Notes ​

pickup_name is always nil, so this script names pickups from type and subclass. game.token_name returns nil for a token it does not know, and get_label_and_color shows those pickups as "PICKUP".

The 200 m distance check keeps the screen clean, so pickups across the map don't get labeled. Lower it if you only want pickups close to you, or remove the check to label pickups on the whole map when you plan before a fight.

get_label_and_color shows a name it doesn't recognize with _pickup.* stripped and in upper case, which usually gives a readable label. An empty name shows as "PICKUP". If a future patch adds new pickup classes, the script keeps working and labels them this way until you add a matching case.

To change colors or add categories, edit the colors table at the top and add a new if name:find(...) branch to get_label_and_color. The render loop never needs to change.