CS2 Lua API

entity

The entity module finds game entities: players, weapons, game rules and any other objects. Methods of the entity object itself are described on the "entity: methods" page.

The entity object#

The module functions return an entity object (entity). Through it you can call methods (pawn:health()) and read and write any game schema field by name (pawn.m_iHealth).

  • The object remembers a specific entity. If the entity is deleted, the object becomes invalid and does not turn into another entity, even if its slot is reused.
  • Objects of the same entity are equal with ==.
  • tostring(ent) gives entity<ClassName>: <index>.

After the entity is deleted almost all methods of its object give the error bad entity index. Only ent:entindex() and ent:is_valid() work. If you keep objects between frames, check ent:is_valid().

In CS2 a player is two entities: the controller (CCSPlayerController: name, slot, score) and the pawn (C_CSPlayerPawn: model, health, position, weapons). entity.local_player() returns both.

entity.entindex(index: number)#

Entity by index.

Parameter Type Description
index number entity index

Returns: entity or nil if the slot is empty or the index is outside 0..32766.

local world = entity.entindex(0)
print(world)   -- the world entity, index 0

entity.handle(handle: number)#

Entity by its full handle (as returned by ent:handle()). Handy to keep a reference to an entity as a number.

Parameter Type Description
handle number entity handle

Returns: entity or nil if the entity is already deleted.

local saved = nil

events.render:set(function()
    local me = entity.local_pawn()
    if me and not saved then saved = me:handle() end
    if saved and entity.handle(saved) == nil then
        print("The saved pawn was deleted")
        saved = nil
    end
end)

entity.playerslot(slot: number)#

Player controller by slot (entity index slot + 1).

Parameter Type Description
slot number player slot, 0..64; -1 — no player

Outside -1..64 — error invalid player slot.

Returns: entity or nil.

for slot = 0, globals.maxplayers - 1 do
    local ctrl = entity.playerslot(slot)
    if ctrl then print(slot, " ", ctrl:name()) end
end

entity.userid(userid: number)#

Player controller by the userid from game events.

Parameter Type Description
userid number player userid

Returns: entity or nil.

local ctrl = entity.local_controller()
if ctrl then
    print(entity.userid(ctrl:userid()) == ctrl)   --> true
end

entity.instance(ptr: lightuserdata|cdata)#

Entity by a pointer to an object in game memory.

Parameter Type Description
ptr lightuserdata or cdata pointer to the entity object

Returns: entity or nil if the pointer does not belong to any entity.

local me = entity.local_pawn()
if me then
    print(entity.instance(me:data()) == me)   --> true
end

Enumerating entities#

list, match, gmatch search by the C++ class name ("C_CSPlayerPawn"), the designer_* functions by the designer name ("cs_player_controller"), case-insensitively.

  • cls not passed — all entities are enumerated.
  • derived = true — classes derived from cls match too.
  • An unknown or empty name — error '<name>' is not a valid entity class/designer name.

entity.list(cls?: string, derived?: boolean)#

All matching entities.

Parameter Type Description
cls string C++ class name
derived boolean include derived classes, default false

Returns: table — an array of entity.

local all   = entity.list()
local pawns = entity.list("C_CSPlayerPawn")
local ents  = entity.list("C_BaseEntity", true)   -- everything derived from C_BaseEntity
print(#all, " ", #pawns, " ", #ents)

entity.match(cls?: string, derived?: boolean)#

The first matching entity.

Parameter Type Description
cls string C++ class name
derived boolean include derived classes, default false

Returns: entity or nil.

local c4 = entity.match("C_PlantedC4")
if c4 then print("The bomb is at ", tostring(c4:origin())) end

entity.gmatch(cls?: string, derived?: boolean)#

An iterator for for ... in. The list is collected when gmatch is called.

Parameter Type Description
cls string C++ class name
derived boolean include derived classes, default false

Returns: function — an iterator.

for ctrl in entity.gmatch("CCSPlayerController") do
    print(ctrl:name())
end

entity.designer_list(name?: string, derived?: boolean)#

All entities with the designer name name.

Parameter Type Description
name string designer name
derived boolean include derived classes, default false

Returns: table — an array of entity.

print("Controllers: ", #entity.designer_list("cs_player_controller"))

entity.designer_match(name?: string, derived?: boolean)#

The first entity with the designer name name.

Parameter Type Description
name string designer name
derived boolean include derived classes, default false

Returns: entity or nil.

local ctrl = entity.designer_match("cs_player_controller")
print(ctrl)

entity.designer_gmatch(name?: string, derived?: boolean)#

An iterator over entities with the designer name name.

Parameter Type Description
name string designer name
derived boolean include derived classes, default false

Returns: function — an iterator.

for ctrl in entity.designer_gmatch("cs_player_controller") do
    print(ctrl:entindex(), " ", ctrl:name())
end

entity.designer_vdata(name: string)#

Weapon data (CCSWeaponBaseVData) by the technical item name, without an entity.

Parameter Type Description
name string item name: "weapon_ak47", "weapon_awp" and so on; case-sensitive

Returns: declared_class or nil if there is no item with that name. Fields are read by schema names, as with ent:vdata().

local v = entity.designer_vdata("weapon_ak47")
if v then
    print(v.m_szName, " damage: ", v.m_nDamage)
end

entity.vdata(cls: string)#

Weapon data by the C++ class name. The class is converted to its designer name, then it works like entity.designer_vdata. Works only for item classes; for other classes it returns nil.

Parameter Type Description
cls string C++ class name, for example "C_AK47"

An unknown class name gives the error '<name>' is not a valid entity class/designer name.

Returns: declared_class or nil.

local v = entity.vdata("C_AK47")
if v then print(v.m_szName) end

entity.local_player()#

The local player: controller and pawn.

Returns: entity, entity — controller and pawn. If there is no pawn — ctrl, nil; if there is no controller — nil, nil.

local ctrl, pawn = entity.local_player()
if pawn then
    print(ctrl:name(), ": ", pawn:health(), " HP")
end

entity.local_controller()#

Returns: entity or nil — the local player's controller.

local me = entity.local_controller()
if me then print("My slot: ", me:playerslot()) end

entity.local_pawn()#

Returns: entity or nil — the local player's pawn.

local me = entity.local_pawn()
if me and me:is_alive() then
    print("Speed: ", me:velocity():length2d())
end

entity.players(enemies?: boolean, dead?: boolean)#

Players as a table {[controller] = pawn}. Players outside the server's visibility (dormant) are always skipped.

Parameter Type Description
enemies boolean true — only opponents; default false
dead boolean true — include dead players; default false

Returns: table — {[entity] = entity}.

for ctrl, pawn in pairs(entity.players(true)) do
    print(ctrl:name(), ": ", pawn:health(), " HP")
end

entity.pawns(enemies?: boolean, dead?: boolean)#

Same as players, but the result is an array of pawns.

Parameter Type Description
enemies boolean true — only opponents; default false
dead boolean true — include dead players; default false

Returns: table — an array of entity.

local font = render.load_font("Verdana", 14, "outline")

-- Count of alive opponents and their total health
events.render:set(function()
    local enemies, total_hp = entity.pawns(true), 0
    for _, pawn in ipairs(enemies) do
        total_hp = total_hp + pawn:health()
    end
    render.text(vector2(20, 80), color(255, 120, 120, 255), font, nil, "Enemies: ", #enemies, "  HP: ", total_hp)
end)

entity.controllers()#

All player controllers, without filters.

Returns: table — an array of entity.

print("Players on the server: ", #entity.controllers())

entity.player_resource()#

Returns: entity or nil — the player resource entity.

print(entity.player_resource())

entity.game_rules()#

Game rules (C_CSGameRules).

Returns: declared_class or nil. Fields are read by schema names, see "Schema types".

local rules = entity.game_rules()
if rules and rules.m_bWarmupPeriod then
    print("Warmup is on")
end

entity.game_mode_rules()#

Rules of the current game mode (m_pGameModeRules of the game rules).

Returns: declared_class or nil.

local mode = entity.game_mode_rules()
print(mode and mode:classname() or "none")