Standalone Mode
RoadPhone Pro can run without any framework. If neitheres_extended, qb-core nor qbx_core is started, the Bridge automatically falls back to standalone mode — no configuration flag needed.
How Detection Works
On resource start,bridge/main.lua probes the framework resources in this order:
qbx_corestarted →Bridge.Framework = 'qbox'es_extendedstarted →Bridge.Framework = 'esx'qb-corestarted →Bridge.Framework = 'qbcore'- Nothing found →
Bridge.Framework = 'standalone'
starting state, detection retries for up to 10 seconds before locking into standalone. There is no config option to force standalone — simply don’t run a framework.
The shipped
fxmanifest.lua has no hard framework dependency. Its only declared dependencies are OneSync and xsound; it additionally loads @ox_lib/init.lua and @mysql-async/lib/MySQL.lua. You still need ox_lib, mysql-async and a MySQL database on a standalone server — the phone’s own roadshop_* tables are auto-created on boot.What Works, What Doesn’t
| Area | Standalone Behavior |
|---|---|
Callbacks (Bridge.RegisterCallback / TriggerCallback) | ✅ Fully working custom net-event implementation (10s timeout) |
Player identity (GetIdentifier, GetName, GetPlayers) | ✅ Works via FiveM natives — identifier is the player’s first identifier (usually license:...) |
Notifications (Bridge.Notification.*, Bridge.UI.Notify) | ✅ Works (native GTA feed) |
Locales (Bridge.Locale.Translate, _U) | ✅ Works (driven by Config.Locale) |
| Phone number assignment | ⚠️ Works only if a users table exists (see Database Setup) |
Money (Bridge.Player.*Money, Bridge.Account.*) | ❌ Stubs — GetMoney/GetBalance return 0, Add/Remove/Set return false |
| Banking app | ❌ Balance always $0, transfers and payments fail (depends on the money stubs) |
| Inventory (no inventory resource running) | ❌ Stubs — AddItem/RemoveItem/HasItem do nothing, RegisterUseableItem unsupported |
Jobs (Bridge.Job.*) | ❌ Every player is always unemployed and always on duty; setters are no-ops |
Framework events (Bridge.Events.On('PlayerLoaded') etc.) | ⚠️ Mapped to plain custom events (playerLoaded, jobUpdate, …) that nothing fires automatically |
| UI extras (context menu, input dialog, progressbar) | ⚠️ Context menu & input do nothing / return nil; progressbar is an invisible wait |
Required Setup
Create a users table
Standalone mode reuses the ESX-style defaults: identity queries run against a table called You must also insert a row per player (e.g. on
users with an identifier column. Nothing auto-creates this table — without it, phone number assignment and IBAN generation will throw SQL errors.Minimal schema:playerJoining, keyed by their first identifier). RoadPhone auto-adds the phone_number and phone_bank_iban columns on boot if the table exists — if it doesn’t, you’ll see this in the console and the columns are skipped:A few name-lookup queries (news, billing, service) take the non-ESX code path in standalone and read QB-style
JSON_VALUE(charinfo, '$.firstname') / JSON_VALUE(job, '$.name') columns. If you use those features, add charinfo and job JSON columns to your users table — otherwise you can ignore this.Point the Bridge at your tables
If your identity table is not called Every framework-agnostic SQL query in RoadPhone builds on these four variables — this is the single place to adapt them.
users (or uses a different identifier column), change the standalone defaults in bridge/main.lua (SetStandalone()):bridge/main.lua
Decide how the phone opens
In pure standalone (no inventory resource), Every player can open the phone with the keybind (
Bridge.Inventory.RegisterUseableItem is unsupported — a phone item can never open the phone. Pick one:- No item (simplest)
- Run an inventory resource
config.lua
Config.OpenKey, default F1). No inventory needed at all.Implement the money stubs (Banking app)
All money functions are intentional no-ops in standalone — the Bank app will show Fill in the
$0 and every transfer fails until you wire them to your own economy. The stubs print to the console when hit:standalone branches in two files:bridge/modules/player/server.lua
bridge/modules/account/server.lua
HasMoney, TransferMoney and GetAccounts derive from these, so implementing GetBalance, AddMoney and RemoveMoney covers the Banking app.Optional: jobs and framework events
Jobs: The phone itself still boots fine without them — its player-load flow is driven by the phone client, not by framework events.
Bridge.Job.GetJob() always returns unemployed in standalone. Every job-gated phone feature therefore never matches: dispatch numbers (Config.Leitstelle), news posting (Config.NewsAppAccess), the service app, taxi job checks and the Career Hub. If you have your own job system, implement the standalone branches in bridge/modules/job/server.lua and job/client.lua (GetJob, HasJob, GetGrade).Events: In standalone, Bridge.Events.Get('PlayerLoaded') maps to a plain custom event named playerLoaded (likewise playerUnload, jobUpdate, moneyChange, …). No framework fires these — if your own scripts rely on Bridge.Events.On(...), trigger the mapped events yourself:Standalone Identity Details
Bridge.Player.GetIdentifier(source)returnsGetPlayerIdentifier(source, 0)— the first identifier the server exposes (typicallylicense:..., but this depends on your server’s identifier order). All phone data is keyed by this value, so make sure it’s stable.Bridge.Player.GetName(source)returns the FiveM display name (GetPlayerName), not a character name.Bridge.Player.GetPlayerByIdentifier()only finds online players (it scans the player list, there is no offline lookup).- Client-side,
Bridge.GetIdentifier()returnsnilandBridge.IsDead()always returnsfalsein standalone.
Troubleshooting
SQL error: Table 'users' doesn't exist
SQL error: Table 'users' doesn't exist
Standalone queries the
users table for phone numbers, IBANs and names. Create the table (see Step 1) or point Bridge.UserTable at your own table in bridge/main.lua.Phone doesn't open
Phone doesn't open
In pure standalone,
Config.NeedItem must be false — item registration is unsupported without an inventory resource. Also verify the keybind (Config.OpenKey, default F1) and that no framework resource is stuck in starting (which delays Bridge init).Bank app always shows $0
Bank app always shows $0
Expected — the standalone money branches are stubs. Implement
GetBalance/AddMoney/RemoveMoney in bridge/modules/account/server.lua and bridge/modules/player/server.lua (see Step 4). Watch the console for [Bridge] Standalone: ... not implemented prints.Dispatch / News / Service apps show nothing
Dispatch / News / Service apps show nothing
These are job-gated and every standalone player is
unemployed. Implement the standalone branches in bridge/modules/job/ or accept that job features stay disabled.Console shows the standalone Bridge warning
Console shows the standalone Bridge warning
The warning on every boot reminds you to configure
Bridge.UserTable & friends. Once your tables are set up correctly you can remove the warning prints from SetStandalone() in bridge/main.lua.Next Steps
Installation
Full installation walkthrough (database, upload API, voice)
Metadata System
Item-based phone data — works in standalone with ox_inventory
Server Exports
Integrate RoadPhone with your own standalone resources
Client Exports
Client-side integration options