Skip to content

Entities ​

The game world is populated with entities, anything that exists in 3D space and can be observed, interacted with, or collided with. Troopers, jungle camps, the midboss, crates, powerup buffs, gravestones, skeletons, and many projectiles (Doorman's luggage cart, Paige's knight charge, and so on) are all entities. Players have their own dedicated accessor, everything else lives in the entity list.

You can also approach detection through particles, modifiers, or other systems, but checking the entity list is usually the first thing to try when designing a script, especially anything ESP or detection-related.

Discovery: Show All Entities ESP ​

The cheat ships with a dev tool that overlays every entity it currently sees with its class name, health, and distance. Enable it from Scripts → Dev Tools → Show All Entities ESP.

Show All Entities ESP overlaying entity labels in-game

In the screenshot above, Graves' Gravestone ultimate shows up as citadel_gravestone_blocker, and the skeletons it spawns are npc_necro_skele. The breakable props next to the gravestone are citadel_breakableprop. Toggle the ESP on to discover the exact class name for whatever entity you're trying to script around, then filter get_world_entities() by that class name.

Include All Entity Types ​

Right below the ESP toggle is Include All Entity Types (off by default). The scanner normally parses only the curated useful entities, everything in the type table below plus known projectiles, gravestones, breakables, and similar gameplay objects. Flip this toggle on to also parse exotic engine entities like env_sky, zipline nodes, func_brush, trigger volumes, and so on. They'll then appear in get_world_entities() alongside the rest.

Leave it off unless a script genuinely needs one of those classes. Scanning the full entity list every frame has measurable overhead, which is why the curated parse is the default.

get_world_entities([filter]) ​

Returns a table of all world entities currently tracked. Optionally filter by a curated type name.

Arguments:

  • filter (string, optional). If provided, only returns entities matching this type name.

Returns: Table of entity tables, each with these fields:

FieldTypeDescription
typestringCurated entity type (see list below). May be empty for entities outside the curated set.
class_namestringInternal RTTI class name (e.g. npc_neutral_sinners_sacrifice, citadel_gravestone_blocker)
x, y, znumberWorld position
healthintegerCurrent HP (if applicable)
max_healthintegerMaximum HP (if applicable)
teamintegerTeam number. 0=none, 1=spectator, 2=amber, 3=sapphire, 4=neutral (jungle, props)
distancenumberDistance from the local player, in meters
currency_valueintegerSoul value (for dropped souls)
pickup_namestring or nilPickup identifier, only present on powerup, pickup_modifier, pickup_gold, and pickup_health types. See Pickup entities.
activebooleanFor pickup entities, whether this variant is currently spawned and collectible. Multiple pickup entities can stack at the same position, only one is active at a time.

Curated types ​

TypeDescription
trooperLane creeps
trooper_bossLane guardian creeps
campJungle camp neutrals and bugs
sinnerSinner sacrifice camps
towerGuardians, walkers, shrines
midbossMid boss
soul_orbDenial/last-hit soul orbs
soul_urnSoul urn pickups
dropped_soulsDropped souls from kills
powerupMap powerups (casting, movement, survival, gun)
pickup_goldSmall gold boxes
pickup_healthHealth pickups
pickup_modifierStat modifier pickups (hp, wp, cd, spirit, firerate)
guided_owlGrey Talon guided arrow projectile
doorman_cartDoorman luggage cart projectile
entityUnclassified entities (props, spawners, items on ground)

For anything outside the curated list, gravestones, breakable props, ability-specific projectiles, skeletons, etc., call get_world_entities() with no argument to get everything, then filter on class_name yourself.

When the local player position isn't valid yet (spectating, pre-spawn, between rounds) get_world_entities() returns an empty table. If you got an entity back, distance is always a valid number. No nil check needed.

Pickup entities ​

Entities of type powerup, pickup_modifier, pickup_gold, and pickup_health carry the extra pickup_name and active fields. Each powerup spawn location has four entities stacked at the same position, one per buff variant, and only one is active at a time. Always filter by active to avoid rendering duplicate labels at the same world point.

Powerup variants (type "powerup", temporary buffs from bridge spawn points):

pickup_nameBuff
survival_powerup_pickupSurvival
casting_powerup_pickupCasting
movement_powerup_pickupMovement
gun_powerup_pickupGun

Modifier variants (type "pickup_modifier", permanent stat bonuses from breakable props):

pickup_nameStat
hp_permanent_pickup_labelMax health
wp_permanent_pickup_labelWeapon damage
cd_permanent_pickup_labelCooldown reduction
spirit_permanent_pickup_labelSpirit power
firerate_permanent_pickup_labelFire rate
ammo_permanent_pickup_labelAmmo

Names ending in _lv2 are upgraded versions of the same stat.

Basic powerup ESP example, labels the four powerup variants by name:

lua
function on_tick()
    for _, p in ipairs(get_world_entities("powerup")) do
        if p.active and p.distance < 200 then
            local sp = draw.world_to_screen(vec3(p.x, p.y, p.z))
            if sp then
                local label = "POWERUP"
                if p.pickup_name then
                    if p.pickup_name:find("survival") then label = "SURVIVAL"
                    elseif p.pickup_name:find("casting") then label = "CASTING"
                    elseif p.pickup_name:find("movement") then label = "MOVEMENT"
                    elseif p.pickup_name:find("gun") then label = "GUN"
                    end
                end
                draw.text(sp.x, sp.y, label, draw.color(255, 0, 255))
            end
        end
    end
end

For a fuller version that handles all four pickup types (powerups, modifiers, gold, health) with color-coded categories, see Powerup ESP.

Examples ​

lua
-- Total count
local all = get_world_entities()
print("Total entities: " .. #all)
lua
-- All sinners with distance
for _, s in ipairs(get_world_entities("sinner")) do
    print("Sinner at " .. s.x .. ", " .. s.y .. " - " .. s.distance .. "m away")
end
lua
-- Mark nearby powerups on screen
for _, p in ipairs(get_world_entities("powerup")) do
    if p.distance < 30 then
        local sp = draw.world_to_screen(vec3(p.x, p.y, p.z))
        if sp then
            draw.text(sp.x, sp.y, "POWERUP", draw.color(255, 255, 0, 255))
        end
    end
end
lua
-- Show camp HP bars
for _, c in ipairs(get_world_entities("camp")) do
    if c.health > 0 and c.distance < 100 then
        local sp = draw.world_to_screen(vec3(c.x, c.y, c.z))
        if sp then
            draw.text(sp.x, sp.y, c.health .. "/" .. c.max_health, draw.color(120, 120, 255, 255))
        end
    end
end
lua
-- Gravestone marker (entity outside the curated list, filter on class_name)
for _, e in ipairs(get_world_entities()) do
    if e.class_name == "citadel_gravestone_blocker" then
        draw.box3d(vec3(e.x, e.y, e.z), 50, 50, 80, draw.color(0, 255, 0, 255), 2)
    end
end
lua
-- Discover unknown entity classes
local seen = {}
function on_tick()
    for _, e in ipairs(get_world_entities()) do
        if not seen[e.class_name] then
            seen[e.class_name] = true
            print("class:", e.class_name)
        end
    end
end

entity.set_rate(type, tier) ​

Controls how frequently entity positions are updated. By default, entities update at sensible speeds. Use this to promote entities to faster updates when your script needs precise, real-time tracking.

Arguments:

  • type (string). Entity type name (e.g. "sinner", "powerup") or internal class name (e.g. "npc_neutral_sinners_sacrifice", "citadel_punchablepowerup").
  • tier (string). One of:
    • "fast". Updated every frame (~16ms). Use for time-critical features like custom parry or precision aiming.
    • "medium". Updated every 200ms. Good for ESP or general tracking.
    • "slow". Updated every ~1 second. For entities you just need to know exist.
    • "default". Revert to the system's default rate for this type.

Returns: nothing.

Notes:

  • You can only promote entities to faster speeds, not demote below their default. For example, sinners default to "medium", setting them to "slow" has no effect.
  • Overrides persist until you call set_rate with "default" or the script is unloaded.
  • Multiple scripts can set different rates for the same type. The fastest rate wins.

Examples:

lua
-- Make powerup positions update every frame for precision tracking
entity.set_rate("powerup", "fast")

-- Revert to default
entity.set_rate("powerup", "default")

-- For a custom auto-parry against a specific projectile, promote it to per-frame
entity.set_rate("citadel_punchablepowerup", "fast")

entity.get_rate(type) ​

Returns the current Lua rate override for an entity type.

Arguments:

  • type (string). Entity type name or class name.

Returns: string: "fast", "medium", "slow", or "default" (no override set).

lua
print(entity.get_rate("sinner"))  -- "default"
entity.set_rate("sinner", "fast")
print(entity.get_rate("sinner"))  -- "fast"
entity.set_rate("sinner", "default")
print(entity.get_rate("sinner"))  -- "default"

Default update rates ​

Entities update at different speeds depending on their importance. You don't need to call set_rate unless you need faster updates than the defaults.

TypeDefault RateNotes
trooperPer-frame when trooper ESP/aimbot is on, otherwise slowHigh count (~100+)
soul_orbPer-frame when soul aimbot/triggerbot is on, otherwise slowHigh count
guided_owlPer-frameAlways fast when present
sinner200 msAlways on
tower200 msAlways on
midboss200 msAlways on
camp200 msAlways on
powerup200 msAlways on
pickup_gold200 msAlways on
pickup_health200 msAlways on
pickup_modifier200 msAlways on
dropped_souls200 msAlways on
soul_urn200 msAlways on
doorman_cart200 msAlways on
entity~1 secondStatic entities (props, items)

Position freshness in get_world_entities() depends on the rate, per-frame entities have positions ~16 ms old, 200 ms entities up to ~200 ms old, slow entities up to ~1 s old. For static entities like props and items, the position never changes so staleness doesn't matter.

Not affiliated with Valve Corporation.