Getting Started
Prerequisites
- FiveM server with
ox_libandoxmysqlin your resource manifest rp-basestarted before any resource that imports it
Installation
Copy rp-base into your resources folder and add it to your server.cfg:
ensure ox_lib
ensure oxmysql
ensure rp-baseRun database.sql against your database to create the required tables.
Importing in another resource
Add the import file to your fxmanifest.lua:
fxmanifest.lua
shared_scripts {
'@rp-base/import.lua',
-- your other scripts
}The import script:
- Waits for
rp-baseto start (handles cold starts and restarts alike) - Attaches the shared
RPobject to the global - Sets up side-specific helpers (
RP.PlayerDataon the client,RP.GetPlayerFromSourceetc. on the server) - Re-registers server callbacks automatically after a
rp-baserestart
import.lua works for both server-side and client-side scripts in the same
resource — IsDuplicityVersion() is checked internally.
Basic usage
-- server/main.lua
RP.RegisterServerCallback('myResource:getData', function(src, cb)
local p = RP.GetPlayerFromSource(src)
if not p then return cb(nil) end
cb({ pid = p.pid, xp = p.xp, rank = p:getRank() })
end)
AddEventHandler('rp-base:playerLoaded', function(p)
-- p is the raw _PlayerData table forwarded from the server
print('Player loaded:', p.pid)
end)Metatables and exports
⚠️
Metatables do not survive FiveM's event or export boundaries. This means:
- You cannot pass an
RCPlayerobject through aTriggerEventorexportscall and expect dynamic props likep.pedto work on the receiving end. - Always pass plain data (pid, source, tables) and re-fetch the player object inside
the handler using
RP.GetPlayerFromSource(src).
The import's server-side RP.GetPlayerFromSource returns a lightweight proxy (not
the real RCPlayer) that forwards property reads/writes through exports. This is safe to
pass as a local variable within a single resource.