Repository navigation
Events and Messages
Scripts talk to the game, to each other and across the network through events, element data and exports.
addEvent("teams:changed") -- declare; only scripts on this side raise it
addEventHandler("teams:changed", root, function(team)
print("teams: " .. (getPlayerName(source) or "?") .. " is " .. team)
end)
triggerEvent("teams:changed", source, new) -- raise it on an element (here in a handler)- A handler on an element hears events raised on that element and, with
propagate(the default), on its parents and children. A handler onroothears everything. - Handlers run oldest first, each with copies of the arguments. In a handler,
sourceis the element the event was raised on,thisthe element the handler is on,eventNamethe name, and on the serverclientthe sending player for a remote event. -
cancelEvent()in a handler makestriggerEventreturnfalse; what that means is up to the event. - Events may nest 16 deep.
- Names: 1 to 128 characters of
A-Z a-z 0-9 _ . : -. Prefix your events with your resource's name.
-- server (from the welcome resource on Server Resources)
addEvent("welcome:hello", true) -- true: players' games may raise it
addEventHandler("welcome:hello", root, function(text)
triggerClientEvent(client, "welcome:reply", root, "Hello back from the server")
end)
-- client
addEvent("welcome:reply", true)
addEventHandler("welcome:reply", root, function(text)
line = text
end)
triggerServerEvent("welcome:hello", localPlayer, "hi")| Server to games | Game to server | |
|---|---|---|
| call | triggerClientEvent(sendTo, name, source, ...) |
triggerServerEvent(name, source, ...) |
| arguments | 64 KiB | 64 KiB |
| large data | triggerLatentClientEvent(sendTo, name, bandwidth, source, ...) |
triggerLatentServerEvent(name, bandwidth, source, ...) |
| latent size, rate | up to 16 MiB at 500 B/s to 1 MB/s; 16 under way per package | the same; a game sends at most 64 KiB/s of latent data |
Every message from a player's game is checked by the server:
- The event must be declared remote by the same resource (
addEvent(name, true)). Another resource's remote event cannot be raised for it. An event that is not taken raisesonPlayerTriggerInvalidEventon the sender. - The
sourcemust be the sender's own player element or an element it owns (setElementOwner). - The arguments must decode strictly within the limits.
- Each player may send 50 events a second (a burst of 200), 128 KiB a second (a burst of 384 KiB) and 75 element
data writes a second (a burst of 125). Messages over that are dropped and
onPlayerEventFloodis raised on the player; a game that floods far beyond it is disconnected.
A message from the server to everyone reaches only the players in the instance its source belongs to; a source
outside any instance reaches every player.
-- server
addEventHandler("onPlayerJoin", root, function()
-- a value every game sees, which the player's own game may change
setElementData(source, "team", "red")
setElementDataClientWritable(source, "team", true)
end)
addEventHandler("onElementDataChange", root, function(key, old, new)
if key ~= "team" then
return
end
if new ~= "red" and new ~= "blue" then
print("teams: refused " .. tostring(new))
cancelEvent() -- the old value comes back, and the player's game is sent it
return
end
triggerEvent("teams:changed", source, new)
end)
-- client
setElementData(localPlayer, "team", "green") -- the server refuses this oneA player's game that writes "green" and later "blue" sees its value go green, back to red, then blue; the
server logs:
scripts: teams: teams: Player is red
scripts: client 1: refused: a handler cancelled the write of "team"
scripts: teams: teams: refused green
scripts: teams: teams: Player is blue
sync |
Sent to |
|---|---|
"broadcast" (default) |
every player's game |
"subscribers" |
the players added with addElementDataSubscriber (they get the value at once) |
"local" |
nobody |
A player's game may write a key only if the server opened it on that element with setElementDataClientWritable
and the element is that player's or owned by it. Anything else is refused and the server's value is sent back.
-- in resource "scores"
exports("best", function(name: string): number?
return best[name]
end)
-- in any other resource on the same side
local points = exports.scores:best("Snow Fox")Arguments and results are copied (1 MiB each way); functions cannot be passed. The called function runs under its
own resource's budget. Call with :. Export calls nest at most 8 deep. If the other resource is not running the
call raises an error. Name the resource in [dependencies] require so it starts first.
| Event | Raised on | Arguments | When |
|---|---|---|---|
onResourceStart |
the resource's root | the resource started (use resourceRoot to hear only your own) |
|
onResourceStop |
the resource's root | it is stopping; its storage is written after | |
onResourcePreStart |
root | resource |
another resource is about to start; cancelEvent() keeps it from starting, only with the right function.stopResource
|
onResourceStateChange |
root | resource, old, new |
a resource moved between loaded, starting, running, stopping, stopped
|
onElementDataChange |
the element | key, old, new |
data changed; client is the writing player; cancelEvent() restores the old value |
onPlayerConnecting |
root | name, keyId, join |
a player passed the server's own checks and waits for a slot; keyId is the 64-hex player id. cancelEvent() refuses; see deferJoin
|
onPlayerJoin |
the player | the player joined | |
onPlayerQuit |
the player | reason |
the player left |
onPlayerResourceStart |
the player | resource |
the player's game started a resource's client scripts |
onRoundStart |
the instance | round, drop |
a round began |
onRoundEnd |
the instance | round |
a round ended |
onRiderCheckpoint |
the rider | checkpoint?, index, clock |
the rider passed a split (checkpoint is nil for the level's own gates, whose index counts from 0; clock in ms) |
onRiderFinish |
the rider | clock, points, failed |
the rider's run ended |
onMarkerHit |
the marker or trigger | rider, forward |
a rider hit it |
onPlayerTriggerInvalidEvent |
the player | eventName, isAdded, isRemote, resource |
the player's game sent an event that was not taken |
onPlayerEventFlood |
the player | dropped |
messages from the player were dropped for its rate |
onShutdown |
root | roundEndSecs |
the server is stopping; players are told after your handlers ran |
| Event | Raised on | Arguments | When |
|---|---|---|---|
onClientResourceStart, onClientResourceStop
|
the resource's root | start and stop | |
onClientElementDataChange |
the element | key, old, new |
data changed (a value from the server cannot be cancelled) |
onClientRender |
root | every frame; the only place draw.* works |
|
onClientKey |
root | key, down |
a bindable key (Client Script API) |
onClientRiderLand |
the local rider | airTime, bail |
the rider touched down (seconds in the air; whether it bailed) |
onClientTrick |
the local rider | name, points |
a trick scored |
onClientMarkerHit |
the marker | rider, forward |
the local rider hit a marker |
Servers
- Hosting a Server
- Server Configuration
- Ports and Firewalls
- Server Console
- Operators and Remote Console
- Access Control List
- Bans and Mutes
- The Server List
- Query and LAN Discovery
- Server Resources
- Blocklists
- Maps and Gamemodes
- Logs and Metrics
- Running as a Service
- Running in Docker
- Joining a Server
Scripting
- Resource Packages
- Content IDs and Kinds
- Scripting Overview
- Server Script API
- Client Script API
- Events and Messages
- Script Permissions
- Script Examples
Modding