Skip to main content

BenzyBridge

BenzyBridge

A standalone-first compatibility layer and include library for FiveM. It detects the framework (ESX / QBCore / QBox / standalone), inventory, money, notifications, on-screen prompts, targeting, and storage that your server is running, and gives every script one unified API for all of them — either in-process as Benzy.* (added to your resource with a single @include), or from outside as exports.BenzyBridge:*. Write a script against the bridge once and it runs the same on a bare standalone server or a full framework stack: every concern degrades gracefully, so nothing is a hard dependency.

Made by Samuel Benzy of Benzy Development.


Features

  • One unified API — player identity, job/gang, money, inventory, access control, notifications, on-screen prompts, targeting, and storage, all through a single surface.
  • In-process include — a consumer adds one shared_script and calls Benzy.* directly: a normal Lua call in its own state, with no cross-resource export hop.
  • Auto-detection — every concern defaults to auto and binds to the first supported provider that is running; force a specific one whenever you like.
  • Multi-framework — normalizes ESX, QBCore, QBox, and standalone into the same player/job/money shape, so your script never branches on the framework.
  • Standalone-first — no framework and no hard dependencies. Every concern has a safe, working answer when nothing is installed.
  • Provider-agnostic — a script written against the bridge keeps working when you swap the underlying notify / money / prompt / targeting system.
  • Extensible — point notifications or prompts at any resource with a custom hook, or register a money adapter at runtime, then select it by name.
  • One storage connection — auto-detects oxmysql or mysql-async and hands out a single query API, or falls back to file mode; each resource keeps its own tables.
  • Headless — no NUI of its own; it routes to the resources that draw, with a built-in native/chat fallback so a prompt or toast is never silently lost.

How it works

The include model

A consumer adds, as its first shared script:

shared_script '@BenzyBridge/init.lua'

and (optionally) declares dependency 'BenzyBridge'. init.lua runs inside the consumer's own Lua state, reads the resolved stack via exports.BenzyBridge:GetSettings(), loads the active framework / inventory / targeting adapters in-process, and builds one global table, Benzy. The consumer then calls Benzy.* directly — a plain Lua call with no export hop. Nothing is a bare global except Benzy itself, so it never collides with your own helpers.

-- Server: normalized across ESX / QBCore / QBox / standalone
local player = Benzy.GetPlayer(src)
Benzy.AddMoney(src, 'cash', 500, 'Reward')
if Benzy.HasItem(src, 'water', 1) then Benzy.RemoveItem(src, 'water', 1) end
Benzy.Notify(src, 'success', 'Shop', 'Purchase complete', 4000)

Auto-detection

On first call (cached, and re-resolved whenever a resource starts or stops) the bridge resolves each concern from your config.lua plus what is actually running:

Concernauto resolves to
Frameworkes_extendedesx, qbx_coreqbox, qb-coreqbcore, else standalone
Inventoryox_inventoryqb-inventoryqs-inventory, else none
Moneya framework's own money if a framework is active, else BenzyMoney, else none
NotifyBenzyNotifications, else the built-in native feed
Draw-textBenzyDrawText, else the built-in native prompt
Targetingox_targetqb-target, else none
Storageoxmysqlmysql-async, else file

Standalone-first degradation

Every concern has a safe answer when its provider is absent — running without one is a normal, supported setup, never an error:

  • No framework → a standalone player identity (Rockstar license + name) and a default job; identity and access still work.
  • No inventory → item operations are silent no-ops. Benzy.HasInventory() returns false and your script keeps its own database tracking (e.g. a counter). This never warns.
  • No money provider (or Config.Money = 'none') → every money call returns false, 'UNSUPPORTED', so a script that supports running without money degrades cleanly. On a framework money provider only the core cash/bank subset works; the rest return false, 'UNSUPPORTED'. On BenzyMoney the whole surface works.
  • No targetingBenzy.ResolveInteraction('target') downgrades a script to draw-text prompts and prints a one-time console warning, so targeting is never forced on a server that has none.
  • No notify / prompt provider → a built-in native (game feed / help-text) or chat fallback renders instead, so a toast or prompt is never lost.

Requirements

  • A FiveM server (fx_version 'cerulean').
  • (Optional) A framework — ESX, QBCore, or QBox. None required; standalone is fully supported.
  • (Optional) A SQL connectoroxmysql or mysql-async — only if a resource asks the bridge to use a database. Without one, storage runs in file mode.
  • (Optional) Providers — an inventory, money, notification, draw-text, or targeting resource for the bridge to route to. Each is detected at runtime; anything missing falls back.

Installation

  1. Place the BenzyBridge folder in your server's resources directory.

  2. Add it to server.cfg in the right order: your SQL connector and framework first, then BenzyBridge, then the providers it routes to, then the consumer resources that use it.

    ensure oxmysql # SQL connector (only if you use a database)
    ensure es_extended # your framework (skip on a standalone server)
    ensure BenzyBridge # the bridge — after the framework/connector, before providers
    ensure BenzyMoney # providers the bridge should route to
    ensure BenzyNotifications
    ensure ox_target
    # ... your resources that call Benzy.* / exports.BenzyBridge:* ...
  3. Open config.lua and set the services + storage (all default to auto).

  4. Restart the server. On boot the bridge prints the resolved stack to the server console.

Load order matters. auto binds to a provider only if that provider is started before the caller. If a call resolves to a fallback you didn't expect, check the order in server.cfg.


Configuration

Everything is in config.lua, and every option lists its accepted values inline on the same line.

OptionValuesWhat it does
Config.Debugtrue | falsePrints resolution + routing diagnostics to the server console and each client's F8. Leave off on a live server.
Config.Frameworkauto | esx | qbcore | qbox | standaloneThe core to integrate with for player/job/money.
Config.Notifyauto | BenzyNotifications | chat | native | custom | noneWhich system shows notifications.
Config.DrawTextauto | BenzyDrawText | native | custom | noneWhich system shows on-screen prompts.
Config.Targetauto | ox_target | qb-target | noneWhich targeting system backs Benzy.Target.* (separate from prompts).
Config.Moneyauto | esx | qbcore | qbox | BenzyMoney | custom | noneWhich system handles balances / payments. none turns money off on purpose (every money call returns UNSUPPORTED).
Config.Inventoryauto | ox_inventory | qb-inventory | qs-inventory | noneWhich inventory backs item operations. none makes item ops silent no-ops.
Config.Storageauto | oxmysql | mysql-async | fileHow resources persist data.
Config.Custom{ Notify = {…}, DrawText = {…} }Hooks used when the matching option above is custom — a { Resource, Export, Event } set, resolved in order Fn → Export → Event. A custom money system is registered as an adapter instead (see the Integrations documentation).
Config.LocaleenLanguage for the bridge's console / diagnostic text. Add locales/<code>.lua (it loads automatically), then set the code here.
  • auto uses the first supported provider that is running, else a safe fallback (native for notify / draw-text, none for targeting and money, file for storage). To route through Config.Custom, set the option to custom explicitly.
  • custom routes notifications / prompts through Config.Custom.

Interaction: draw-text vs targeting

The bridge treats on-screen prompts and targeting as two separate concerns, controlled independently:

  • Config.DrawText — the "press E" style help-text / prompt system (Benzy.Show / Benzy.Hide).
  • Config.Target — the eye/target system (Benzy.Target.*).

Each consumer picks per-script which style it wants. A script that prefers targeting calls Benzy.ResolveInteraction('target'): if a targeting system is running it returns 'target', otherwise it warns once and returns 'drawtext' so the script falls back to prompts. This way a server without a targeting system still works, and a script never forces one on you.


Commands

  • debugbridge — prints the full resolved stack: framework, language, and what backs each concern (money, inventory, notify, draw-text, target, storage), plus a live database probe server-side. Run it in the server console, or in a player's F8 console. In F8 it works only when Config.Debug = true — otherwise it just tells you to enable it — so ordinary players can't probe your setup.

On boot the bridge also prints the resolved stack to the server console.


What works with and without a framework / inventory / money

Everything in the Standalone column works on a bare server with nothing installed. Adding a framework, inventory, or money provider upgrades those rows — no change to the scripts that call the bridge.

CapabilityStandalone (nothing installed)+ Framework (ESX / QBCore / QBox)+ Inventory+ Money provider
Player identity (GetPlayer, GetLicense, GetName, IsLoaded)✅ license + name✅ full normalized record (job, gang, money)
Job / gang (GetJob, GetGang, HasJob, OnDuty)✅ default job✅ real job/gang + duty
Access control (HasAccess)✅ via ACE / identifiers / Discordalso framework job/group
Notifications & prompts (Notify, Show)native / chat fallback
Targeting (Benzy.Target.*)⚠️ downgrades to draw-text (needs ox_target / qb-target)
Item operations (HasItem, AddItem, RemoveItem, CanCarry)⚪ silent no-op (HasInventory() = false)✅ real item ops
Money reads / mutators (GetCash, AddMoney, …)false, 'UNSUPPORTED'✅ core cash/bank subset✅ full surface on BenzyMoney
Storage (Query, Insert, …)✅ file mode— (a SQL connector switches storage to database mode)

✅ works · ⚠️ works with a documented fallback · ⚪ safe, intentional no-op


Integrating

  • the Integrations documentation — adding the bridge to a resource, what it auto-detects, storage, and registering a custom notification / prompt / money system.

Notes

  • Integrating from outside the suite — a third-party resource calls the script it actually wants (exports.BenzyMoney:*, exports.BenzyFuel:*, …) and listens to that script's events. The bridge is what lets those scripts run on whatever framework / inventory / money system you have; it isn't an API layer for outside code.
  • Each provider script keeps all of its own logic and works standalone; the bridge only routes to it.
  • Server-authoritative — money, inventory, and access checks are validated server-side; a client never sets a balance or grants itself an item.
  • The whole bridge folder ships escrow-open on purpose — the include model reads its own files, which cannot be encrypted. Your individual scripts stay encrypted on their own.

Troubleshooting

  • Turn on debug first — set Config.Debug = true, restart, and read the boot summary + the debugbridge output.
  • A call does nothing / resolves to a fallback — check what each concern resolved to. auto needs the provider started before the caller; fix the order in server.cfg.
  • Money returns UNSUPPORTED — no money provider resolved, or Config.Money = 'none' (which forces this on purpose). Start a provider (e.g. BenzyMoney), register a custom adapter, or set Config.Money to one that is running. On a framework money provider, non-core operations return this by design.
  • Item ops do nothing and there's no warning — that's the intended no-inventory behavior. Branch on Benzy.HasInventory() and use your own database tracking when it's false.
  • Targeting isn't working — no targeting system is running, so Benzy.ResolveInteraction fell back to draw-text (it warns once). Start ox_target / qb-target, or set the script to draw-text to silence it.
  • Queries return nil — storage is in file mode (no connector), or a forced connector isn't started. Check debugbridge.

Support

Need help? Visit support.benzy.lol.


Credits

Made by Samuel Benzy of Benzy Development.

Website: https://benzy.lol