Skip to content
ripexvPublic

About

One framework layer for FiveM and RedM. ESX, QBCore, Qbox, VORP, RSG or standalone.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

rx_core

One framework layer for FiveM and RedM scripts. Free, open source, zero dependencies.

Write your script once. It runs on ESX, QBCore, Qbox, VORP, RSG, or no framework at all, and you never write another framework.lua.

-- Same five lines on every server, every framework, both games.
RX.OnReady(function()
    local player = RX.Player.get(source)
    print(player.charId, player.job.name)

    if RX.Money.remove(source, 'cash', 250, 'bought a horse') then
        RX.Notify(source, 'Enjoy the horse.', 'success')
    end
end)

Install

  1. Download the latest release and drop rx_core in your resources folder.
  2. Add ensure rx_core to server.cfg before any script that uses it.
  3. Done. No configuration required.

Use it in your script

Two lines in fxmanifest.lua:

dependency 'rx_core'
shared_script '@rx_core/init.lua'

That gives you a global RX table in both client and server files.


Supported frameworks

Framework Game Detected by Cash Bank Other currencies
ESX Legacy FiveM es_extended ✅ ✅ black
QBCore FiveM qb-core ✅ ✅ crypto
Qbox FiveM qbx_core ✅ ✅ crypto
VORP RedM vorp_core ✅ ❌ gold, rol
RSG RedM rsg-core ✅ ✅ bloodmoney + regional banks
Standalone both (nothing found) ❌ ❌ —

Two details worth knowing before you write against them:

  • VORP has no native bank. Banking lives in separate resources, so RX.Framework.supports('bank') is false rather than quietly aliased to cash.
  • Gold is VORP only. RSG has no gold; it has bloodmoney and per-region banks which each server configures itself, so rx_core reads them from the running RSG config instead of hardcoding a guess.

Never assume a currency exists. Ask:

if RX.Framework.supports('gold') then
    RX.Money.add(source, 'gold', 5)
end

print(table.concat(RX.Money.types(), ', ')) -- what this server actually has

API

Lifecycle

RX.OnReady(fn)              -- run fn once the framework is resolved
RX.Require('>=1.1.0')       -- assert an rx_core version, error loudly if unmet

Resources start in parallel. Always put startup logic inside RX.OnReady, or you will ask which framework this is before anyone knows.

Framework

RX.Framework.name           -- 'esx'|'qbcore'|'qbx'|'vorp'|'rsg'|'standalone_fivem'|'standalone_redm'
RX.Framework.platform       -- 'fivem'|'redm'
RX.Framework.version        -- rx_core version
RX.Framework.ready          -- boolean
RX.Framework.supports(f)    -- 'money'|'bank'|'gold'|'inventory'|'jobs'|any currency

Player (server)

local player = RX.Player.get(source)
-- {
--   source, identifier, charId, name,
--   job = { name, label, grade, gradeLabel },
--   group
-- }

identifier is the player. charId is the character — on RedM one player owns several, so that is the key most things should hang off.

Money (server)

RX.Money.get(source, 'cash')                        --> number | false
RX.Money.add(source, 'bank', 500, 'reason')         --> boolean
RX.Money.remove(source, 'cash', 250, 'reason')      --> boolean, false if broke
RX.Money.types()                                    --> { 'cash', 'bank', ... }

Asking for a currency this framework does not have returns false and prints a warning naming what is available. It never silently succeeds.

Notifications

RX.Notify(source, 'Saved.', 'success', 4000)  -- server
RX.Notify('Saved.', 'success', 4000)          -- client

Types: info, success, error, warning — translated to each framework's native call. To route everything through your own notification resource, set RXConfig.NotifyOverride in config.lua.

Debug

RX.Debug('anything', 'here')

Silent unless RXConfig.Debug = true, and tagged with your resource name so a server running ten RX scripts can tell which one is talking.

Inventory

RX.Item.has / count / add / remove exist but are not implemented in 1.0.0. Every framework fronts a different inventory resource and only some are documented well enough to implement without guessing — and a guess that silently loses a player's item is worse than no function at all. They return false and say so. Landing in 1.1.


Why the init.lua bridge

FiveM serialises everything that crosses an export boundary, and functions do not survive that trip. If rx_core handed back a player object with methods on it, every method would arrive as nil — which is exactly how VORP works internally, since a VORP character is a table of methods.

So rx_core's exports only move plain data, and @rx_core/init.lua runs inside your resource's Lua state to put a normal-looking API back on top. Same approach ox_lib uses.

Escrow

rx_core is open source and not escrowed. Your scripts can be. An escrowed resource calling exports on a non-escrowed one is the same mechanism as any escrowed script calling oxmysql.

Two things to remember when you escrow a resource that uses rx_core:

escrow_ignore { 'config.lua', 'locales/*.lua' }   -- or buyers cannot edit them

and note that NUI files (html/css/js) are not covered by escrow — only Lua, YFT, YDD and YDR are. Keep business logic out of your UI.


Config

config.lua, all optional:

Key Default Purpose
Debug false Verbose output from rx_core and RX.Debug
Banner true Print the RX banner on server start
VersionCheck true Check for newer releases
ForceFramework false Skip auto-detection, e.g. 'vorp'
NotifyOverride false Function routing all notifications to your own resource

Console

rx      # framework, platform, money types, registered RX scripts

Testing

lua tests/run.lua

Runs the real source against a stubbed FiveM runtime. See tests/README.md.

A complete script

Everything above, in one file:

-- fxmanifest.lua
dependency 'rx_core'
shared_script '@rx_core/init.lua'
server_script 'server.lua'
-- server.lua
RX.OnReady(function()
    print(('running on %s (%s)'):format(RX.Framework.name, RX.Framework.platform))
end)

RegisterCommand('buyhorse', function(source)
    local player = RX.Player.get(source)
    if not player then return end

    if RX.Money.remove(source, 'cash', 250, 'bought a horse') then
        RX.Notify(source, ('Sold to %s.'):format(player.name), 'success')
    else
        RX.Notify(source, 'Not enough cash.', 'error')
    end
end, false)

That runs unchanged on every framework in the table above.


MIT licensed · built by Ripexv · github.com/ripexv/rx_core

About

One framework layer for FiveM and RedM. ESX, QBCore, Qbox, VORP, RSG or standalone.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages