Local player and vehicle API
Shared types
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:
| Field | Type | Meaning |
|---|---|---|
type | "player" | Handle kind. |
poolId | integer | Current local player pool ID. |
generation | integer | Local-player generation. |
sessionId | integer | Owning session. |
Player Handle methods
| Signature | Permission | Returns / rules |
|---|---|---|
player:is_valid() | game.player.read | boolean; never raises merely because the Handle is stale. |
player:position() | game.player.read | Vector3. |
player:health() | game.player.read | number. |
player:armor() | game.player.read | number. |
player:velocity() | game.player.read | Vector3. |
player:vehicle() | game.vehicle.read | current Vehicle Handle or nil. |
player:set_health(value) | game.player.write | value is finite 0..1000. |
player:set_armor(value) | game.player.write | value is finite 0..1000. |
player:set_position(vector) | game.player.write | each component is finite -100000..100000. |
player:set_velocity(vector) | game.player.write | each 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:
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.
| Field | Type | Meaning |
|---|---|---|
type | "vehicle" | Handle kind. |
poolId | integer | Current vehicle pool ID. |
generation | integer | Local-player generation. |
sessionId | integer | Owning session. |
| Signature | Permission | Returns / rules |
|---|---|---|
vehicle:is_valid() | game.vehicle.read | boolean. |
vehicle:position() | game.vehicle.read | Vector3. |
vehicle:health() | game.vehicle.read | number. |
vehicle:velocity() | game.vehicle.read | Vector3. |
vehicle:set_health(value) | game.vehicle.write | finite 0..10000. |
vehicle:set_position(vector) | game.vehicle.write | components -100000..100000. |
vehicle:set_velocity(vector) | game.vehicle.write | components -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:
| Method | Return |
|---|---|
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.
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)
endAPI 1.1 vehicle snapshots
The current vehicle Handle adds these read methods, all requiring game.vehicle.read:
| Method | Return |
|---|---|
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.