Callback Module Documentation โ
The Callback module provides a robust RPC (Remote Procedure Call) system for client-server communication in RedM scripts.
Getting Started โ
lua
-- Client-side
local Callback = exports.bln_lib:callback()
-- Server-side
local Callback = exports.bln_lib:callback()Server-Side Usage โ
Register a Callback โ
lua
Callback.Register(name, callback)Parameters
name(string): Unique identifier for the callbackcallback(function): Function to handle the request- Parameters: 
source(number): Player sourcecb(function): Callback function to send response...(any): Additional parameters from client
 
- Parameters: 
 
Example
lua
-- Register simple callback
Callback.Register('getPlayerMoney', function(source, cb)
    local money = 1000
    cb(money)
end)
-- Register callback with parameters
Callback.Register('checkPlayerCanBuy', function(source, cb, itemPrice)
    local playerMoney = 1000
    cb(playerMoney >= itemPrice)
end)Trigger Client Callback โ
lua
-- Async version
Callback.TriggerAsync(name, source, callback, ...)
-- Sync version (uses promises)
local result = Callback.TriggerAwait(name, source, ...)Parameters
name(string): Callback identifiersource(number): Target playercallback(function): Response handler (async only)...(any): Additional parameters
Example
lua
-- Async
Callback.TriggerAsync('getPlayerPosition', player, function(position)
    print(json.encode(position))
end)
-- Sync
local position = Callback.TriggerAwait('getPlayerPosition', player)
print(json.encode(position))Client-Side Usage โ
Register a Callback โ
lua
Callback.Register(name, callback)Parameters
name(string): Unique identifier for the callbackcallback(function): Function to handle the request- Parameters: 
cb(function): Callback function to send response...(any): Additional parameters from server
 
- Parameters: 
 
Example
lua
-- Register position callback
Callback.Register('getPlayerPosition', function(cb)
    local coords = GetEntityCoords(PlayerPedId())
    cb(coords)
end)
-- Register callback with parameters
Callback.Register('isPlayerNearCoords', function(cb, coords, distance)
    local playerCoords = GetEntityCoords(PlayerPedId())
    local isNear = #(playerCoords - coords) < distance
    cb(isNear)
end)Trigger Server Callback โ
lua
-- Async version
Callback.TriggerAsync(name, callback, ...)
-- Sync version (uses promises)
local result = Callback.TriggerAwait(name, ...)Parameters
name(string): Callback identifiercallback(function): Response handler (async only)...(any): Additional parameters
Example
lua
-- Async usage
Callback.TriggerAsync('getPlayerMoney', function(money)
    print('Player has $' .. money)
end)
-- Sync usage
local money = Callback.TriggerAwait('getPlayerMoney')
print('Player has $' .. money)Complete Examples โ
Inventory Check System โ
lua
-- Server-side registration
Callback.Register('canPlayerCarryItem', function(source, cb, item, amount)
    local player = GetPlayer(source)
    local canCarry = player.inventory.canCarry(item, amount)
    cb(canCarry)
end)
-- Client-side usage
-- Async
Callback.TriggerAsync('canPlayerCarryItem', function(canCarry)
    if canCarry then
        print('Can carry item')
    else
        print('Cannot carry item')
    end
end, 'apple', 5)
-- Sync
local canCarry = Callback.TriggerAwait('canPlayerCarryItem', 'apple', 5)
if canCarry then
    print('Can carry item')
endPlayer Position System โ
lua
-- Client-side registration
Callback.Register('getDetailedPosition', function(cb)
    local ped = PlayerPedId()
    local coords = GetEntityCoords(ped)
    local heading = GetEntityHeading(ped)
    cb({
        pos = coords,
        heading = heading,
        ground = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z)
    })
end)
-- Server-side usage
-- Async
Callback.TriggerAsync('getDetailedPosition', playerId, function(data)
    print(json.encode(data))
end)
-- Sync
local position = Callback.TriggerAwait('getDetailedPosition', playerId)
print(json.encode(position))Best Practices โ
- Use Meaningful Names
 
lua
-- Good
Callback.Register('getPlayerInventory', ...)
-- Avoid
Callback.Register('gpi', ...)- Handle Errors
 
lua
Callback.Register('sensitiveOperation', function(source, cb)
    if not IsPlayerAceAllowed(source, 'admin') then
        cb(false, 'Not authorized')
        return
    end
    -- Proceed with operation
    cb(true, 'Operation successful')
end)- Choose Async vs Sync Wisely
 
lua
-- Use async for non-blocking operations
Callback.TriggerAsync('longOperation', function(result)
    -- Handle result
end)
-- Use sync for operations that need immediate results
local result = Callback.TriggerAwait('quickCheck')
if result then
    -- Proceed immediately
endPerformance Considerations โ
- Avoid excessive callbacks for frequent operations
 - Use sync callbacks sparingly as they block execution
 - Consider batching multiple requests when possible
 - Clean up registered callbacks when no longer needed