Skip to content

Powerup ESP ​

Color-coded ESP labels for 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 category gets its own color so a glance tells you what's available without reading the label.

What this shows ​

  • One unified loop for all four pickup types. powerup, pickup_modifier, pickup_gold, and pickup_health get read in one pass via get_world_entities(type). The inner logic doesn't care which type it's looking at. The pickup_name field disambiguates.
  • The active filter is doing real work. 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_name drives the label and color. A small get_label_and_color helper substring-matches the pickup name to a human-readable label and a category color. Adding a new pickup type is one line in that function. No other changes.
  • Distance label. A faint distance readout below each pickup label so you can quickly tell what's nearby versus far away without parsing world geometry.

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

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(e.pickup_name)
                    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 ​

The 200 m distance gate keeps the screen clean, pickups across the map don't get labeled. Lower it if you only want immediate surroundings, or remove the check entirely for full-map awareness during pre-fight planning.

get_label_and_color falls back to a generic "PICKUP" label for anything it doesn't recognize. If new pickup classes are added in a future patch, the script keeps working, those pickups just render with the fallback label until a matching case is added. The fallback also strips _pickup.* from the unrecognized name and uppercases it, which usually produces something readable.

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

Not affiliated with Valve Corporation.