Advanced Guide: Integrating rps_lib Into Your Script¶
This guide goes beyond simply calling the export. It covers the internal architecture of RPS_LIB, load order considerations, automatic resource cleanup, permissions, framework events, error handling, and advanced integration patterns.
If you only need the basics:
local RPS_Lib = exports['rps_lib']:GetLibObject()
Everything below explains what this object contains and how to use it correctly in production resources.
Internal Architecture¶
During startup, RPS_LIB creates a shared _Lib table on both the client and server. Every integration module attaches its functions directly to this table.
Example:
local _Lib = _G.RPS_Lib
function _Lib.GetStress()
-- ...
end
By the time initialization finishes, the library contains:
- Framework detection
- Inventory bridges
- Target bridges
- Fuel systems
- Vehicle keys
- Garages
- Banking
- Notifications
- Progress bars
- Stress systems
- All helper functions
The export simply returns the same table:
exports('GetLibObject', function()
return _Lib
end)
Because the returned object is a reference to the live table, future updates to the library become immediately available without needing to reacquire the object.
Load Order¶
Correct Setup¶
Inside your fxmanifest.lua:
fx_version 'cerulean'
game 'gta5'
dependency 'rps_lib'
client_script 'client.lua'
server_script 'server.lua'
Declaring a dependency guarantees that rps_lib reaches the started state before your resource starts.
Safe Usage¶
local RPS_Lib = exports['rps_lib']:GetLibObject()
print(RPS_Lib.Framework)
No additional waiting is required when using dependencies correctly.
Inventory Item Cache¶
The inventory item cache is populated asynchronously.
Avoid:
local items = RPS_Lib.Items
during resource startup.
Instead use:
local items = RPS_Lib.GetItems()
which fetches fresh data directly from the active inventory.
Defensive Startup Pattern¶
For optional compatibility:
local RPS_Lib
CreateThread(function()
while GetResourceState('rps_lib') ~= 'started' do
Wait(100)
end
RPS_Lib = exports['rps_lib']:GetLibObject()
end)
Framework Events¶
Branch dynamically based on the detected framework:
local RPS_Lib = exports['rps_lib']:GetLibObject()
if RPS_Lib.Framework == 'esx' then
AddEventHandler('esx:playerLoaded', function()
-- setup
end)
elseif RPS_Lib.Framework == 'qb' then
AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
-- setup
end)
elseif RPS_Lib.Framework == 'qbx' then
AddEventHandler('qbx_core:client:playerLoaded', function()
-- setup
end)
end
This removes the need for polling loops.
Automatic Target Cleanup¶
Every zone created through rps_lib is automatically removed when your resource stops.
Example:
RPS_Lib.AddBoxZone(
'my_shop',
vector3(100.0, 200.0, 30.0),
2.0,
2.0,
{},
{
options = {
{
label = 'Open Shop',
icon = 'fas fa-shopping-cart',
action = function()
TriggerEvent('my_script:openShop')
end
}
}
}
)
No manual cleanup is required.
Removing Zones Manually¶
local zoneId = RPS_Lib.AddBoxZone(...)
RPS_Lib.RemoveZone(zoneId)
Permission System¶
RPS_LIB supports:
- ACE permissions
- License checks
- Identifier whitelists
- Framework groups and jobs
Example:
local allowed = RPS_Lib.HasPermission(source, {
WithAce = true,
WithGroup = {
admin = true,
god = true
}
})
This allows one permission system to work across multiple frameworks.
Error Handling¶
Always check return values:
local success = RPS_Lib.AddSocietyMoney('police', 500)
if success == false then
print('Banking system not configured.')
end
RPS_LIB intentionally returns safe values instead of crashing resources.
Example: Vehicle Impound System¶
Client:
local RPS_Lib = exports['rps_lib']:GetLibObject()
CreateThread(function()
RPS_Lib.AddGlobalVehicle({
options = {
{
label = 'Impound Vehicle',
icon = 'fas fa-warehouse',
action = function(entity)
local plate = GetVehicleNumberPlateText(entity)
local netId = NetworkGetNetworkIdFromEntity(entity)
TriggerServerEvent(
'your_script:impoundVehicle',
plate,
netId
)
end
}
}
})
end)
Server:
local RPS_Lib = exports['rps_lib']:GetLibObject()
RegisterNetEvent('your_script:impoundVehicle', function(plate, netId)
local source = source
RPS_Lib.RemoveVehicleKey(source, plate, netId)
RPS_Lib.AddSocietyMoney('police', 250)
RPS_Lib.GainStress(source, 5)
end)
Notice there is no branching for:
- Inventory
- Vehicle Keys
- Banking
- Stress
- Target Systems
RPS_LIB handles all compatibility internally.
Module Reference¶
| Module | Client | Server |
|---|---|---|
| Inventory | integration/client/inventory.lua | integration/server/inventory.lua |
| Target | integration/client/target.lua | — |
| Fuel | integration/client/fuel.lua | — |
| Vehicle Keys | integration/client/keys.lua | integration/server/inventory.lua |
| Garage | integration/client/garage.lua | integration/server/garage.lua |
| Stress | integration/client/stress.lua | integration/server/stress.lua |
| Notify | integration/client/notify.lua | — |
| Progress Bar | integration/client/progress.lua | — |
| Status | integration/client/status.lua | — |
| Banking & Permissions | — | framework/server/init.lua |
| Framework Detection | framework/client/init.lua | framework/server/init.lua |
Best Practices¶
✔ Call GetLibObject() once.¶
local RPS_Lib = exports['rps_lib']:GetLibObject()
✔ Use bridge functions.¶
Good:
RPS_Lib.AddItem(source, 'water', 1)
Bad:
if RPS_Lib.Inventory == 'ox_inventory' then
exports.ox_inventory:AddItem(...)
end
✔ Use GetItems()¶
Avoid reading:
RPS_Lib.Items
during startup.
✔ Let RPS_LIB manage target cleanup.¶
Avoid creating duplicate onResourceStop handlers.
Build Once. Support Everything.¶
RPS_LIB removes framework-specific code and provides a unified API for building portable, future-proof FiveM resources.