Skip to content

Event callback parameters ​

Subscribe with samp.events.on. Every callback receives one event table.

Common envelope ​

Every event contains:

FieldTypeMeaning
namestringExact event name.
sequenceintegerMonotonic dispatch sequence within the runtime. All subscribers to one dispatch see the same value.
timestampintegerMonotonic event timestamp in milliseconds; not wall-clock time.
sessionIdintegerSession associated with the event.
playerGenerationintegerLocal-player generation associated with the event.

Payload tables are valid for the callback only. Copy primitive values if a task needs them later. Unless marked mutable, changing a field has no host effect.

Lifecycle, frame, and UI events ​

EventAdditional fieldsNotes
plugin.loadednoneDispatched after the entry file loads; subscribe during entry evaluation to receive it.
plugin.unloadingnoneDispatched before the plugin's subscriptions, tasks, and effects are released.
session.startednoneA new runtime session began.
session.endednoneCurrent session ended.
game.readynoneGame services became ready.
server.connectednoneMultiplayer connection completed.
server.disconnectednoneConnection ended.
player.spawnednoneAcquire new player/resources here.
player.diednonePrevious player-generation resources must be considered stale.
game.framedeltaSeconds: numberPer-frame managed callback. Keep work bounded.
draw.huddeltaSeconds, screenWidth, screenHeight: numberOnly phase in which samp.draw is available.
ui.menu_openednoneThis plugin's menu became visible; requires ui.menu.
ui.menu_closednoneThis plugin's menu was closed; requires ui.menu.
ui.control_changedpluginId, pageId, controlId, valueType, valueswitch → boolean; slider/number_input → normalized number; choice-like controls and list → string; button/confirm_button → action/click; group → action/toggle. Filter by page and control ID.

ui.control_changed is emitted only for interactive controls. section, text, divider, and progress are display-only. multi_choice sends the value of the option that was toggled, while text_input and color_picker send their value after the user presses Apply. A list sends the selected item value as a string.

Local-player events ​

EventPermissionPayload
player.health_changedgame.player.readpreviousHealth: number, health: number.
player.vehicle_enteredgame.vehicle.readvehicleId: integer, passenger: boolean.
player.vehicle_leftgame.vehicle.readvehicleId: integer, passenger: boolean.
player.interior_changedgame.state.readpreviousInterior: integer, interior: integer.
player.weapon_changedgame.player.readpreviousWeapon: integer, weapon: integer.
player.aiming_changedgame.player.readpreviousAiming: boolean, aiming: boolean.
player.motion_changedgame.player.readpreviousActivity, activity, previousMoveState, moveState, onGround, inAir.
player.vehicle_collisiongame.vehicle.readvehicleId, otherType (vehicle, player, or world), optional otherId, impact, speed, position.
player.skin_changedgame.player.readpreviousSkin: integer, skin: integer.
player.animation_changedgame.player.readpreviousAnimation: integer, animation: integer.
player.task_changedgame.player.readpreviousCategory, category, previousType, previousName, type, name.
world.time_changedgame.state.readpreviousHour, previousMinute, hour, minute.
world.weather_changedgame.state.readpreviousWeather, previousHoldTime, weather, holdTime.
vehicle.health_changedgame.vehicle.readvehicle ID and previous/current health.
vehicle.state_changedgame.vehicle.readvehicleId, previousModel, model, optional previousHeading/heading, and before/after engine, lights, and siren booleans.

player.damage_before ​

Requires game.player.write. Additional fields:

FieldTypeMutability
damagenumberWritable, finite 0..100000; set 0 to suppress damage.
weaponTypeintegerRead-only input.
bodyPartintegerRead-only input.
sourceType"player", "actor", or "entity"Read-only input.
sourcePlayerIdintegerPresent only for a known player source.
sourceActorIdintegerPresent only for a known actor source.

Handlers run by priority and each sees the accepted result of earlier handlers. Invalid replacements are ignored. The callback cannot yield.

Dispatch and lifecycle rules ​

Notifications from the game, network, and Android UI enter a bounded queue of 256 immutable snapshots and are delivered on the next game-thread frame; the network observation share is capped at 96 items and ordinary notifications at 224 items so lifecycle events retain capacity. When a queue is full, new notifications are dropped and the network thread never waits for Lua.

Player availability and generation are synchronized independently of that queue. State-change events are sampled at most once per frame after lifecycle events and before game.frame and draw.hud. A direct vehicle switch emits player.vehicle_left before player.vehicle_entered. Initial observation after spawn, reconnect, or runtime enable establishes a baseline and does not invent historical change events. Handles from an old generation must be reacquired even when an event was queued before the generation changed.

Chat events ​

EventPermissionPayload
chat.message_receivedchat.readplayerId: integer, playerName: string, message: string, localPlayer: boolean.
chat.server_message_receivedchat.readmessage: string, color: integer (ARGB).
chat.bubble_receivedchat.readplayerId: integer, message: string, color: integer, drawDistance: number, durationMs: integer.

chat.message_sending ​

Requires chat.intercept. message: string and cancelled: boolean are writable. The replacement must be valid UTF-8, non-empty, at most 4,096 bytes, contain no NUL/CR/LF, and must not begin with /.

command.executing ​

Requires command.intercept. command: string and cancelled: boolean are writable. The replacement has the same 4,096-byte and line restrictions, must start with /, and must contain at least one character after it.

Cancellation is sticky for both events: once true, later handlers cannot set it back to false. Mutable interception callbacks cannot yield.

Checkpoint events ​

checkpoint.entered and checkpoint.left require game.state.read.

FieldTypeMeaning
kind"normal" or "race"Checkpoint kind.
positionVector3Checkpoint position.
sizeVector3Present for box-shaped checkpoints.
radiusnumberPresent for radius-shaped checkpoints.
raceTypeintegerPresent together with radius.

Touch, camera, and network events ​

input.touch ​

Requires ui.input and is dispatched synchronously before touch input is passed to the game. The payload contains:

FieldMeaning
actiondown, move, up, or cancel.
pointerIdPointer identity, valid only for the current gesture sequence.
x, yCurrent screen-pixel coordinates.
width, heightDisplay dimensions in pixels.
normalizedX, normalizedYCoordinates clamped to 0..1.
cancelledWritable; starts false.

Set writable cancelled = true, or return false, to consume the gesture. Cancellation remains in effect for later events in the same pointer sequence.

camera.mode_changed ​

Requires game.state.read and contains previousMode and mode. The event is read-only and reports a camera mode change; it does not grant camera control.

Network observation and interception ​

The following events contain bounded, read-only packet metadata and a binary payload prefix:

EventPermissionAdditional payload
network.packet_receivednetwork.inspectpacket ID, source index, byte/bit lengths, payload.
network.rpc_receivednetwork.inspectRPC ID, source index, byte/bit lengths, payload.
network.packet_sendingnetwork.inspectoutgoing packet metadata and payload.
network.rpc_sendingnetwork.inspectoutgoing RPC metadata and payload.
network.packet_before_sendnetwork.interceptsame metadata plus writable cancelled.
network.rpc_before_sendnetwork.interceptsame metadata plus writable cancelled.

Network payloads are Lua binary strings capped at 4,096 bytes; byteLength and bitLength retain the original lengths and truncated indicates a prefix. Observation is asynchronous and cannot replace or mutate payloads. Before-send interception is synchronous and best-effort: if the runtime cannot obtain its game-thread lock safely, the packet is allowed through and the runtime records a bypass. It is not an absolute firewall.

Server entity events ​

entity.streamed_in and entity.streamed_out require game.entity.read. Both contain:

FieldType
entityTypeplayer, vehicle, object, actor, pickup, or text_label
entityIdinteger
streamGenerationpositive integer

On streamed_in, pass all three fields to samp.entity.get. On streamed_out, an existing Handle for that identity is stale.

pickup.collected ​

Requires game.entity.read. The event contains pickupId, model, type, and position for the collected pickup. It is a notification only; it does not provide a mutable pickup Handle.

Dialog events ​

dialog.shown ​

Requires dialog.read.

FieldTypeMeaning
dialogIdinteger0..32767.
styleIdintegerNumeric style 0..5.
stylestringmessage, input, list, password, tablist, or tablist_headers.
titlestringDialog title.
messagestringDialog body/list data.
primaryButtonstringPrimary button label.
secondaryButtonstringSecondary button label; may be empty.

All strings are UTF-8. title and each button are at most 1,024 bytes; message is at most 16 KiB.

dialog.responding ​

Requires dialog.intercept. Fields accepted: boolean, listItem: integer (-1..65534), input: string (valid UTF-8, maximum 4,096 bytes, no NUL/CR/LF), and cancelled: boolean are writable. dialogId is read-only. Cancellation is sticky, invalid replacements are ignored, and the callback cannot yield.

TextDraw events ​

All TextDraw identities combine textdrawId (0..3071) and textdrawGeneration (positive integer).

EventPermissionAdditional payload
textdraw.showntextdraw.readidentity, styleId: integer, text: string, selectable: boolean, x: number, y: number.
textdraw.hiddentextdraw.readidentity.
textdraw.text_changedtextdraw.readidentity, text: string.
textdraw.clickingtextdraw.interceptidentity, writable cancelled: boolean.

Text may contain at most 4,096 bytes in an event. Click cancellation is sticky; the interception callback cannot yield.