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)forpowerup,pickup_modifier,pickup_goldandpickup_healthin turn. - The
activefilter removes duplicates. Each powerup spawn point has four entities stacked at the same position, one per buff variant. Without theactivefilter, the script would draw four overlapping labels at every powerup location. pickup_keynames each pickup. Gold and health pickups go bytype, the four powerups by theirsubclasstoken, and the rest bygame.token_name(e.subclass).get_label_and_colormatches 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
-- 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
endNotes
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.