Skip to content

Local player and vehicle API ​

Shared types ​

lua
Vector3 = { x = number, y = number, z = number }

All returned positions and velocities are snapshots. Handle methods use colon syntax, for example player:health(). Handles are generation-safe and must not be retained across death, respawn, disconnect, or session replacement.

Acquire the local player ​

samp.player.local_player() ​

Requires game.player.read. Returns nil when the local player is unavailable, otherwise a Player Handle:

FieldTypeMeaning
type"player"Handle kind.
poolIdintegerCurrent local player pool ID.
generationintegerLocal-player generation.
sessionIdintegerOwning session.

Player Handle methods ​

SignaturePermissionReturns / rules
player:is_valid()game.player.readboolean; never raises merely because the Handle is stale.
player:position()game.player.readVector3.
player:health()game.player.readnumber.
player:armor()game.player.readnumber.
player:velocity()game.player.readVector3.
player:vehicle()game.vehicle.readcurrent Vehicle Handle or nil.
player:set_health(value)game.player.writevalue is finite 0..1000.
player:set_armor(value)game.player.writevalue is finite 0..1000.
player:set_position(vector)game.player.writeeach component is finite -100000..100000.
player:set_velocity(vector)game.player.writeeach component is finite -1000..1000.

Setters return nothing and are available only in a managed callback: an event, timer, task, or menu-control callback. They are unavailable while evaluating the entry file. draw.hud is an event callback and therefore managed, but gameplay writes there are strongly discouraged because it is a per-frame hot path.

Any method other than is_valid() raises an error if the Handle is stale. Check validity after delayed work:

lua
local player = samp.player.local_player()
samp.timer.after(500, function()
    if player ~= nil and player:is_valid() then
        samp.log.info(samp.format.number(player:health(), 1))
    end
end)

Vehicle Handle ​

player:vehicle() represents only the local player's current vehicle. It is invalidated when the player leaves or changes vehicle, or when the player generation/session changes.

FieldTypeMeaning
type"vehicle"Handle kind.
poolIdintegerCurrent vehicle pool ID.
generationintegerLocal-player generation.
sessionIdintegerOwning session.
SignaturePermissionReturns / rules
vehicle:is_valid()game.vehicle.readboolean.
vehicle:position()game.vehicle.readVector3.
vehicle:health()game.vehicle.readnumber.
vehicle:velocity()game.vehicle.readVector3.
vehicle:set_health(value)game.vehicle.writefinite 0..10000.
vehicle:set_position(vector)game.vehicle.writecomponents -100000..100000.
vehicle:set_velocity(vector)game.vehicle.writecomponents -1000..1000.

Vehicle setters follow the same managed-callback rule and return nothing.

API 1.1 player snapshots ​

The following methods require game.player.read and return snapshots rather than live game objects:

MethodReturn
player:weapon(){ id, ammo, clipAmmo, state }; state is ready, firing, reloading, out_of_ammo, or melee_contact.
player:aim(){ active, cameraMode, direction, position, aimZ, zoom }; returns nil when no finite aim snapshot is available.
player:motion(){ activity, moveState, onGround, inAir, aiming, firing }.
player:skin()Current local model ID.
player:animation()Current synchronization animation code; 0 means no synchronized animation.
player:task(){ category, nativeType, nativeName, type, name }; category is none, driving, combat, movement, animation, interaction, or other.

player:skin(), player:animation(), and player:task() are read-only and may return the latest validated snapshot. Their corresponding change events are documented in Event payloads.

Local-player writes added in API 1.1 ​

player:set_skin(id) requires game.player.write and accepts a loaded, valid Ped model ID. player:set_weapon(id, ammo) gives and selects a weapon; player:set_ammo(id, ammo) changes the total ammunition for that weapon. All three methods are managed-phase, local client operations. Server updates or a respawn may overwrite their results.

lua
local player = samp.player.local_player()
if player and player:is_valid() then
    player:set_skin(23)
    player:set_weapon(24, 30)
    player:set_ammo(24, 90)
end

API 1.1 vehicle snapshots ​

The current vehicle Handle adds these read methods, all requiring game.vehicle.read:

MethodReturn
vehicle:state(){ model, heading, engineOn, lightsOn, sirenOn }.
vehicle:seat()Current seat; driver is 0, passengers are 1..n, or nil when stale.
vehicle:occupants(){ driver, passengers, capacity, total }; only counts are exposed.

vehicle.state_changed reports changes while the local player remains in the same vehicle. Use player.vehicle_entered and player.vehicle_left for vehicle lifecycle changes.

vehicle:state() returns { model, heading, engineOn, lightsOn, sirenOn }; heading is nil when the engine cannot provide a finite value. vehicle:seat() returns 0 for the driver, 1..n for passengers, or nil when the player is no longer in that vehicle. vehicle:occupants() returns { driver, passengers, capacity, total } and never exposes other occupants.