Events and client/server communication
Everything in Isle Modkit scripts is driven by events. You register a handler with modkit.events.add(name, fn) and the host calls it.
The paths
| From | To | Call | Handler receives |
|---|---|---|---|
| Game server | server scripts | built-in events such as playerSpawned |
player, sometimes more |
| Client script | server scripts | modkit.events.callRemote(name, ...) |
player of the sender, then the arguments |
| Server script | one client | player:call(name, ...) |
the arguments |
| Server script | all clients | modkit.events.callAll(name, ...) |
the arguments |
| Server script | server scripts of all resources | modkit.events.call(name, ...) |
the arguments |
| Client script | client scripts of all resources | modkit.events.call(name, ...) |
the arguments |
| UI page | the client script that opened it | modkit.trigger(name, ...) in the page |
the arguments, on browser:on(name, fn) |
| Client script | its UI page | browser:call(name, ...) |
the arguments, on modkit.events.add in the page |
A UI page can not talk to the server. It talks to its client script, and the client script talks to the server.
Ping pong example
server.lua
modkit.events.add("ping", function(player, value)
print(player.name .. " sent " .. tostring(value))
player:call("pong", value + 1)
end)
client.lua
modkit.events.add("onServerConnected", function()
modkit.events.callRemote("ping", 41)
end)
modkit.events.add("pong", function(value)
print("server answered " .. tostring(value))
end)
Argument types
Arguments travel as a flat JSON array. Strings, numbers, booleans and nil arrive with their type. A Lua table does not survive the trip. Encode it yourself.
player:call("inventory", modkit.json.encode({ meat = 3, bones = 1 }))
modkit.events.add("inventory", function(text)
local items = modkit.json.decode(text)
end)
When a UI page sends an object or an array, the client script receives it as raw JSON text. Decode it with modkit.json.decode.
Who sent it
On the server the first argument of a client event is always the player table of the sender. The server takes the identity from the connection, never from the message. A client can not send an event in the name of another player.
A client can send any event name with any arguments. Treat every argument as untrusted input. Check permissions with player.admin before you act.
modkit.events.add("giveGrowth", function(player, amount)
if not player.admin then return end
amount = tonumber(amount)
if not amount or amount < 0 or amount > 1 then return end
player:setGrowth(amount)
end)
Clients can not send the names of the built-in server events. The server drops playerConnected, playerDisconnected, playerSpawned, playerDied, playerJoined, playerLeft, chat, chatCommand and resourceStart when they come from a client, and writes a log line.
Built-in events
The full list with arguments is in the events reference. The most used ones are these.
Server: playerConnected, playerSpawned, playerDied, playerDisconnected, playerJoined, playerLeft, chat, chatCommand, resourceStart.
Client: onClientReady, onServerConnected, resourceStart.
playerConnected and playerJoined are different things. playerConnected fires once per visit, when the script link of a new player opens. playerJoined fires right after it, and again every time the script link comes back after a drop. Use playerJoined when you want to send something to the client scripts.
Cancelling
Only chat can be cancelled. Return false from a handler and the message is not delivered to anyone.
modkit.events.add("chat", function(player, text, mode)
if text:lower():find("badword", 1, true) then
player:message("That word is not allowed here.")
return false
end
end)
Removing a handler
Keep the function in a variable and pass the same function to remove.
local function onSpawn(player) print(player.name) end
modkit.events.add("playerSpawned", onSpawn)
modkit.events.remove("playerSpawned", onSpawn)
Timing
The server checks the player list twice per second. playerSpawned, playerDied and playerDisconnected can be up to half a second late. playerConnected waits for the script link, which opens about 45 seconds after the game began to connect. Client events are handled on the next server tick, about 25 ms later. The client runs its scripts about five times per second, so a server event reaches a client handler with up to 200 ms extra delay.