Callbacks
VORP and RSG callback APIs use different signatures underneath. wc_libs normalizes server callback registration, server-to-client triggers, and client-to-server triggers into one namespaced shape.
You don't type the prefix yourself. Pass
"myCallback" and wc_libs registers/triggers it internally as "wc_libs:myCallback". Passing an already-prefixed name is safe too — it won't double-prefix.
RegisterCallback(name, handler)server
Registers a server-side callback.
| Param | Type | Description |
|---|---|---|
| name | string | Callback name (auto-prefixed). |
| handler | function(source, cb, ...) | Call cb(result) when done. |
example — job-gate check, ported from wc_encounter
wc:RegisterCallback('encounter:isJobAllowed', function(source, cb)
local job = wc:GetJob(source)
if not job then cb(true); return end
for _, blocked in ipairs(Config.BlacklistJobs or {}) do
if job.name == blocked then cb(false); return end
end
cb(true)
end)
TriggerCallback(name, source, cb, ...)server
Triggers a client-registered callback from the server (server → client → server round trip).
| Param | Type | Description |
|---|---|---|
| name | string | Callback name (auto-prefixed). |
| source | integer | Target player. |
| cb | function(result) | Called with the client's response. |
| ... | any | Extra args passed through to the client handler. |
underneath, on —
vorp_core
Core.Callback.TriggerAsync(name, source, cb, ...)
rsg-core
RSGCore.Functions.TriggerClientCallback(name, source, cb, ...)
TriggerCallback(name, ...)client
Triggers a server-registered callback from the client and waits for the result.
| Param | Type | Description |
|---|---|---|
| name | string | Callback name (auto-prefixed). |
| ... | any | Extra args passed through to the server handler. |
client example
local allowed = wc:TriggerCallback('encounter:isJobAllowed')
if not allowed then
return
end
Real Wild County example — trader stock check
wc_trader asks the server for live stock before opening its purchase menu, rather than trusting a stock count the client cached earlier.
server
wc:RegisterCallback('wc_trader:getStock', function(source, cb, traderId)
local stock = Traders[traderId] and Traders[traderId].stock or {}
cb({ stock = stock }) -- always wrap multiple values in ONE table
end)
client
local result = wc:TriggerCallback('wc_trader:getStock', traderId)
OpenTraderMenu(result.stock)
Common mistakes
- Calling
cb('a', 'b')with multiple arguments on the server — VORP's promise system only resolves a single value, so the second one is silently dropped. Always wrap multiple return values in one table:cb({ a = 'a', b = 'b' }). - Firing a callback in a tight loop every frame ("callback spam") — throttle client-triggered callbacks (e.g. with a cooldown or on menu-open only) instead of polling every tick.
- Forgetting the handler must call
cb(...)at every code path, including early returns — an un-resolved callback leaves the caller waiting. - Registering the same callback name twice across two resources — the prefix is shared (
wc_libs:), so pick specific, resource-qualified names like'wc_trader:getStock', not generic ones like'getStock'.
Troubleshooting
- If
TriggerCallbackhangs forever: the server handler never calledcb(...)on some code path — audit everyreturnin the handler. - If only the first field of your result table arrives: check you didn't accidentally call
cb(a, b)instead ofcb({ a = a, b = b })server-side. - If nothing happens at all: confirm the name matches on both sides — it's auto-prefixed the same way in both directions, but a typo in either
RegisterCallbackorTriggerCallbackwill silently mismatch.