Skip to content

Entity handles

Network pool IDs are reusable. Plugin API therefore identifies a streamed entity by:

text
sessionId + entityType + entityId + streamGeneration

Never cache a native pointer or assume that the same pool ID refers to the same entity later.

lua
local function inspect_entity(event)
    local entity = samp.entity.get(
        event.entityType,
        event.entityId,
        event.streamGeneration
    )

    if entity == nil or not entity:is_valid() then
        return
    end

    local position = entity:position()
    samp.log.info(
        entity.type .. "#" ..
        samp.format.number(entity.poolId, 0) ..
        " at " ..
        samp.format.number(position.x, 1) .. ", " ..
        samp.format.number(position.y, 1) .. ", " ..
        samp.format.number(position.z, 1)
    )
end

samp.events.on("entity.streamed_in", inspect_entity)

Supported types

TypeSelected methods
playername(), npc(), state(), health(), armor(), vehicle_id()
vehiclemodel(), health(), velocity(), heading()
objectmodel(), rotation(), moving(), attachment()
actormodel(), health(), invulnerable(), heading()
pickupmodel(), pickup_type()
text_labeltext(), color(), draw_distance(), test_los(), attachment()

Every handle provides identity fields, is_valid(), and position(). An attached text label's position is its server-configured offset.

Listing current entities

Plugins enabled during a session should establish a baseline with bounded pages:

lua
local next_id = 0
repeat
    local page = samp.entity.list("vehicle", next_id, 64)
    for _, vehicle in ipairs(page.items) do
        if vehicle:is_valid() then
            samp.log.info(samp.format.number(vehicle:model(), 0))
        end
    end
    next_id = page.nextId
until next_id == nil

A handle can become stale between listing and use. Check is_valid() and do not reuse it after a streamed-out event or session change.