tw.callback
Side: Client + Server
Bidirectional client-server callback system. Register a callback on one side, trigger it from the other, with support for both synchronous and asynchronous calls.
Client Functions
tw.callback.register(name, handler)
Registers a client-side callback that can be triggered from the server.
| Parameter | Type | Description |
|---|---|---|
name | string | Unique callback name |
handler | function | Handler function. Return value is sent back to the caller |
Alias: tw.callback.registerCallback(name, handler)
tw.callback.triggerServer(name, cb, ...)
Triggers a server-side callback from the client.
| Parameter | Type | Description |
|---|---|---|
name | string | Name of the server callback to trigger |
cb | function or nil | Callback for async mode, or nil for synchronous (blocking via Citizen.Await) |
... | any | Arguments passed to the server handler |
Returns: When cb is nil, returns the server handler's return value(s) synchronously.
tw.callback.triggerClient(name, cb, ...)
Triggers a local client-side callback (client-to-client).
| Parameter | Type | Description |
|---|---|---|
name | string | Name of the client callback to trigger |
cb | function or nil | Callback for async mode, or nil for synchronous |
... | any | Arguments passed to the handler |
Server Functions
tw.callback.register(name, handler)
Registers a server-side callback. The source of the calling player is always injected as the first argument.
| Parameter | Type | Description |
|---|---|---|
name | string | Unique callback name |
handler | function(source, ...) | Handler function. source is the player server ID |
tw.callback.register.latent(name, handler)
Registers a server-side callback with bandwidth-limited responses (latent events). Useful for sending large payloads back to the client without saturating the network.
| Parameter | Type | Description |
|---|---|---|
name | string | Unique callback name |
handler | function(source, ...) | Handler function with bandwidth-limited response delivery |
tw.callback.triggerServer(name, cb, ...)
Triggers a local server-side callback (server-to-server).
| Parameter | Type | Description |
|---|---|---|
name | string | Name of the server callback to trigger |
cb | function or nil | Callback for async mode, or nil for synchronous |
... | any | Arguments passed to the handler |
tw.callback.triggerClient(name, target, cb, ...)
Triggers a client-side callback from the server.
| Parameter | Type | Description |
|---|---|---|
name | string | Name of the client callback to trigger |
target | integer | Player server ID |
cb | function or nil | Callback for async mode, or nil for synchronous |
... | any | Arguments passed to the client handler |
Examples
Register on server, call from client (async)
-- server.lua
tw.callback.register("getPlayerBalance", function(source)
local user = tw.fw:getUser(source)
return user:getMoney(0)
end)
-- client.lua
tw.callback.triggerServer("getPlayerBalance", function(balance)
print("My balance: $" .. balance)
end)Synchronous call from client
-- client.lua
local balance = tw.callback.triggerServer("getPlayerBalance", nil)
print("My balance: $" .. balance)Register on client, call from server
-- client.lua
tw.callback.register("getPlayerCoords", function()
return GetEntityCoords(PlayerPedId())
end)
-- server.lua
tw.callback.triggerClient("getPlayerCoords", source, function(coords)
print("Player is at: " .. coords)
end)Latent callback for large data
-- server.lua
tw.callback.register.latent("getAllShopItems", function(source)
return Config.ShopItems -- large table sent with bandwidth control
end)
-- client.lua
local items = tw.callback.triggerServer("getAllShopItems", nil)Notes
- Synchronous calls (
cb = nil) useCitizen.Awaitand block the current thread until the response arrives. - The
sourceparameter is automatically injected on server-side handlers; do not pass it manually from the client. - Use
register.latentwhen the response payload is large to avoid network congestion.

