JavaScript (window.gmp)
The JavaScript side of the in-game web UI - window.gmp.trigger / on / off, how values are converted between JavaScript and Lua, a TypeScript declaration.
Every page opened in the game (the main document of a Browser, not its iframes) has the
global object window.gmp before its own scripts run. It is the page's only link to the game; the Lua
side is the page's Browser object. The Web UI guide shows it in whole
examples.
gmp.trigger
gmp.trigger(name, ...args)Sends an event to the client script: the functions registered with
browser:on(name, fn) are called with args. Nothing is returned - the script answers
with an event of its own (browser:trigger) when it has something to say.
gmp.trigger("ready"); // the page registered its gmp.on handlers
gmp.trigger("buy", "ItMi_Gold", 5); // browser:on("buy", function(item, amount) ... end)
gmp.trigger("login", { user: "lorem", password: "ipsum" }); // in Lua: data.user, data.passwordgmp.on
gmp.on(name, handler)Registers a function called when the script calls browser:trigger(name, ...);
it gets the script's arguments. Several functions for one name are called in the order of registration;
an exception in one of them is written to the log and does not stop the others.
gmp.on("stats", (s) => {
document.querySelector("#health").textContent = `${s.health} / ${s.maxHealth}`;
});Events the script sends before the page registered its handler are lost - register the handlers first,
then send gmp.trigger("ready").
gmp.off
gmp.off(name, handler)Removes a function registered with gmp.on (the same function object) - e.g. when a component of a
framework is unmounted.
Values between JavaScript and Lua
Arguments are converted like JSON (JSON.stringify in the page, a JSON decoder in the game):
| JavaScript | Lua | Notes |
|---|---|---|
number | number | whole numbers become Lua integers |
string | string | UTF-8 |
true / false | boolean | |
null, undefined | nil | undefined in an array becomes null |
array [1, 2, 3] | table {1, 2, 3} | |
object { a: 1 } | table { a = 1 } | |
Date, Map, Set, class instances | as JSON.stringify makes them | send plain objects |
functions, Symbol | not sent |
From Lua: a table with keys 1..n only becomes an array, any other table an object; an empty table is
{}. Lua functions, characters and other objects cannot be sent - send ids (ch:getId()) and plain data.
One browser:trigger / browser:execute carries at most 4 MB.
TypeScript
type Handler = (...args: any[]) => void;
interface Gmp {
trigger(name: string, ...args: unknown[]): void;
on(name: string, handler: Handler): void;
off(name: string, handler: Handler): void;
}
declare global {
interface Window { gmp?: Gmp }
}
// in the game window.gmp exists; in a normal browser (npm run dev) a stand-in prints the events
export const gmp: Gmp = window.gmp ?? {
trigger: (name, ...args) => console.log("gmp.trigger", name, ...args),
on: () => {},
off: () => {},
};What a page can and cannot do
- Everything of a modern Chromium: ES modules,
fetchof the server's own files (fetch("./data.json")),localStorage(kept while the game runs), 2D canvas, SVG, CSS animations and transitions, web fonts from the server's files. Pages are drawn without the GPU (the game owns it) - prefer CSS and 2D canvas to WebGL. - No internet: requests to other addresses are blocked (see the guide).
- No new windows, no navigation away from the server's files;
alert/confirm/promptshow nothing (the text goes to the log). console.logand errors go to the player's GROnline log (client_debug.log,[WEB]lines).
