Callbacks Guide#
Overview#
The Callback System provides a simple way to create request-response communication between client and server, as well as between different packages. It builds on top of the event system to provide a cleaner callback-based API.
Key Concepts#
- Callbacks are registered functions that can be called remotely and return values
- Cross-package support allows any package to call callbacks registered in other packages
- Isolated environments - each package has its own callback registry
API Reference#
Client-Side Functions#
TriggerCallback(name, callback, ...)#
Triggers a server-side callback and receives the response.
Parameters:
-
name(string) - Callback name, orpackage:CallbackNamefor cross-package calls -
callback(function) - Function to call with the response -
...- Arguments to pass to the server callback
-- Same package
TriggerCallback('GetPlayerData', function(data)
print('Player name: ' .. data.name)
end, playerId)
-- Cross-package
TriggerCallback('inventory:GetItems', function(items)
print('Got ' .. #items .. ' items')
end, playerId)
Server-Side Functions#
RegisterCallback(name, callback)#
Registers a callback that can be called by clients.
Parameters:
-
name(string) - Callback name (no colon allowed) -
callback(function) - Function to execute when called. First parameter is alwayssource(player). Returns value(s) to send back to client.
RegisterCallback('GetPlayerData', function(source, playerId)
local data = Database.GetPlayer(playerId)
return data
end)
RegisterCallback('RentApartment', function(source, apartmentId)
local success = RentApartment(source, apartmentId)
local message = success and 'Rented!' or 'Failed'
return success, message -- Multiple return values
end)
Usage Examples#
Server:
RegisterCallback('GetApartmentData', function(source, apartmentId)
local apartment = {
id = apartmentId,
name = "Luxury Apartment 101",
price = 50000,
owner = nil
}
return apartment
end)
Client:
TriggerCallback('GetApartmentData', function(apartment)
print('Apartment: ' .. apartment.name)
print('Price: $' .. apartment.price)
end, 101)
Cross-Package Communication#
Inventory Package
RegisterCallback('RefreshInventory', function(items)
UpdateInventoryUI(items)
return true
end)
Apartments Package
TriggerCallback(source, 'inventory:RefreshInventory', function(updated)
print('Inventory UI refreshed:', updated)
end, items)
Important Notes#
Callback Naming Rules#
- ⚠️ Do NOT use colons (
:) in callback names - they are reserved for package targeting - ✅ Good:
GetPlayerData,PurchaseItem,ShowNotification - ❌ Bad:
player:getData,item:purchase
Cross-Package Syntax#
- To call a callback in the same package:
TriggerCallback('CallbackName', ...) - To call a callback in another package:
TriggerCallback('package:CallbackName', ...)
Best Practices#
-
Always handle nil/error cases in callbacks:
TriggerCallback('GetData', function(data) if not data then print('Failed to get data') return end -- Process data end, id) -
Use descriptive callback names:
-- Good RegisterCallback('GetPlayerInventory', ...) RegisterCallback('PurchaseApartment', ...) -- Bad RegisterCallback('Get', ...) RegisterCallback('Do', ...) -
Keep callbacks focused and single-purpose:
-- Good - separate callbacks RegisterCallback('GetPlayerData', ...) RegisterCallback('UpdatePlayerData', ...) -- Bad - one callback doing too much RegisterCallback('PlayerDataHandler', ...) -
Return meaningful values:
-- Good return success, errorMessage, data -- Bad return true -- What does true mean?
Troubleshooting#
Callback not firing#
- Verify the callback is registered before being called
- Check that package names match exactly (case-sensitive)
- Ensure callback name doesn't contain colons unless targeting another package
No response received#
- Check server/client logs for errors
- Verify the callback is returning a value
- Make sure TriggerServerEvent/TriggerClientEvent are working
Cross-package calls failing#
- Verify target package has loaded and registered the callback
- Check package name spelling (e.g.,
inventory:GetItemsnotInventory:GetItems) - Ensure both packages have loaded the callback system
Technical Details#
- Each package maintains its own
RegisteredCallbackstable in its isolated Lua environment - Request IDs are unique per package instance to track callback responses
- Events use the format:
{packageName}:server:TriggerCallbackand{packageName}:client:CallbackResponse - The system broadcasts events to all packages, but only the target package processes them