IMIsle Modkit
Pages in this area

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.