NX CreativeNX CreativeDocs
Scriptsnx_phone

Installation

Dependencies, inventory items, start order, media storage, app access and first-start checks for nx_phone.

This page covers what nx_phone needs beyond the generic installation guide: its dependencies, the inventory items, the start order, media storage, and how to limit an app to certain jobs.

Dependencies

oxmysql
Required

Database access. Every table is created automatically on first start.

ox_lib
Required

Callbacks, the open keybind and UI helpers.

ox_inventory
Required

The phone, SIM card and privacy screen items.

pma-voice
Optional

Optional. Carries the voice of phone calls and FaceTime, and is the default Airwave radio backend.

ox_target
Optional

Optional. The "Use payphone" option on payphones, the carrier counter and the pick-up option on a dropped phone. qb-target works too (Config.Target).

nx_computer
Optional

Optional. Shares accounts and mail with the laptop, feeds Bulletin, Stall and Exchange, and adds phone tools to its MDT.

nx_realbanking
Optional

Optional. Bank cards in Wallet, company cards in Wallet (1.11.0 or later), and required for Tap to Pay. Without it, Wallet sends money through your framework.

nx_fourseasons
Optional

Optional. The Weather app reads its forecast when it runs, and the game weather otherwise.

Garage, Home, Shift and Airwave also work with many popular garage, housing, dispatch, banking and voice scripts. They find a supported script on their own (Adapter = 'auto'). The lists are under Configuration.

Start order

Start nx_phone after your framework and the ox resources. If you run nx_computer, start the phone after it:

ensure oxmysql
ensure ox_lib
ensure ox_inventory
ensure ox_target

# your framework core (es_extended, qb-core or qbx_core) goes here

ensure nx_computer   # optional
ensure nx_phone

Database: no import required

The resource creates and updates every nx_phone_* table itself when it starts. There is no SQL file to import. The database user in your oxmysql connection string must be allowed to CREATE TABLE and ALTER TABLE.

Inventory items

Open install/ox_items.lua. Copy everything between the >>> BEGIN nx_phone items >>> and <<< END nx_phone items <<< lines into the return { ... } table of ox_inventory/data/items.lua. QBCore and QBox servers running ox_inventory use the same file.

['nx_phone'] = {
    label = 'Phone',
    weight = 200,
    stack = false,
    consume = 0,
    close = true,
    description = 'A smartphone. Needs a SIM card for calls and messages.',
    client = { export = 'nx_phone.usePhone' },
    server = { export = 'nx_phone.nx_phone' },
},

['nx_sim'] = {
    label = 'SIM Card',
    weight = 5,
    stack = false,
    consume = 0,
    close = true,
    description = 'Carries a phone number. Insert it into a phone to get service.',
    client = { export = 'nx_phone.useSim' },
    server = { export = 'nx_phone.nx_sim' },
},

-- Optional: the privacy screen (Config.Screen.Protector.Item).
['nx_phone_protector'] = {
    label = 'Privacy Screen',
    weight = 10,
    stack = true,
    close = true,
    consume = 1,
    description = 'Fits the phone in your hand. Reads straight on, goes dark from the side.',
    client = { usetime = 1500 },
    server = { export = 'nx_phone.useProtector' },
},

Keep these flags as they are:

  • stack = false on the phone and the SIM. Each one is a separate object with its own identity, and stacking would merge two of them.
  • consume = 0 on the phone and the SIM. ox_inventory removes an item with an export after use unless consume is 0.
  • Do not add degrade or durability. ox_inventory treats durability as an expiry clock and deletes the item when it runs out.

Add a 100 × 100 PNG for each item to ox_inventory/web/images/, named after the item: nx_phone.png, nx_sim.png and nx_phone_protector.png.

The item names must match Config.Item, Config.SimItem and Config.Screen.Protector.Item in config.lua. To test, give yourself a phone and a SIM, open the phone once, then use the SIM to insert it. The SIM gets its number on that first use.

First configuration

Check these in config.lua before the first start:

  • Config.Framework: 'auto' detects ESX, QBCore and QBox. Set 'esx', 'qbcore', 'qbox' or 'standalone' if detection picks the wrong one.
  • Config.Calls.Services: point jobs at your real police and EMS job names so 911 rings someone.
  • Config.Companies.List: add your businesses, one entry per company with its framework job, plus an optional label, number, location, icon and alwaysOpen. With FrameworkJobs = true every other job of your framework is listed too, so hide the ones that are not businesses with Hidden (job names) and HiddenTypes (Qbox and QBCore job types such as leo and ems). See Companies.
  • Config.Carrier.Stores: no carrier counters ship, so add your own spots if you want players to buy SIMs there.
  • Config.Locale: English ('en') is the only language that ships.

config.lua, config_server.lua, locales/ and bridge/ are not escrowed, so your edits survive updates and you can adapt the framework bridge to a forked core.

Keeping an older config.lua

If you update and keep your own config.lua, add the Companies app to it:

  • Add 'companies' to Config.Apps.Ids and to Config.Depot.Default.
  • Add AddToExisting = { 'home', 'companies' } to Config.Depot, so players who already have a phone get both apps once.
  • Add the Config.Companies block from the shipped config.lua.
  • If a business number such as the Mechanic line is in Config.Calls.Services, move it to that company's number in Config.Companies.List, or the two will clash.

Media storage

Photos, videos, voicemail, custom greetings and voice memos are stored on Fivemanage. The rest of the phone works without it: the camera still opens but cannot save, and voicemail and the Recorder are switched off.

  1. Create an API key in your Fivemanage dashboard (Tokens). One API v3 key covers images, video and audio.
  2. Put it in config_server.lua:
Config.Server.Media = {
    Backend = 'fivemanage',
    FiveManage = {
        Url    = '',   -- '' = the official Fivemanage API
        ApiKey = '',   -- your own key goes here
    },
    -- ...
}

Use your own key. Never put it in config.lua: that file is sent to every player who connects, and config_server.lua never leaves the server. Backend = 'fivemanage' is the only backend that works today. A self-hosted, Fivemanage-compatible server goes in FiveManage.Url (https only).

Restricting an app to a job

Config.Apps.Disabled turns an app off for everyone. To give an app to some players only, add a row to the nx_phone_app_policies table, which the resource creates on first start:

ColumnMeaning
app_idThe app's id, for example trace or yapp.
access_modepublic, job, gang, job_or_gang or deny.
job_name, min_job_gradeThe job, and the lowest grade that gets the app.
gang_name, min_gang_gradeThe same for gangs.
INSERT INTO nx_phone_app_policies (app_id, access_mode, job_name, min_job_grade)
VALUES ('trace', 'job', 'police', 0);

nx_phone_app_overrides grants (allow_access = 1) or refuses (0) one app to one account, with an optional expires_at. An override wins over the policy row. The phone picks up changes without a restart.

FaceTime and privacy

FaceTime connects phones through the ICE servers in Config.Server.FaceTime.Ice. With only the default STUN server, the phones in a call connect directly, and each player could read the others' public IP address from the connection. Add a TURN server (a fixed login in Ice, or a coturn TurnSecret with TurnUrls) and calls go through the relay. RelayOnly is on by default once a TURN server is configured. The nearby-voices option of the Recorder uses the same TURN server.

Troubleshooting

On start, nx_phone prints a status line and a configuration self-check to the server console:

[nx_phone] v0.0.6 | framework: esx | locale: en | media: fivemanage (configured) | nx_computer: linked
[nx_phone] Self-check passed.

Each warning names the setting at fault.

WarningFix
Config.Framework resolved to '...' but ... is not startedSet Config.Framework explicitly and start your framework core before nx_phone.
Config.Item = '...' is not registered in ox_inventoryAdd the item snippet above and restart ox_inventory.
Config.SimItem = '...' is not registered in ox_inventoryThe same, for the SIM item.
Config.Locale = '...' has no dictionary in locales/Use 'en', or add your translated locale file.
Config.Server.Media.Backend = '...' but its credentials are emptyAdd your Fivemanage API key to config_server.lua.
Config.DependOnComputer = true but nx_computer is not startedStart nx_computer, or set Config.DependOnComputer = 'auto'.
nx_phone_* tables missingCheck the oxmysql connection string and that the database user can CREATE TABLE.
NX Docs