Skip to main content

Client events

Every built-in event the client fires to its scripts. Register a handler with Event.Add in any client or shared script; see Events for how handlers, cancelling and custom events work. Messages sent by the server with Net.SendToPlayer/Net.Broadcast are not events of this list, see Net.

Available on: Client

Shared scripts also run on the server, where a different set of events fires: see Server events. OnResourceStart, OnResourceStop, OnPlayerJoin, OnPlayerQuit, OnChat, OnPlayerTeleport, OnPlayerDamage, OnPlayerKilled, OnVehicleDamage and OnVehicleDestroy exist on both sides, with differences described on each page.

Unless an event says otherwise:

  • it can't be cancelled (Event.Cancel() has no effect),
  • what the handler returns is ignored,
  • it only concerns this player's game: other players' games fire their own events, and nothing is sent to the server.

Events about objects (players, vehicles) only fire for networked objects this client knows about, that is the ones streamed in around the local player (see World). The game's own objects that aren't networked never fire them.

EventWhen
OnResourceStarta resource started on this client
OnResourceStopa resource is stopping on this client
OnClientJointhis client finished joining the server
OnPlayerJoinanother player joined
OnPlayerQuitanother player left
OnUpdateevery game update, before the multiplayer update
OnPostUpdateevery game update, after the multiplayer update
OnRenderevery frame, before the UI is drawn
OnPostRenderevery frame, after the UI is drawn
OnKeyDowna key or mouse button was pressed
OnKeyUpa key or mouse button was released
OnMouseDownthe left or right mouse button was pressed
OnMouseWheelthe mouse wheel moved
OnLocalPlayerInputthe game read an active input action (cancellable)
OnWaypointPlacethe player is placing a map waypoint (cancellable)
OnWaypointRemovethe map waypoint is being removed (cancellable)
OnScanStartthe scan overlay is opening (cancellable)
OnScanEndthe scan overlay is closing (cancellable)
OnChata chat message arrived
OnPlayerTeleporta player finished a scripted teleport or respawn
OnPlayerRagdollStarta player started ragdolling
OnPlayerRagdollEnda player stopped ragdolling
OnPlayerKickeda player's character was kicked
OnPlayerGrappleHita player's character was hit by a grappling hook
OnPlayerDamagea player was damaged
OnPlayerKilleda player's health reached 0
OnVehicleDamagea vehicle was damaged
OnVehicleDestroya vehicle's health reached 0
OnVehicleExplodea vehicle exploded in this game
OnVehicleCollisiona vehicle collided
OnVehiclePartChangedStatea vehicle door or part opened or closed
OnVehicleNitrousUsea vehicle is using nitrous
OnVehicleTurboJumpa vehicle turbo jumped
OnVehicleHornPlaya vehicle's horn started
OnVehicleHornStopa vehicle's horn stopped
OnVehicleRenderevery frame, for each vehicle

Resources and connection​

OnResourceStart(name)​

Fires when a resource has started on this client: all its client and shared scripts have run their top level without errors. It fires in every running resource, including the one that just started, so compare name with Resource.Name to react only to your own start. It doesn't fire for resources that were already running when your resource started.

The client starts the resources the server is running when it joins (before OnClientJoin), and again every time the server starts, restarts or updates one of them. A start asked for from inside an event handler happens at the next resource update. A restart fires OnResourceStop and then OnResourceStart. The server learns about each start through OnPlayerResourceAction.

Parameters

NameTypeDescription
namestringThe name of the resource that started.

Frequency: once per resource start.

Example

Event.Add("OnResourceStart", function(name)
if name == Resource.Name then
Local.UnlockAbility(Ability.Parachute)
Local.UnlockAbility(Ability.Wingsuit)
end
end)

OnResourceStop(name)​

Fires when a resource is about to stop on this client, before its scripts are shut down: its own handlers still run. It fires in every running resource, including the one that is stopping. Use it to undo what your resource changed in the game (abilities, UI, weather...), since the game doesn't undo it for you.

A resource stops when the server stops, restarts or updates it, and every running resource stops when the client disconnects or the game closes.

Parameters

NameTypeDescription
namestringThe name of the resource that is stopping.

Frequency: once per resource stop.

Example

Event.Add("OnResourceStop", function(name)
if name == Resource.Name then
-- give back the abilities this mode removed
Local.UnlockAbility(Ability.Tether)
end
end)

OnClientJoin()​

Fires once per connection, when this client has finished its first resource sync with the server, has started the resources the server is running, and has told the server it joined. It's the moment to send the server your first Net messages.

It doesn't fire again for the same connection, so a resource started later (for example one the server restarts while you play) never sees it. Such a resource can check at the top level whether the client already joined, as in the example.

Parameters none.

Frequency: once per connection.

Example

local function ask_state()
Net.Send("drones_state")
end

Event.Add("OnClientJoin", ask_state)

-- the resource was (re)started after the join: no OnClientJoin will come
if World.LocalPlayer() then
ask_state()
end

OnPlayerJoin(client)​

Fires when another player finishes joining the server while this client is connected. The players that were already on the server when this client joined don't fire it (they are already in the player list), and neither does this client itself (see OnClientJoin).

Parameters

NameTypeDescription
clientPlayerHandleThe player that joined. See Player.

Frequency: once per player joining.

Example

Event.Add("OnPlayerJoin", function(client)
print(client:GetName() .. " joined")
end)

OnPlayerQuit(client)​

Fires when another player leaves the server. The player is still in the player list while the handlers run, so you can still read its name; it is removed right after.

Parameters

NameTypeDescription
clientPlayerHandleThe player that is leaving.

Frequency: once per player leaving.

Example

local scoreboard = {}

Event.Add("OnPlayerQuit", function(client)
scoreboard[client:GetNetId()] = nil
end)

Frame​

OnUpdate()​

Fires on every game update (once per game frame), before the multiplayer systems update: the resource update (timers, queued resource actions), the players and the network sync all run after it. Game logic goes here: reading and changing the game, players, vehicles and the world. Use World.GetUpdateDeltaTime() (see World) for the time since the last update.

It starts firing once the game has loaded past its boot (from the main menu or the loading screen on).

Parameters none.

Frequency: every game frame. Keep handlers light: a slow handler lowers the frame rate.

Example

local last = 0

Event.Add("OnUpdate", function()
local now = Client.GetElapsedSeconds()

if now - last >= 1 then
last = now

local player = World.LocalPlayer()

if player then
print("health: " .. player:GetHealth())
end
end
end)

OnPostUpdate()​

Fires on every game update, right after OnUpdate and the multiplayer update (timers, players, network), before the game runs its own update. Use it for work that must see the latest network state of this frame.

Parameters none.

Frequency: every game frame.

Example

Event.Add("OnPostUpdate", function()
local player = World.LocalPlayer()

if player and player:GetPosition().y < -50 then
Net.Send("fell_out_of_world")
end
end)

OnRender()​

Fires every time a frame is presented, before the name tags and the webview pages (see UI) are drawn over it, so anything you draw here ends up under the UI. It comes from the game's rendering, not from its update: use it to draw and to feed screen positions to pages (see Render and Camera), and keep game logic and game queries in OnUpdate. It fires on every frame, including loading screens and menus.

Parameters none.

Frequency: every rendered frame.

Example

-- "marker_page" is a webview this resource created (see UI)
local target = vec3(2370, 300, 1210)

Event.Add("OnRender", function()
local screen = Camera.WorldToScreen(target)

if screen then
WebView.SendMessage("marker_page", "marker", { x = screen.x, y = screen.y })
end
end)

OnPostRender()​

Fires every time a frame is presented, after the name tags and the webview pages were drawn, so anything you draw here ends up over the UI.

Parameters none.

Frequency: every rendered frame.

Example

local frames = 0

Event.Add("OnPostRender", function()
frames = frames + 1
end)

Timer.Set(function()
print("fps: " .. frames)
frames = 0
end, 1000, -1)

Input​

The key and mouse events come straight from the game window's messages, before the game sees them. They fire whether or not the game's input is enabled (Input.SetEnabled, see Input), and also in menus and loading screens. They don't fire for input that goes to a webview: keys typed while a page has keyboard focus, clicks and wheel over a focused page, and all of them while the UI captures the game's input (see UI).

OnKeyDown(key)​

Fires when a key is pressed, including system keys (Alt combinations, F10). Holding a key down repeats the event at the keyboard's repeat rate, so keep a "held" state if you want to act once per press (see the example). It also fires when a mouse button is pressed, with the button's code (Key.MouseLeft...).

Parameters

NameTypeDescription
keyintegerThe Windows virtual-key code of the key, a Key value (e.g. Key.F1).

Notes

  • Shift, Ctrl and Alt fire it twice: once with the side-specific code (Key.LeftShift...) and once with the generic code (Key.Shift...).

Frequency: once per press, then repeatedly while held.

Example

local held = {}

Event.Add("OnKeyDown", function(key)
if held[key] then return end -- auto-repeat

held[key] = true

if key == Key.F2 then
Net.Send("menu_open")
end
end)

Event.Add("OnKeyUp", function(key)
held[key] = nil
end)

OnKeyUp(key)​

Fires when a key or mouse button is released, with its code. For Shift, Ctrl and Alt it fires with the side-specific code, and with the generic code once neither side is held any more.

Parameters

NameTypeDescription
keyintegerThe Windows virtual-key code of the released key, a Key value.

Frequency: once per release.

Example

Event.Add("OnKeyUp", function(key)
if key == Key.F7 then
Net.Send("toggle_spawn_menu")
end
end)

OnMouseDown(button)​

Fires when a mouse button is pressed over the game, right before the matching OnKeyDown. Releases don't fire it (use OnKeyUp). A double click fires it twice.

Parameters

NameTypeDescription
buttonintegerKey.MouseLeft, Key.MouseRight, Key.MouseMid, Key.MouseX4 or Key.MouseX5.

Frequency: once per click.

Example

Event.Add("OnMouseDown", function(button)
if button == Key.MouseRight then
print("right click")
end
end)

OnMouseWheel(delta)​

Fires when the mouse wheel moves over the game.

Parameters

NameTypeDescription
deltavec2x is always 0. y is the movement in wheel notches: positive when the wheel is rolled away from the user, negative towards the user (a fast spin can give more than 1 per event). A horizontal wheel is reported in y too.

Frequency: once per wheel message.

Example

local zoom = 10

Event.Add("OnMouseWheel", function(delta)
zoom = math.max(2, math.min(50, zoom - delta.y))
end)

OnLocalPlayerInput(action)​

Fires when the game reads one of the local player's input actions (jump, fire, enter vehicle, steer...) and it is active: a pressed button or a non-zero analog value. Cancelling it hides the input from the game for that read, which is how you block game actions while a menu or the chat is open.

The game reads many actions every frame, some several times, so this fires very often while the player is pressing something: keep the handler fast. It doesn't fire while the game input is disabled with Input.SetEnabled(false) (all input is already blocked then).

Parameters

NameTypeDescription
actionintegerThe game's 32-bit hash of the input action's name. The InputAction table has the named ones (InputAction.Jump), and Hash computes it from a name (Hash("jump") == InputAction.Jump).

Cancellable: yes. Cancelling makes the game see the action as not pressed (or 0 for an analog value) for that read. Other reads of the same action in the same frame fire the event again, so cancel every time.

Frequency: every read of an active action, often several times per frame.

Example

local menu_open = false

-- no jumping while the menu is open
Event.Add("OnLocalPlayerInput", function(action)
if menu_open and action == InputAction.Jump then
Event.Cancel()
end
end)

Map and HUD​

OnWaypointPlace(position)​

Fires when the player places a waypoint on the map, before it is placed. Setting it from a script with World.SetWaypoint (see World) doesn't fire it.

Parameters

NameTypeDescription
positionvec3Where the waypoint is being placed, in world coordinates.

Cancellable: yes. Cancelling it doesn't place the waypoint (any previous waypoint stays).

Frequency: once per waypoint placed.

Example

Event.Add("OnWaypointPlace", function(position)
-- in this mode waypoints teleport the player instead
Event.Cancel()
Net.Send("teleport_to", position)
end)

OnWaypointRemove(automatic)​

Fires when the map waypoint is about to be removed, before it is removed. Clearing it from a script with World.ClearWaypoint doesn't fire it.

Parameters

NameTypeDescription
automaticbooleantrue when the game removes it by itself during its map marker update (for example when the player reaches it), false when it's removed some other way, such as the player clearing it on the map.

Cancellable: yes. Cancelling it keeps the waypoint.

Frequency: once per removal attempt.

Example

Event.Add("OnWaypointRemove", function(automatic)
if automatic then
print("waypoint reached")
end
end)

OnScanStart()​

Fires when the game is about to show the scan overlay (the vision mode that highlights points of interest), before it is shown. Local.ShowScan(true) (see Local) doesn't fire it.

Parameters none.

Cancellable: yes. Cancelling it keeps the overlay from opening.

Frequency: once per opening.

Example

-- no scanning in this game mode
Event.Add("OnScanStart", function()
Event.Cancel()
end)

OnScanEnd()​

Fires when the game is about to hide the scan overlay, before it is hidden. Local.ShowScan(false) doesn't fire it.

Parameters none.

Cancellable: yes. Cancelling it keeps the overlay open.

Frequency: once per closing.

Example

Event.Add("OnScanEnd", function()
print("scan closed")
end)

Chat​

OnChat(sender, text)​

Fires when a chat message arrives from the server. Messages written by players arrive after the server let them through (see the server's OnChat), with the sender's name already in the text, and this includes the local player's own messages. Messages broadcast by server scripts with Chat.Broadcast (see Chat) arrive with no sender.

Parameters

NameTypeDescription
senderPlayerHandle or nilThe player that wrote it, nil for a message from the server.
textstringThe text to show. For a player's message it is "<name>: <message>".

Frequency: once per message.

Example

Event.Add("OnChat", function(sender, text)
local me = World.LocalClient()

if sender and me and sender:GetNetId() == me:GetNetId() then
print("(me) " .. text)
else
print(text)
end
end)

Players​

OnPlayerTeleport(player)​

Fires when the server confirms that a player finished a teleport or respawn a server script asked for (see the server's OnPlayerTeleport). It fires on the teleported player's client and on the clients that see that player.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe player's character. See Player.

Frequency: once per scripted teleport or respawn of a player this client sees.

Example

Event.Add("OnPlayerTeleport", function(player)
local me = World.LocalPlayer()

if me and player:GetNetId() == me:GetNetId() then
print("teleported to " .. tostring(player:GetPosition()))
end
end)

OnPlayerRagdollStart(player)​

Fires when a player's character starts ragdolling (falls limp after an explosion, a hit, a crash...). For the local player it fires when the game puts it in ragdoll; for other players when their synced state says so.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe player's character.

Frequency: once each time the player starts ragdolling.

Example

Event.Add("OnPlayerRagdollStart", function(player)
local me = World.LocalPlayer()

if me and player:GetNetId() == me:GetNetId() then
print("down!")
end
end)

OnPlayerRagdollEnd(player)​

Fires when a player's character stops ragdolling.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe player's character.

Frequency: once each time the player stops ragdolling.

Example

Event.Add("OnPlayerRagdollEnd", function(player)
local me = World.LocalPlayer()

if me and player:GetNetId() == me:GetNetId() then
print("back on your feet")
end
end)

OnPlayerKicked(player)​

Fires when the game runs its "kicked" reaction on a player's character, that is when the character is physically kicked in the game. It has nothing to do with being kicked from the server. It fires before the game applies the reaction.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe player's character that was kicked.

Frequency: once per kick.

Example

Event.Add("OnPlayerKicked", function(player)
local client = player:GetClient()

if client then
print(client:GetName() .. " got kicked")
end
end)

OnPlayerGrappleHit(player, position, direction)​

Fires when a player's character is hit by a grappling hook, before the game plays its hit reaction.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe player's character that was hit.
positionvec3Where the hook hit, in world coordinates.
directionvec3The direction of the hit, as the game reports it.

Frequency: once per hit.

Example

Event.Add("OnPlayerGrappleHit", function(player, position, direction)
local me = World.LocalPlayer()

if me and player:GetNetId() == me:GetNetId() then
print("you've been hooked at " .. tostring(position))
end
end)

OnPlayerDamage(player, damager, damage, weapon, position)​

Fires when the server relays a hit on a player that this client sees, the local player included. Hits are reported to the server by the game of the player who caused them, and the server relays the ones its scripts didn't cancel (see the server's OnPlayerDamage). The health is lowered right after the handlers, and OnPlayerKilled follows if the hit took it from above 0 to 0.

Health changes the server makes without a hit (for example a server script calling SetHealth) don't fire it on the client.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe damaged player's character.
damagerPlayerObjectHandle, VehicleHandle, MountedGunHandle, RigidObjectHandle, NPCHandle, TetherHandle, SandstormHandle or nilWhat caused the damage, as its typed handle. nil when unknown or when this client doesn't know that object.
damagenumberThe health lost, as a fraction of the maximum health (health goes from 0 to 1).
weaponintegerThe game's 32-bit hash of the weapon's name (see Hash), 0 when there's none.
positionvec3Where the hit landed, in world coordinates.

Frequency: once per relayed hit.

Example

Event.Add("OnPlayerDamage", function(player, damager, damage)
local me = World.LocalPlayer()

if me and player:GetNetId() == me:GetNetId() then
print(string.format("you lost %d%% health", damage * 100))
end
end)

OnPlayerKilled(player, damager, damage, weapon, position)​

Fires when a relayed hit takes a player's health from above 0 to 0, right after its OnPlayerDamage, with the same arguments. Only players this client sees fire it. Later hits on the dead player don't fire it again; once the player respawns, it can be killed again and fires it again.

Parameters

NameTypeDescription
playerPlayerObjectHandleThe player that died.
damagertyped handle or nilWhat dealt the killing damage, nil when unknown.
damagenumberThe health lost by the killing hit (fraction of the maximum).
weaponintegerThe weapon's name hash (see Hash), 0 when there's none.
positionvec3Where the killing hit landed.

Frequency: once per death of a player this client sees.

Example

Event.Add("OnPlayerKilled", function(player, damager)
local killer = damager and damager:AsPlayer()

if killer and killer:GetNetId() ~= player:GetNetId() then
local victim_client = player:GetClient()
local killer_client = killer:GetClient()

if victim_client and killer_client then
print(killer_client:GetName() .. " killed " .. victim_client:GetName())
end
end
end)

Vehicles​

OnVehicleDamage(vehicle, damager, damage, weapon, position)​

Fires when the server relays a hit on a vehicle this client sees, the same way as OnPlayerDamage (see the server's OnVehicleDamage). The game then applies the damage to the vehicle, and OnVehicleDestroy follows if its health reached 0.

Parameters

NameTypeDescription
vehicleVehicleHandleThe damaged vehicle. See Vehicle.
damagertyped handle or nilWhat caused the damage, nil when unknown.
damagenumberThe health lost, as a fraction of the vehicle's maximum health.
weaponintegerThe weapon's name hash (see Hash), 0 when there's none.
positionvec3Where the hit landed.

Frequency: once per relayed hit.

Example

Event.Add("OnVehicleDamage", function(vehicle, damager, damage)
local player = World.LocalPlayer()
local current = player and player:AsPlayer():GetVehicle()

if current and current:GetNetId() == vehicle:GetNetId() then
print(string.format("your vehicle lost %d%% health", damage * 100))
end
end)

OnVehicleDestroy(vehicle, damager, damage, weapon, position)​

Fires when a relayed hit takes a vehicle's health from above 0 to 0, right after its OnVehicleDamage, with the same arguments. Further hits on the destroyed vehicle still fire OnVehicleDamage, but not OnVehicleDestroy again.

Parameters

NameTypeDescription
vehicleVehicleHandleThe destroyed vehicle.
damagertyped handle or nilWhat dealt the final damage, nil when unknown.
damagenumberThe health lost by the final hit (fraction of the maximum).
weaponintegerThe weapon's name hash (see Hash), 0 when there's none.
positionvec3Where the final hit landed.

Frequency: once per destruction.

Example

Event.Add("OnVehicleDestroy", function(vehicle, damager)
print("vehicle " .. vehicle:GetNetId() .. " was destroyed")
end)

OnVehicleExplode(vehicle)​

Fires when a vehicle explodes in this client's game, before the game plays the explosion. Each client fires it from its own game, so it's a client-only event: the server has no equivalent (use OnVehicleDestroy there).

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle that exploded.

Frequency: once per explosion.

Example

Event.Add("OnVehicleExplode", function(vehicle)
print("boom at " .. tostring(vehicle:GetPosition()))
end)

OnVehicleCollision(vehicle, position, normal, impulse)​

Fires every time the game reports a collision for a vehicle on this client: against the ground, buildings, objects or other vehicles. A vehicle scraping along a wall reports collisions continuously, so expect many events per second; filter by impulse to react only to real crashes.

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle that collided.
positionvec3The contact point, in world coordinates.
normalvec3The contact normal.
impulsenumberThe physical impulse the collision applied (in the physics engine's units; larger means a harder hit).

Frequency: once per reported collision, often several per frame.

Example

Event.Add("OnVehicleCollision", function(vehicle, position, normal, impulse)
if impulse > 5000 then
print("hard crash: " .. impulse)
end
end)

OnVehiclePartChangedState(vehicle, part, state)​

Fires when a door or other moving part of a vehicle (trunk, hood, cargo bay door, folding wings...) is told to open or close: when it happens in this client's game, and when the change comes from the server (another player's vehicle, or a vehicle streaming in with a part in a different state).

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle.
partintegerThe part, a VehiclePart value (e.g. VehiclePart.Trunk). See Enums.
stateintegerThe new state, VehiclePartState.Open or VehiclePartState.Closed.

Frequency: once per change.

Example

Event.Add("OnVehiclePartChangedState", function(vehicle, part, state)
if part == VehiclePart.CargoBayDoor and state == VehiclePartState.Open then
print("cargo bay opened")
end
end)

OnVehicleNitrousUse(vehicle)​

Fires on every game update in which a vehicle's nitrous is active, whoever drives it.

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle using nitrous.

Frequency: every game frame while nitrous is active.

Example

local boosting = {}

Event.Add("OnVehicleNitrousUse", function(vehicle)
boosting[vehicle:GetNetId()] = Client.GetElapsedSeconds()
end)

OnVehicleTurboJump(vehicle)​

Fires once when a vehicle performs a turbo jump, at the moment it starts.

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle that jumped.

Frequency: once per jump.

Example

Event.Add("OnVehicleTurboJump", function(vehicle)
print("vehicle " .. vehicle:GetNetId() .. " jumped")
end)

OnVehicleHornPlay(vehicle)​

Fires when a vehicle's horn starts playing.

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle honking.

Frequency: once each time the horn starts.

Example

local honking = {}

Event.Add("OnVehicleHornPlay", function(vehicle)
honking[vehicle:GetNetId()] = true
end)

Event.Add("OnVehicleHornStop", function(vehicle)
honking[vehicle:GetNetId()] = nil
end)

OnVehicleHornStop(vehicle)​

Fires when a vehicle's horn stops playing.

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle that stopped honking.

Frequency: once each time the horn stops.

Example

Event.Add("OnVehicleHornStop", function(vehicle)
print("horn released on vehicle " .. vehicle:GetNetId())
end)

OnVehicleRender(vehicle)​

Fires every frame for every vehicle on this client, while the game updates the vehicle for rendering, as part of the game update (not the render step of OnRender). Use it for per-vehicle work that must run every frame.

Parameters

NameTypeDescription
vehicleVehicleHandleThe vehicle being updated.

Frequency: every frame, once per vehicle. With many vehicles around this adds up quickly: keep the handler minimal.

Example

local closest, closest_distance

Event.Add("OnUpdate", function()
closest, closest_distance = nil, math.huge
end)

Event.Add("OnVehicleRender", function(vehicle)
local player = World.LocalPlayer()

if player then
local distance = (vehicle:GetPosition() - player:GetPosition()):length()

if distance < closest_distance then
closest, closest_distance = vehicle, distance
end
end
end)