Getting Started
Last updated on
This documentation covers setup, configuration, and internals of the dnd_phone resource.
What the resource does
dnd_phone is a modular, escrow-ready phone system for FiveM. It's built on a config-driven bridge pattern — framework, inventory, voice, banking, garage, and housing are all swappable without touching core logic — with a React + TypeScript NUI (Vite + Mantine + Zustand).
Unlike most phone scripts, dnd_phone is device-centric, not player-centric: identity (number, contacts, messages, settings, …) lives on the physical phone item's device_id, not on the player. Losing the item means losing the phone; a role-play-friendly account/recovery system lets a player re-link a new item back to their previous device.
Highlights
- Billing + EDC — job-only payment terminal (
/billing_edc, F7) that bills a phone number or a live nearby player; unpaid bills auto-charge once overdue, and a cross-resourceCreateBillexport lets other scripts invoice a player directly. - Payphone — world-prop phones that place a call through the same session machinery as a normal 1:1 call, with their own dedicated booth-bezel call UI.
- Signal Strength System — real tower-distance + altitude signal model gating Calls/Messages, separate from (and layered on top of) the mobile data/WiFi internet gate.
- Bridge pattern — swap framework (Qbox/QBCore/ESX), inventory, voice, banking, garage, housing without touching core logic; unsupported targets fall back to a
custom.luabridge you fill in yourself. - Config-driven — everything tunable from
config/*.lua, kept open (escrow_ignore) for server owners even when the rest of the resource is escrowed. - Security-first — every NUI endpoint goes through a secured wrapper (
Security.Callback/Security.NetEvent): server-side ownership checks, input validation/sanitization, and per-action rate limiting. - 20+ apps — see Features Overview for the full catalog.
- i18n — the entire UI (all apps, not just the shell) is translatable; see Locale Guide.
Core workflows
Device setup & recovery
- Player opens the phone with no device set up on their current
phoneitem → Setup Wizard. - If this identifier already has a phone account (lost/replaced item), the wizard offers "Pulihkan HP Saya" (recover — re-links the item to the most recent previous device, restoring the same number and data) alongside "Setup sebagai HP Baru" (start fresh).
- A fresh setup creates a
device_id+ serial, assigns/generates a phone number, and walks through model (iOS/Android)/language/passcode/appearance/performance steps. - The assigned number is mirrored into the framework's own player record where one exists (Qbox/QBCore's
charinfo.phone) so other resources reading the framework's number see the same one dnd_phone assigned.
Account & password recovery (role-play feature, not a real credential system)
- The first time a player sets up a phone, they create one persistent email/password + security question, scoped to their identifier (survives losing the phone item).
- Forgot password → answer the security question → set a new password.
- Credentials are stored in plain text (
dnd_phone_accounts) — an explicit server-owner decision, since this is a role-play recovery feature, not a real auth system, and DB admins already have full access to every other table.
Messaging / calls / banking / cab / etc.
Each feature is its own app + server module (server/modules/*.lua) + client module (client/modules/*.lua), gated by Config.Features and its own config/<feature>.lua. See Features Overview for the full list and Exports & Events for the endpoint reference.
Recommended first steps
- Install dependencies — see Dependencies.
- Import/verify the database schema — see Database Setup.
- Build the frontend (
cd web && npm install && npm run build). - Register the
phoneitem in your inventory — see Installation. - Configure
config/*.luato match your server (framework, banking, garage, housing bridges) — see Configuration. - Run the offline test suite before going live (
lua5.4 tests/run.lua).
Production-ready settings
Config.Debug = false(config/config.lua)- Verify
web/distwas built (cd web && npm run build) — it's git-ignored and not shipped pre-built. - Set
dnd_phone:fivemanage_keyvia convar if Camera/Gallery/media uploads are enabled. - Keep database migrations up to date after every update+restart (
server/migrations.lualogs on startup).