> For the complete documentation index, see [llms.txt](https://beetle-studios.gitbook.io/beetle-studios-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://beetle-studios.gitbook.io/beetle-studios-docs/beetle-studios/chow-drop/installation.md).

# Installation

### Installation Guide

#### Requirements

Required on every server

| Resource      | Purpose                         |
| ------------- | ------------------------------- |
| ox\_lib       | Callbacks, progress, UI helpers |
| ox\_target    | Pickup / delivery interactions  |
| oxmysql       | Database                        |
| ox\_inventory | Food container item             |

Pick one framework

| Framework  | Resource      |
| ---------- | ------------- |
| Qbox / QBX | `qbx_core`    |
| QB-Core    | `qb-core`     |
| ESX        | `es_extended` |

Pick one phone

| Phone        | Resource      |
| ------------ | ------------- |
| LB Phone     | `lb-phone`    |
| CodeM mPhone | `codem-phone` |

***

#### Step 1 — Database

Import the install schema once (HeidiSQL, phpMyAdmin, or CLI):

source sql/install.sql

Or import `sql/install.sql` in your SQL client.\
This creates all Chow Drop tables. You do not need separate migration files.

***

#### Step 2 — Install the resource

1. Place the folder as `bs_chowdrop` in your `resources` directory (path may vary, e.g. `resources/[standalone]/bs_chowdrop`).
2. Open `config.lua` and set framework / phone (or leave `"auto"` — see Config Guide).
3. Ensure dependencies start before Chow Drop.

***

#### Step 3 — server.cfg

QBX + lb-phone

ensure ox\_libensure ox\_targetensure oxmysqlensure ox\_inventoryensure qbx\_coreensure lb-phoneensure bs\_chowdrop

QB-Core — use `ensure qb-core` instead of `qbx_core`.\
ESX — use `ensure es_extended`.\
CodeM — use `ensure codem-phone` instead of `lb-phone`.

Restart the server or `ensure bs_chowdrop` after a first-time install.

***

#### Step 4 — Inventory item

Chow Drop uses a food container for driver pickups.

1. Open `items.lua` in the Chow Drop resource (reference definition for `cd_food_container`).
2. Add that item to `ox_inventory/data/items.lua`.
3. Copy `cd_food_container.png` into `ox_inventory/web/images/` (if provided with the package).

Restart `ox_inventory` (or the server) after adding the item.

***

#### Step 5 — Create businesses (required for player orders)

1. In-game, run `/cd_admin` (permissioned staff).
2. Create a business and set:
   * Display name
   * Job name (must match your framework job, e.g. `burgershot`)
   * Pickup coordinates (driver GPS for that restaurant)
3. Create a menu for that business.
4. Add menu items (ox inventory name, price, optional ox inventory image name).
5. Have a player with that job go on duty, open Chow Drop → Staff, and toggle the restaurant Open.

NPC deliveries work without a `/cd_admin` business (they use built-in NPC restaurant/delivery locations). Player ordering requires businesses + menus as above.

***

#### Step 6 — Verify

| Check               | Expected                                                          |
| ------------------- | ----------------------------------------------------------------- |
| F8 / server console | No fatal errors; with `Config.Debug = false`, consoles stay quiet |
| Phone app           | “Chow Drop” appears on home / app list                            |
| Driver              | Can create account, go online, see NPC orders                     |
| Customer            | Sees open businesses after staff toggles open                     |
| Staff               | On-duty matching job → Staff tools in app                         |

***

#### Post-install checklist

* &#x20;`sql/install.sql` imported
* &#x20;`cd_food_container` in ox\_inventory
* &#x20;Framework + phone ensured before `bs_chowdrop`
* &#x20;`Config.Framework` / `Config.Phone` correct (or `auto`)
* &#x20;`Config.SoloTestMode = false` on live
* &#x20;At least one business + menu for player orders
* &#x20;ESX: duty mode configured (see Config Guide)

***

#### Common install issues

| Problem                      | Fix                                                                                |
| ---------------------------- | ---------------------------------------------------------------------------------- |
| App missing on phone         | Phone resource started? `Config.Phone` match? Restart both phone + Chow Drop       |
| No restaurants for customers | Business open? Staff on duty? Menus exist?                                         |
| No NPC orders                | Driver online? Locations loaded? (empty NPC restaurants = config/load order issue) |
| Staff mode missing           | Job name matches business? Player on duty?                                         |
| Money / ID errors            | Wrong framework selected; set `Config.Framework` explicitly                        |

***

### Configuration Guide

All buyer-facing options live in `config.lua` (escrow-ignored).\
Do not replace the whole file with `Config = {}` — that wipes escrowed NPC restaurants/locations. The file correctly uses `Config = Config or {}`.

***

#### Framework & phone

Config.Framework = "auto" -- "qbx" | "qb" | "esx" | "auto"Config.Phone = "auto" -- "lb-phone" | "codem-phone" | "auto"Config.ESXDutyMode = "job" -- ESX only

| Option        | Values                            | Notes                                               |
| ------------- | --------------------------------- | --------------------------------------------------- |
| `Framework`   | `auto`, `qbx`, `qb`, `esx`        | Prefer explicit value on production                 |
| `Phone`       | `auto`, `lb-phone`, `codem-phone` | Prefer explicit value if both phones exist          |
| `ESXDutyMode` | `job`, `metadata`, `always`       | Staff gate needs duty; `always` is for testing only |

ESX duty

* `job` — `job.onDuty` / `job.onduty` (common forks)
* `metadata` — `xPlayer.get("duty")` / meta
* `always` — any holder of the restaurant job counts as on duty (not for live)

Player IDs are stored in DB columns named `citizenid` (QBX/QB citizenid, or ESX `identifier`).

***

#### App listing (phone store / home)

Config.Identifier = "bs\_chowdrop" -- unique app id (do not change after go-live)Config.Name = "Chow Drop"Config.Description = "Deliver food, earn money, climb the ranks!"Config.Developer = "Beetle Studios"Config.DefaultApp = true -- pre-installed on home when supported

***

#### General

Config.Debug = false -- verbose client/server/UI logs when trueConfig.SoloTestMode = false -- MUST be false on liveConfig.DistanceUnits = 'imperial' -- 'metric' | 'imperial'

| Option          | Live recommendation                                                         |
| --------------- | --------------------------------------------------------------------------- |
| `Debug`         | `false`                                                                     |
| `SoloTestMode`  | `false` — bypasses silo, duty staff lock, own-workplace bans (solo QA only) |
| `DistanceUnits` | `metric` or `imperial` for in-app distance text                             |

***

#### XP & leveling (`Config.XP`)

| Field                              | Meaning                                                                                |
| ---------------------------------- | -------------------------------------------------------------------------------------- |
| `PerDelivery`                      | Base XP per completed delivery                                                         |
| `BonusPerStar`                     | Extra XP per rating star                                                               |
| `PenaltyCancel` / `PenaltyTimeout` | XP penalties                                                                           |
| `Levels[n]`                        | Per-level name, XP required, `maxOrders`, `orderRadius` (m), `maxDeliveryDistance` (m) |

* `orderRadius` — how far away a job can spawn relative to the driver (meters).
* `maxDeliveryDistance` — max restaurant → drop-off trip length for that level.

Raise radii if drivers see too few NPC jobs; lower if the map feels flooded.

***

#### Ratings (`Config.Rating`)

| Field              | Meaning                                         |
| ------------------ | ----------------------------------------------- |
| `StartingRating`   | New driver rating                               |
| `WarningThreshold` | Low-rating warning                              |
| `FiringThreshold`  | Account deactivated below this                  |
| `RatingWindow`     | Recent ratings used in calculation              |
| `RatingChances`    | NPC star weights for on-time / late / very late |

***

#### Payment (`Config.Payment`)

| Field                                                            | Meaning                                                             |
| ---------------------------------------------------------------- | ------------------------------------------------------------------- |
| `MinBasePay` / `MaxBasePay`                                      | Base pay roll                                                       |
| `DistanceBonus`                                                  | Extra per distance unit                                             |
| `MinTipPercent` / `MaxTipPercent`                                | Tip band (NPC / formula use)                                        |
| `EarlyBonus` / `OnTimeBonus` / `LatePenalty` / `VeryLatePenalty` | Time bonuses                                                        |
| `MinOrderValue` / `MaxOrderValue`                                | Simulated order value range                                         |
| `AccountType`                                                    | `'bank'` or `'cash'`                                                |
| `CollectInApp`                                                   | `true` = pending earnings collected in app; `false` = pay instantly |

***

#### Orders (`Config.Orders`)

| Field                                   | Meaning                              |
| --------------------------------------- | ------------------------------------ |
| `BaseDeliveryTime`                      | Base timer (seconds)                 |
| `TimePerKm`                             | Extra time per km                    |
| `MaxDeliveryTime`                       | Cap                                  |
| `MinOrderInterval` / `MaxOrderInterval` | NPC order spawn cadence (seconds)    |
| `OrderExpireTime`                       | How long an offer stays available    |
| `InquiryChance`                         | Chance of customer chase-up messages |
| `CancelCooldown`                        | Driver cancel cooldown               |
| `InquiryMessages`                       | Message pool for inquiries           |

***

#### NPC locations (editable extras)

Escrowed NPC restaurants and delivery spots load automatically. Add more without editing escrowed files:

Config.ExtraRestaurants = {-- {-- name = "My Custom Spot",-- coords = vec4(x, y, z, heading),-- blipSprite = 106,-- blipColor = 1,-- items = { "Burger", "Fries" },-- pedModel = "s\_m\_y\_busboy\_01"-- },}Config.ExtraDeliveryLocations = {-- { name = "Custom Residence", coords = vec4(x, y, z, h), type = "house" },}

Also configurable:

* `Config.CustomerNames` — NPC customer name pool
* `Config.DeliveryCustomerPeds` — ped models for drop-off NPCs
* `Config.DoorDeliveryChance` — % chance of door drop vs ped (0–100)

***

#### Blips (`Config.Blips`)

Config.Blips = {Pickup = { sprite = 478, color = 5, scale = 1.0 },Delivery = { sprite = 501, color = 2, scale = 1.0 }}

***

#### Admin commands (`Config.Admin`)

Defaults (rename if they clash with other scripts):

| Config key         | Default command         | Purpose                  |
| ------------------ | ----------------------- | ------------------------ |
| `AdminCommand`     | `cd_admin`              | Business / menu admin UI |
| `ResetCommand`     | `bs_chowdrop_reset`     | Reset fired driver       |
| `StatsCommand`     | `bs_chowdrop_stats`     | View driver stats        |
| `SetXPCommand`     | `bs_chowdrop_setxp`     | Set XP                   |
| `SetRatingCommand` | `bs_chowdrop_setrating` | Set rating               |

Wire these to your ace/permissions system as you do for other admin tools.

***

#### Leaderboard (`Config.Leaderboard`)

| Field             | Meaning                 |
| ----------------- | ----------------------- |
| `MaxEntries`      | Top N drivers in app    |
| `RefreshInterval` | Cache refresh (seconds) |

***

#### What you should not edit

* Escrowed NPC location files (use `ExtraRestaurants` / `ExtraDeliveryLocations` instead)
* Core bridge logic unless you know your phone/framework fork needs it
* Do not reset `Config = {}` at the top of `config.lua`

***

#### Quick live-server defaults

Config.Framework = "qbx" -- or qb / esxConfig.Phone = "lb-phone" -- or codem-phoneConfig.Debug = falseConfig.SoloTestMode = falseConfig.Payment.CollectInApp = trueConfig.Payment.AccountType = "bank"
