Register on the server
server.lua
my-bank:GetBalance.
Options
UgSchema
required
Arguments, from
UgCore.Schema.Define. No schema, no registration.{ max: integer, per: integer }
required
Per-player token bucket:
max calls burst, refilled over per ms.boolean
Rejects players whose
ug-core:Loaded statebag is not true, with not_loaded.boolean
Rejects downed and dead players with
no_permission. They are not flagged.string
ACE the player MUST have, such as
ug.admin.Handler
The handler gets the player’ssource and the validated arguments, and returns one value. It runs in a thread, so it can wait on the database.
If it raises, the client gets internal_error and the error is logged on the server. Clients never see stack traces.
Call from the client
client.lua
Await MUST run in a thread. It times out after 10 seconds. Late answers are ignored.
Use Trigger to avoid blocking:
client.lua
The pipeline
Every request goes through these checks, in order. The first failure answers with an error code and, for most checks, adds to the player’s Guard score. Malformed requests, such as a missing request id, are flagged and get no answer at all.Server to client
The server can ask a client too. The answer is untrusted input, so it MUST match a schema:timeout when the player drops.