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

# Pepper Taxi

<figure><img src="https://content.gitbook.com/content/2wrlmY2LsiAJf6u7YGfs/blobs/GXMHiphx3XJXlRlqZtTn/.gitbook/assets/taxi-cover.png" alt="Pepper Taxi"><figcaption></figcaption></figure>

Not just "pick up an NPC, get paid": with **Pepper Taxi** your players drive a real career. They climb 50 levels, earn reputation, unlock better cars up to the limousine and can even run their own taxi company with employees and salaries. Everything is controlled from the dispatch tablet at the taxi depot.

{% hint style="info" %}
🧪 **Tested on our dev server:** Of course we test all scripts continuously on our own dev server “Pepper Scripts”.
{% endhint %}

{% hint style="success" %}
**Get Pepper Taxi:** [pepper-scripts.tebex.store](https://pepper-scripts.tebex.store/)
{% endhint %}

### Features

* Taxi career with **50 levels**, titles, level rewards and unlocks
* Reputation from **Bronze to Legend**, 1–5 star rating with reasons
* **15 customer types** and **12 mission types** – e.g. airport, hotel, night, business, VIP, multi-stop, limousine
* Real NPC passengers who wave, get in, ride along and get out
* Daily and weekly challenges, bonus for active duty time
* **Taxi company** – public or player-run – with employees, ranks, salaries and a company account
* Player rides and `/taxi` requests (also as an export for phone apps)
* **Admin panel** with offline editing and audit log
* Dispatch tablet, in-ride HUD and optional sounds
* Server-side payouts, protection against double payouts and teleports
* German & English, config and locales open

### At a glance

|                  |                                                                                                               |
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
| **Version**      | 1.0.1                                                                                                         |
| **Framework**    | ESX Legacy 1.9+                                                                                               |
| **OneSync**      | required                                                                                                      |
| **Dependencies** | [es\_extended](https://github.com/esx-framework/esx_core), [oxmysql](https://github.com/overextended/oxmysql) |
| **Not required** | ox\_lib, ox\_target, ox\_inventory                                                                            |
| **Performance**  | approx. 0.02 ms idle / 0.1 ms on duty (guide value)                                                           |
| **Distribution** | Cfx.re Asset Escrow (`config/`, `locales/`, `sql/` open)                                                      |

{% hint style="info" %}
**Open-source variant:** Pepper Taxi is also available as **Pepper Taxi (Open Source)** with the full, unencrypted source code – see the [shop](https://pepper-scripts.tebex.store/).
{% endhint %}

### Installation

#### Requirements

| Requirement        | Version                                            |
| ------------------ | -------------------------------------------------- |
| FiveM server build | 7290+ with **OneSync** (Legacy or Infinity)        |
| Framework          | ESX Legacy 1.9+ (`es_extended`)                    |
| Database           | [oxmysql](https://github.com/overextended/oxmysql) |

ox\_lib, ox\_target and ox\_inventory are **not** required.

#### Steps

{% stepper %}
{% step %}
**Download**

Download `pepper_taxi` from the [Cfx.re Portal → Granted Assets](https://portal.cfx.re/assets/granted-assets).
{% endstep %}

{% step %}
**Copy**

Extract it to `resources/[pepper]/pepper_taxi`.
{% endstep %}

{% step %}
**Database**

Keep `Config.Database.AutoInstall = true` (default) – missing tables are created on first start. Alternatively, import `sql/install.sql` manually.
{% endstep %}

{% step %}
**server.cfg**

Add the resource after its dependencies:

```cfg
ensure oxmysql
ensure es_extended
ensure pepper_taxi
```

{% endstep %}

{% step %}
**Admin permissions**

Grant admin access (see below) and adjust `config/config.lua`.
{% endstep %}

{% step %}
**Start**

Restart the server, drive to the taxi depot (yellow taxi icon, Downtown Cab Co.) and press `E`.
{% endstep %}
{% endstepper %}

#### Admin permissions

A player has admin access if **one** of these applies (always checked server-side):

* ESX group listed in `Config.Admin.Groups` (default: `superadmin`, `admin`)
* ACE permission `pepper_taxi.admin`:

```cfg
add_ace group.admin pepper_taxi.admin allow
```

{% hint style="info" %}
`Config.Admin.RequireReason = true` requires a reason for every admin change – all changes are stored in the audit log.
{% endhint %}

#### Characters (multicharacter)

Career data is stored per **ESX character identifier**. With `esx_multicharacter` every character has its own taxi career. On a character switch the shift ends cleanly and the profile is saved.

#### Database

`sql/install.sql` can be imported safely several times. It contains tables for the career, statistics, challenges, unlocks, company, transactions, admin logs and mission history.

### Configuration

All settings are open in `config/`. Restart the resource after changes.

#### Files

| File                    | Content                                                                                                                                            |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config/config.lua`     | Language, depot, dispatch, AFK, security, payouts, damage, rating, reputation, duty bonus, vehicles, NPCs, player rides, company, admin, sounds/UI |
| `config/vehicles.lua`   | Vehicle classes and taxis with requirements                                                                                                        |
| `config/levels.lua`     | XP curve, titles, career bonus, level rewards                                                                                                      |
| `config/customers.lua`  | Customer types                                                                                                                                     |
| `config/missions.lua`   | Mission types                                                                                                                                      |
| `config/locations.lua`  | Pickup and drop-off locations (81 across the map)                                                                                                  |
| `config/challenges.lua` | Daily and weekly challenge pools                                                                                                                   |
| `config/server.lua`     | Server-only: optional Discord webhook for logs                                                                                                     |

#### General

| Option                         | Default  | Description                                                |
| ------------------------------ | -------- | ---------------------------------------------------------- |
| `Config.Locale`                | `'de'`   | Language: `'de'` or `'en'`                                 |
| `Config.Debug`                 | `false`  | Detailed console logs for troubleshooting                  |
| `Config.Currency`              | `'$'`    | Currency symbol in the UI                                  |
| `Config.TimeSource`            | `'game'` | Time of day for customers/missions: `'game'` or `'server'` |
| `Config.Resets.DailyHour`      | `5`      | Daily challenge reset (server time)                        |
| `Config.Resets.WeeklyDay`      | `1`      | Weekly reset day (1 = Monday)                              |
| `Config.Database.AutoInstall`  | `true`   | Create missing tables on start                             |
| `Config.Database.SaveInterval` | `300`    | Seconds between intermediate saves                         |

#### Taxi depot (`Config.Center`)

| Option             | Default              | Description                                        |
| ------------------ | -------------------- | -------------------------------------------------- |
| `Label`            | `'Downtown Cab Co.'` | Name of the depot                                  |
| `Blip`             | enabled              | Map icon of the depot                              |
| `Dispatcher`       | enabled              | Dispatcher NPC at the terminal                     |
| `Terminal`         | Downtown             | Interaction point (press `E`)                      |
| `SpawnPoints`      | 4 spots              | Taxi spawn points, checked for free space in order |
| `MaxStartDistance` | `60.0`               | Shifts can only start this close to the depot      |

{% hint style="info" %}
Using a different depot (MLO)? Simply move all coordinates in `Config.Center` there.
{% endhint %}

#### Tablet & dispatch

| Option                                   | Default       | Description                                   |
| ---------------------------------------- | ------------- | --------------------------------------------- |
| `Config.Tablet.DefaultKey`               | `'F6'`        | Key for the tablet (players can rebind it)    |
| `Config.Tablet.AcceptKey` / `DeclineKey` | `'Y'` / `'N'` | Accept or decline jobs without the mouse      |
| `Config.Dispatch.FirstMissionDelay`      | 15–45 s       | Time until the first job after going on duty  |
| `Config.Dispatch.MinMissionDelay`        | `60`          | Minimum seconds between jobs                  |
| `Config.Dispatch.MaxMissionDelay`        | `300`         | Maximum seconds between jobs                  |
| `Config.Dispatch.OfferTimeout`           | `25`          | Seconds to accept an offer                    |
| `Config.Dispatch.MaxIgnoredOffers`       | `3`           | Ignored offers in a row before going off duty |
| `Config.Dispatch.RequireInTaxi`          | `true`        | Jobs only while sitting in your own taxi      |

#### Inactivity (`Config.Afk`)

| Option            | Default | Description                                       |
| ----------------- | ------- | ------------------------------------------------- |
| `PickupTimeout`   | `900`   | Seconds to reach the pickup point                 |
| `BoardingTimeout` | `120`   | Seconds until the passenger must be on board      |
| `IdleTimeout`     | `900`   | Available without moving → automatically off duty |

#### Payouts (`Config.Economy`)

| Option                   | Default  | Description                                              |
| ------------------------ | -------- | -------------------------------------------------------- |
| `PayAccount`             | `'bank'` | `'bank'` or `'money'`                                    |
| `GlobalMultiplier`       | `1.0`    | Multiplies all payouts (e.g. `1.5` for an event weekend) |
| `MinPayout`              | `25`     | Minimum payout per successful ride (never negative)      |
| `MaxRepairDeduction`     | `0.8`    | Repair deduction max. 80 % of the payout                 |
| `ChallengeBonusPerDaily` | `0.02`   | +2 % per completed daily challenge today …               |
| `ChallengeBonusMax`      | `0.06`   | … up to +6 %                                             |

Payouts per mission type (base amount, price per km, XP) are set in `config/missions.lua`.

#### Rating & reputation

| Option                               | Default | Description                                                                      |
| ------------------------------------ | ------- | -------------------------------------------------------------------------------- |
| `Config.Rating.SpeedLimit`           | `36.0`  | m/s (\~130 km/h) – faster counts as speeding                                     |
| `Config.Rating.DamagePerStar`        | `120`   | Damage points per lost star                                                      |
| `Config.Reputation.Tiers`            | 6 tiers | Bronze, Silver, Gold, Platinum, Diamond, Legend – each with a pay bonus (0–15 %) |
| `Config.DutyBonus.DutyBonusInterval` | `3600`  | Seconds of **active** duty per XP bonus                                          |
| `Config.DutyBonus.DutyBonusXP`       | `120`   | XP per interval                                                                  |

#### Vehicles (`Config.VehicleRules`)

| Option            | Default  | Description                                           |
| ----------------- | -------- | ----------------------------------------------------- |
| `PlatePrefix`     | `'TAXI'` | License plate prefix                                  |
| `SpawnCooldown`   | `45`     | Seconds between two spawns of a player                |
| `DeleteOnDutyEnd` | `true`   | Remove the taxi when the shift ends                   |
| `Fuel`            | `100.0`  | Start fuel (state bag `fuel` for common fuel scripts) |

New taxis are added in `config/vehicles.lua` with a unique `key`, the spawn `model`, a class (`standard`, `comfort`, `business`, `premium`, `luxury`, `limousine`) and requirements (level, reputation, rating, rides, challenge). Add-on vehicles work the same way.

{% hint style="warning" %}
Don't rename vehicle `key`s or challenge `id`s after going live – they are stored in the database.
{% endhint %}

#### Player rides & requests

| Option                           | Default | Description                                      |
| -------------------------------- | ------- | ------------------------------------------------ |
| `Config.PlayerRides.Enabled`     | `true`  | Drivers can transport players (no script payout) |
| `Config.PlayerRequests.Enabled`  | `true`  | Players can call a taxi with `/taxi`             |
| `Config.PlayerRequests.Cooldown` | `120`   | Seconds between two requests                     |
| `Config.PlayerRequests.Timeout`  | `300`   | Open request expires after … seconds             |

#### Company (`Config.Company`)

| Option               | Default     | Description                                       |
| -------------------- | ----------- | ------------------------------------------------- |
| `AllowPurchase`      | `true`      | Players can take over the company at the terminal |
| `PurchasePrice`      | `750000`    | Purchase price                                    |
| `OwnerCanDrive`      | `true`      | The owner may drive as well                       |
| `DriverShareDefault` | `0.35`      | Driver's share if the rank sets nothing           |
| `RepairPaidBy`       | `'company'` | `'company'` or `'driver'`                         |
| `VehicleSpawnCost`   | `150`       | Operating cost per taxi taken out                 |
| `SalaryInterval`     | `1800`      | Seconds of active duty per salary payment         |
| `MaxEmployees`       | `40`        | Maximum employees                                 |
| `DefaultRanks`       | 5 ranks     | Salary, share and permissions per rank            |

#### Admin, sounds & UI

| Option                       | Default               | Description                                        |
| ---------------------------- | --------------------- | -------------------------------------------------- |
| `Config.Admin.Groups`        | `superadmin`, `admin` | ESX groups with admin access                       |
| `Config.Admin.Ace`           | `'pepper_taxi.admin'` | ACE permission as an alternative                   |
| `Config.Admin.RequireReason` | `true`                | Reason required for every change                   |
| `Config.Sounds.Enabled`      | `true`                | Default for new players (changeable in the tablet) |
| `Config.Sounds.Volume`       | `0.45`                | Volume 0.0–1.0                                     |
| `Config.UI.HudPosition`      | `'right'`             | In-ride HUD `'right'` or `'left'`                  |

#### Other files

* **Levels** (`config/levels.lua`): XP curve, single level overrides, maximum level (can be raised, e.g. to 75), titles and rewards.
* **Challenges** (`config/challenges.lua`): daily/weekly pools, metrics (rides, distance, earnings, player rides, duty minutes), filters and rewards.
* **Locations** (`config/locations.lua`): place coordinates at the roadside – the NPC finds a safe sidewalk spot automatically.

### Gameplay

#### Starting a shift

1. Drive to the **taxi depot** (yellow taxi icon, Downtown Cab Co.) and press `E` at the terminal.
2. Choose an unlocked taxi – it spawns on a free parking spot.
3. You are now **available**. No ESX job is needed – every player can drive.

#### Taking jobs

* Jobs arrive at random intervals (by default every 1–5 minutes) with a countdown and sound.
* Accept with `Y`, decline with `N` – no mouse needed while driving.
* Jobs only arrive while you sit in your own taxi and are not on a break.

#### The ride

{% stepper %}
{% step %}
**Pickup**

Drive to the marked pickup point. The passenger waves, walks to the taxi and gets in.
{% endstep %}

{% step %}
**Drive**

Bring the customer to the destination – some missions have intermediate stops. The HUD shows route and status.
{% endstep %}

{% step %}
**Arrival**

Stop at the destination. The passenger gets out and you get your result: stars, payout, XP and reputation.
{% endstep %}
{% endstepper %}

#### Mission types

City, airport, hotel, night, long distance, remote, business, multi-stop, event, VIP, chauffeur and limousine. Which missions you get depends on level, reputation, rating, vehicle class, time of day and position.

#### Rating (1–5 stars)

Calculated server-side from damage, collisions, speed, duration and waiting time – the reason is shown in the UI. Good ratings raise your reputation and XP.

#### Career & reputation

* **50 levels** with titles, level rewards and vehicle unlocks up to the limousine
* **Reputation** Bronze → Silver → Gold → Platinum → Diamond → Legend (separate from level, with pay bonus)
* **Challenges** daily and weekly with rewards
* **Duty bonus:** extra XP per hour of *active* duty (driving, not AFK)

#### Player rides & taxi requests

* Players call a taxi with `/taxi [message]` – all drivers on duty are notified and can accept with `Y` or via the tablet.
* For rides with real players, switch to **"Player as passenger"** in the tablet: no NPC jobs and no script payout during the ride.

#### Taxi company

| Mode                 | Description                                                                                                                                                         |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Public** (default) | Nobody owns the company – everybody drives and gets the full payout.                                                                                                |
| **Player company**   | Once a player owns it, only the owner and employees drive. Fares go to the company, drivers receive their rank's share, salaries are paid from the company account. |

The company can be taken over in the tablet ("Take over company") or assigned by an admin. The owner can give it up, or an admin can make it public again.

#### Admin panel

Tablet → **Admin**: search players (also offline), change XP, level, reputation, statistics, challenges and unlocks, manage the company – every change is recorded in the audit log.

### Commands & Exports

#### Commands & keys

| Command        | Key  | Function                                                         |
| -------------- | ---- | ---------------------------------------------------------------- |
| `/taxitablet`  | `F6` | Open the tablet (anywhere while on duty, otherwise at the depot) |
| `/taxiaccept`  | `Y`  | Accept a job / the newest player request                         |
| `/taxidecline` | `N`  | Decline a job                                                    |
| `/taxi [text]` | –    | Call a taxi (all drivers on duty are notified)                   |
| `/taxicancel`  | –    | Cancel your own request                                          |

{% hint style="info" %}
Players can change the keys in the GTA settings → Key Bindings → FiveM.
{% endhint %}

#### Exports (server)

| Export                                      | Returns / description                                                                |
| ------------------------------------------- | ------------------------------------------------------------------------------------ |
| `GetTaxiPlayerData(source)`                 | Career and statistics (level, XP, reputation, rating …)                              |
| `IsTaxiDriverOnDuty(source)`                | `boolean`                                                                            |
| `GetTaxiDriverStatus(source)`               | Status, e.g. `'OFF_DUTY'`, `'AVAILABLE'`, `'PLAYER_PASSENGER'`, `'BREAK'`            |
| `SetPlayerPassengerActive(source, active)`  | Turn "player as passenger" on/off – returns `ok, reason`                             |
| `CreatePlayerTaxiRequest(source, message)`  | Create a taxi request (e.g. from a phone app) – returns `requestId` or `nil, reason` |
| `CancelPlayerTaxiRequest(source)`           | Cancel the player's request                                                          |
| `GetOpenTaxiRequests()`                     | List of open requests                                                                |
| `GetOnDutyDrivers()`                        | List of drivers on duty                                                              |
| `GetTaxiCompany()`                          | Company info (label, mode, balance, employees, owner)                                |
| `IsTaxiCompanyEmployee(sourceOrIdentifier)` | `boolean, grade`                                                                     |

Example:

```lua
local onDuty = exports.pepper_taxi:IsTaxiDriverOnDuty(source)
```

{% hint style="info" %}
There is deliberately **no** export that lets other resources create money, XP or reputation.
{% endhint %}

#### Events (server)

For phone apps and other server resources:

| Event                         | Parameters                                                 |
| ----------------------------- | ---------------------------------------------------------- |
| `pepper_taxi:requestCreated`  | `request`                                                  |
| `pepper_taxi:requestAccepted` | `request`, `driverSource`                                  |
| `pepper_taxi:requestClosed`   | `requestId`, `reason` (`finished`, `cancelled`, `expired`) |

### FAQ

| Problem                      | Solution                                                                                                            |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| "Database not reachable"     | Is oxmysql running? Is `mysql_connection_string` correct? Check the console on start.                               |
| Tables missing               | Import `sql/install.sql` or set `Config.Database.AutoInstall = true`.                                               |
| No jobs                      | Sit in your own taxi (`Config.Dispatch.RequireInTaxi`), no break, status "Available". Waiting time up to 5 minutes. |
| "All parking spots occupied" | Remove vehicles at the spawn points or add more `Config.Center.SpawnPoints`.                                        |
| NPC does not get in          | After `Config.Passenger.BoardTimeout` the NPC is seated automatically. Free rear seats are needed.                  |
| Passenger doesn't appear     | Check the model in `config/customers.lua`. Enable `Config.Debug = true` and check the F8 console.                   |
| Payout missing               | The ride was probably implausible (teleport, too short) – see the server console.                                   |
| Admin area missing           | ESX group in `Config.Admin.Groups` or ACE `pepper_taxi.admin`. Reopen the tablet.                                   |
| A location is badly placed   | Adjust the coordinates in `config/locations.lua` (roadside) and restart the resource.                               |

<details>

<summary>Do players need an ESX job?</summary>

No. Everyone can go on duty at the depot. Employees and ranks of a player company are managed inside the script.

</details>

<details>

<summary>Does every character have its own career?</summary>

Yes. Data is stored per ESX character identifier, so `esx_multicharacter` works out of the box.

</details>

<details>

<summary>Can I connect a phone app?</summary>

Yes – use the export `CreatePlayerTaxiRequest` and the request events, see **Commands & Exports**.

</details>

<details>

<summary>Does F6 conflict with Pepper Bus or Pepper Trucking?</summary>

No – Bus uses F7 and Trucking F9. Every player can also rebind the key.

</details>

### Changelog

#### 1.0.1 – 2026-09-26

**Fixed**

* Company account: crash on deposits, withdrawals, salaries and ride income of a player company
* Challenge popup: texts and rewards were displayed shifted

#### 1.0.0 – 2026-09-26

**Initial release**

* Taxi career with 50 levels, reputation, 15 customer types and 12 mission types incl. limousine career
* 1–5 star rating, daily and weekly challenges, duty bonus
* Player rides and `/taxi` requests
* Taxi company (public or player-run) with employees, ranks, salaries and company account
* Admin panel with offline editing and audit log
* Dispatch tablet, HUD, sounds; German and English
