Skip to content

Unique Phones & SIM Cards

By default sd-phone works like most phone resources: every character has one phone number and one set of data, and any phone item opens it. configs/uniqueandsim.lua replaces that with a system where numbers live on SIM cards (or on the phone itself) and you choose who owns the data — each phone item, the SIM, or the character.

Pick your setup

You wantSet
Stock behaviour (shared data, automatic numbers)Enabled = false
Unique phones, SIM cards carry the numberEnabled = true, DataOwner = 'device'
Unique phones, no SIM items (built-in numbers)'device' + BuiltInNumbers = true
Stock data, SIMs only change your numberEnabled = true, DataOwner = 'character'
The SIM is the phone (original unique phones)Enabled = true, DataOwner = 'sim'

The mental model for players: phone = your stuff, SIM = your reachability. How literally that holds depends on the mode.

Backend requirement

Reading and writing per-slot item metadata is required. Supported out of the box: ox_inventory (metadata mode, or the physical SIM-tray mode) and qb-inventory / ps-inventory / lj-inventory (metadata via the QBCore item info table). Other inventories need a small adapter in server/sim/inv.lua; plain ESX inventory has no item metadata and cannot support the feature — the phone falls back to stock behaviour with a console warning.

The three data models

DataOwner = 'device' — the phone owns the data (default)

Each phone item gets a persistent identity the first time it's used, and that identity keys everything: messages, call log, contacts, photos, notes, app logins, settings, installed apps, games. The SIM only lends a number.

  • Eject the SIM and the phone drops to No Service — calls and texts are refused with a clear message — but it still opens and every non-number app keeps working.
  • Move a SIM to another phone and that phone gets your number, never your data.
  • Steal a phone and you hold its data behind the owner's lockscreen: the passcode still gates it, and Face Unlock never works for a thief (the phone remembers its first activator).
  • Texts sent to a number whose SIM is out of service queue and deliver when the SIM lands in a phone again — like real SMS store-and-forward.

DataOwner = 'character' — stock data, SIM numbers

Your data always belongs to your character. Messages, contacts, photos, app logins — every phone you pick up opens your profile, with or without a SIM, exactly as if the feature were off. A stolen phone shows the thief's own data, never the owner's. The only thing SIM cards do in this mode is decide your number:

  • Install a SIM → your number becomes the card's number. Your data doesn't change.
  • Swap to a different SIM → different number, same data.
  • Eject (or never own a SIM) → you're not cut off: the phone keeps full service on a vanilla auto-assigned number. SIMs are entirely optional here — think of them as number-changers players can use, not something they need.
  • Enabling this mode on an existing stock server changes nothing for anyone — same data, same rows, zero migration. Use /givesim <id> bind to put a character's existing number onto a physical card.

DataOwner = 'sim' — the SIM owns everything (legacy)

Whichever SIM sits in a phone decides whose data that phone shows. Steal a phone with its SIM inside and you're reading the owner's phone; without any SIM the phone opens to a full-screen No SIM wall with every server action refused. This is the original unique-phones behaviour, kept byte-for-byte for servers that want maximum-stakes phone theft.

Migrating between modes

Flipping a 'sim' server to 'device' is safe and automatic: on first use each phone adopts the identity of the SIM currently in it (one-shot grandfathering, no data copied or lost); only from then on does the number float free of the data. Flipping stock to 'character' is a no-op for data. Numbers from an lb-phone import are preserved through migrate.lua either way.

Built-in numbers ("eSIM")

BuiltInNumbers = true removes SIM items from the equation entirely: every phone mints its own permanent number on first use, stamped onto the item. No install, no eject — the number lives and dies with the phone, and giving someone "your number" means handing over the phone. Pairs with DataOwner = 'device' or 'character' ('sim' has no SIM to own data and coerces to 'device'). With it on, SimItem, SimTray, AllowEject, ActivateBlankSims, and /givesim are all inert, and Settings shows the SIM as Built-in.

Physical SIM trays

SimTray = true (ox_inventory only) gives every phone item its own 1-slot SIM tray. Instead of using a sim_card item to install it, players drag the card into the tray and drag it back out to eject. The tray belongs to that individual phone and travels with the item, so a phone that changes hands takes its SIM with it.

Using the phone item still opens the phone. The tray gets its own right-click button, which you declare on each phone item in ox_inventory/data/items.lua:

lua
buttons = {
    { label = 'SIM Tray', action = function(slot) exports['sd-phone']:openSimTray(slot) end },
},

This is the one setup step tray mode adds; the installation guide shows it in place on a full item.

Only the player currently carrying a phone can open its tray, and only a sim_card will go in.

Upgrading from the container version

Earlier builds backed the tray with an ox item container, which meant using the phone item opened the tray and the phone UI was keybind-only. That is fixed. Phones created under the old build convert themselves the first time their owner is online: the SIM inside moves to the new tray and the stale container metadata is cleared. Nothing to run, but the phone has to be in a player's inventory to be reached, so a phone left in a stash or a drop converts whenever someone picks it up.

How players experience it

  • Multiple phones: a player can carry several phones; each is reachable on its own number, and the phone they last opened is the one they "act as". Calls ring whichever phone holds the dialed number, even in a pocket.
  • Phone-scoped notifications: banners and lockscreen notifications belong to the phone they're for. A message to the phone in your pocket shows a transient "Red Phone" buzz banner (with the app's real icon), and the full notification waits on that phone's lockscreen for its next open — never leaking onto the phone you're using.
  • Live swaps: ejecting or installing a SIM updates everything in place — My Card, Settings, service state — no reopen needed.
  • Getting SIMs to players needs zero integration: sell or spawn the sim_card item anywhere (shop, loot table, admin give). A blank card activates itself on first use, minting a fresh registered number. ActivateBlankSims = false turns that off so every SIM comes through the giveSimCard export or /givesim.

Cloud Backup

With unique phones on, Settings gains a SIM & Backup page. Backups are real snapshots, iCloud-style:

  • Back Up This Phone enables a backup profile for the current phone and takes an immediate full snapshot: contacts, messages, call history, photos and albums, notes, passwords, alarms, app logins, settings, wallet ledger, game stats — everything except the phone number (numbers follow SIMs; a lost number is lost) and live room state.
  • One password per character guards every profile; it's set on first enable, required on later ones, and a copy is saved into the phone's Passwords app. If a character deletes all their profiles, the next enable may set a fresh password (the recovery path).
  • Auto Backup (on by default) refreshes the snapshot when the phone is holstered, throttled to once per 5 minutes — and only ever from the phone that owns the profile, so a lost or stolen phone can never overwrite a backup with an empty one.
  • Up to Backup.MaxProfiles phones (default 3) can be backed up per character; the Settings page lists them with last-backup times, and tapping one deletes it to free the slot.
  • Restore copies a chosen snapshot onto the current phone (with a picker when several exist), moves group-chat membership and mail logins over from the source phone, resets the UI in place, and leaves the snapshot itself untouched — so restoring can never destroy a backup.

Configuration reference

Every option in configs/uniqueandsim.lua:

OptionDefaultWhat it does
EnabledfalseMaster switch. Off = stock sd-phone: numbers auto-assigned per character, phone always has service
DataOwner'device'Who owns the data: 'device', 'sim', or 'character' (see above). The older DeviceIdentity boolean is still honoured when this key is absent
BuiltInNumbersfalsePhones mint their own permanent numbers; no SIM items at all
SimItem'sim_card'The inventory item that carries a number in its metadata
ActivateBlankSimstrueBlank cards self-activate with a fresh number on first use. Off = only /givesim and the giveSimCard export produce usable SIMs
SimTrayfalseox_inventory only: each phone gets a 1-slot "SIM tray" and SIMs are physically dragged in and out. Needs a buttons entry on the phone item (see Physical SIM trays). Renamed from UseContainers, which is still read when this key is absent
AllowEjecttrueMetadata mode: allow ejecting the installed SIM from Settings → SIM & Backup (the card returns to the inventory with its number intact)
Backup.EnabledtrueThe Cloud Backup section in Settings
Backup.MaxProfiles3How many phones one character can back up at once (each holds a full snapshot)

Admin & integration

  • /givesim <playerId> (admin) hands out a blank SIM; /givesim <playerId> bind creates a character-bound SIM carrying that character's existing number and, in 'sim' mode, their data.
  • The server exports cover the rest: giveSimCard (pre-provisioned cards with specific numbers), getSimNumber, hasSimInstalled, isSimModeActive, isNumberAvailable, and setSimNumber (the hook for "buy a custom number" scripts).
  • The SIM item setup (inventory definition + icon) is in the installation guide. Not needed with BuiltInNumbers.