Параметры событий
Каждый callback(event) получает общий envelope:
| Поле | Тип | Значение |
|---|---|---|
name | string | Точное имя. |
sequence | integer | Монотонный номер доставки. |
timestamp | integer | Монотонное время в мс, не календарное. |
sessionId | integer | Связанная сессия. |
playerGeneration | integer | Связанное поколение игрока. |
Table действует только во время callback. Изменения немаркированных полей не влияют на host.
Lifecycle, frame и UI
| Событие | Дополнительные поля |
|---|---|
plugin.loaded, plugin.unloading, session.started, session.ended, game.ready, server.connected, server.disconnected, player.spawned, player.died | Нет. |
game.frame | deltaSeconds: number. |
draw.hud | deltaSeconds, screenWidth, screenHeight: number. |
ui.menu_opened, ui.menu_closed | Нет; требуется ui.menu. |
ui.control_changed | pluginId, pageId, controlId, valueType, value; switch → boolean, slider/number_input → нормализованный number, варианты и list → string, button/confirm_button → action/click, group → action/toggle. |
ui.control_changed создаётся только интерактивными control. section, text, divider и progress являются display-only; multi_choice возвращает value переключённого варианта, text_input и color_picker отправляют значение после Apply, а list возвращает value выбранного элемента.
На player.spawned заново получайте Handles и leases.
Игрок
| Событие | Разрешение | Payload |
|---|---|---|
player.health_changed | game.player.read | previousHealth, health: number. |
player.vehicle_entered, player.vehicle_left | game.vehicle.read | vehicleId: integer, passenger: boolean. |
player.interior_changed | game.state.read | previousInterior, interior: integer. |
player.weapon_changed | game.player.read | Предыдущее и текущее оружие. |
player.aiming_changed | game.player.read | Предыдущее и текущее состояние прицеливания. |
player.motion_changed | game.player.read | previousActivity, activity, previousMoveState, moveState, onGround, inAir. |
player.vehicle_collision | game.vehicle.read | vehicleId, otherType (vehicle, player, world), optional otherId, impact, speed, position. |
player.skin_changed | game.player.read | previousSkin, skin. |
player.animation_changed | game.player.read | previousAnimation, animation. |
player.task_changed | game.player.read | previousCategory, category, previousType, previousName, type, name. |
world.time_changed | game.state.read | previousHour, previousMinute, hour, minute. |
world.weather_changed | game.state.read | previousWeather, previousHoldTime, weather, holdTime. |
vehicle.health_changed | game.vehicle.read | ID транспорта и прежнее/новое здоровье. |
vehicle.state_changed | game.vehicle.read | vehicleId, previousModel, model, optional previousHeading/heading, а также старые и новые engine/lights/siren. |
player.damage_before требует game.player.write: damage — изменяемое конечное число 0..100000; 0 подавляет урон. Также доступны weaponType, bodyPart, sourceType="player"|"actor"|"entity" и условные sourcePlayerId/sourceActorId. Обработчики видят результат предыдущих; некорректная замена игнорируется; yield запрещён.
Доставка и lifecycle
Игра, сеть и Android UI записывают неизменяемые snapshots в bounded-очередь на 256 элементов; доставка происходит в следующем кадре game thread. Наблюдение сети занимает не более 96 элементов, обычные уведомления — не более 224, чтобы сохранить место для lifecycle. При переполнении новые уведомления отбрасываются, сетевой поток не ждёт Lua.
Доступность игрока и generation синхронизируются отдельно и не теряются из-за переполнения очереди. Состояния снимаются не чаще одного раза за кадр после lifecycle и до game.frame/draw.hud. При прямой смене транспорта сначала приходит player.vehicle_left, затем player.vehicle_entered. После spawn, reconnect или включения плагина первая выборка только создаёт baseline; старые изменения не воспроизводятся, поэтому после смены generation Handle нужно получать заново.
Чат
| Событие | Payload |
|---|---|
chat.message_received | playerId, playerName, message, localPlayer; требует chat.read. |
chat.server_message_received | message, color ARGB; требует chat.read. |
chat.bubble_received | playerId, message, color, drawDistance, durationMs; требует chat.read. |
chat.message_sending (chat.intercept) позволяет менять message и cancelled; строка UTF-8, 1–4096 байт, без NUL/CR/LF и не начинается с /. command.executing (command.intercept) позволяет менять command и cancelled; команда начинается с /, имеет символ после него и те же лимиты. Отмена sticky: true нельзя вернуть в false. Yield запрещён.
Checkpoint и сущности
checkpoint.entered/checkpoint.left требуют game.state.read и содержат kind="normal"|"race", position: Vector3, а также либо size: Vector3, либо radius: number и raceType: integer.
entity.streamed_in/entity.streamed_out требуют game.entity.read и содержат entityType, entityId, streamGeneration. После streamed_out старый Handle недействителен.
input.touch требует ui.input и синхронно вызывается до передачи touch игре; payload содержит action (down, move, up, cancel), pointerId, пиксельные x/y, размеры width/height, ограниченные 0..1normalizedX/normalizedY и изменяемый cancelled. cancelled = true или возврат false поглощает текущую последовательность. camera.mode_changed требует game.state.read и содержит previousMode, mode.
network.packet_received, network.rpc_received, network.packet_sending и network.rpc_sending требуют network.inspect; версии *_before_send требуют network.intercept и позволяют менять только sticky cancelled. Payload — ограниченный префикс до 4096 байт с флагом truncated; небезопасный синхронный перехват работает в fail-open режиме.
pickup.collected требует game.entity.read и содержит pickupId, model, type, position; это только уведомление.
Dialog
dialog.shown требует dialog.read: dialogId (0..32767), styleId (0..5), style (message, input, list, password, tablist, tablist_headers), title, message, primaryButton, secondaryButton. Все строки UTF-8; title и каждая кнопка — до 1024 байт, message — до 16 КиБ.
dialog.responding требует dialog.intercept. Изменяемы accepted: boolean, listItem: integer (-1..65534), input: string (UTF-8, до 4096 байт, без NUL/CR/LF) и cancelled; dialogId только для чтения. Отмена sticky, yield запрещён.
TextDraw
Идентичность: textdrawId (0..3071) плюс положительный textdrawGeneration.
| Событие | Разрешение | Payload |
|---|---|---|
textdraw.shown | textdraw.read | identity, styleId, text, selectable, x, y. |
textdraw.hidden | textdraw.read | identity. |
textdraw.text_changed | textdraw.read | identity, text. |
textdraw.clicking | textdraw.intercept | identity, изменяемый cancelled. |
Text до 4096 байт. Отмена клика sticky, yield запрещён.