Documentation

Pepper Bus

Bus driver career with real line service, schedules, 50 levels and an in-game route editor – ESX Legacy.

Overview

Pepper Bus is a long-term bus driver career for ESX Legacy: real lines with stops, NPC passengers who get on and off, a running schedule with punctuality, 50 levels, reputation, ratings, challenges and an optional player-run bus company. Admins build their own lines in the in-game line editor. Everything runs through the driver tablet (F7) at the bus depot.

  • 14 default lines, 10 line types, 9 passenger types with their own fare and comfort needs
  • Stops with doors, minimum dwell time and schedule – punctual stops pay a bonus
  • 6 buses from the shuttle bus to the festival bus, unlocked through the career
  • 1–5 stars from punctuality, driving style, speed, collisions and damage, reputation from Bronze to Legend
  • Charter rides with real players, bus company (public or player-owned)
  • Line editor and admin panel with audit log, German and English

Requirements

Dependency Required/optional Used for Link
FiveM server build 7290+ with OneSync required declared in fxmanifest.lua as /server:7290 and /onesync https://docs.fivem.net/docs/server-manual/setting-up-a-server/
ESX Legacy 1.9+ (es_extended) required players, money, admin groups, characters https://github.com/esx-framework/esx_core
oxmysql required database (career, lines and stops, company, logs) https://github.com/overextended/oxmysql
Fuel script optional buses get the fuel state bag set when they spawn (Config.VehicleRules.Fuel) –

ox_lib, ox_target and ox_inventory are not required. No ESX job is needed. Pepper Bus only runs on ESX Legacy (no QBCore/Qbox).

Installation

  1. Download the resource from the Cfx.re portal → Granted Assets.
  2. Extract it to resources/[pepper]/pepper_bus. Do not rename the pepper_bus folder – other resources call the exports via exports.pepper_bus.
  3. Add it to your server.cfg after its dependencies:
ensure oxmysql
ensure es_extended
ensure pepper_bus
  1. Database: with Config.Database.AutoInstall = true (default) the resource creates missing tables on start (14 tables prefixed bus_). The manual way is importing sql/install.sql – it can safely be imported more than once. On first start the 14 default lines from config/routes.lua are created (Config.Database.SeedDefaultRoutes).
  2. Grant admin rights (details under “Commands and permissions”), for example:
add_ace group.admin pepper_bus.admin allow
  1. Drive the default lines once and fix stops in the line editor if needed.

Pepper Bus uses no inventory items – there are no items or images to add.

First test

  1. Start the server and check the console that pepper_bus starts without errors.
  2. Drive to the bus depot (bus icon on the map, Los Santos Transit) and press E at the terminal.
  3. Pick the shuttle bus, open the tablet with F7 and choose an unlocked line.
  4. Stop inside the radius of the first stop, let passengers get on and off and drive to the last stop – stars, payout and XP appear.
  5. As an admin, check under Admin → Line editor in the tablet that the default lines exist.

Configuration

All settings are open in config/ (readable and editable under Asset Escrow):

File Controls
config/config.lua language, database, depot, tablet, dispatch, stops, schedule, AFK, security, passengers, pay, damage, rating, reputation, duty bonus, vehicle rules, charter rides, company, admin
config/vehicles.lua bus classes, 6 buses with seats, doors and requirements
config/routetypes.lua 10 line types
config/routes.lua 14 default lines and stops (only imported on first start)
config/passengers.lua 9 passenger types
config/levels.lua XP curve, titles, level rewards
config/challenges.lua pools for daily and weekly challenges
config/server.lua optional Discord webhook for logs (server-side only)
locales/de.lua, locales/en.lua all in-game and tablet texts

General

Config.Locale = 'de'
Config.TimeSource = 'game'
Config.Database = { AutoInstall = true, SeedDefaultRoutes = true, SaveInterval = 300 }
Option Default Description
Config.Locale 'de' language (de or en)
Config.Debug false verbose logs for troubleshooting
Config.TimeSource 'game' time of day for lines and passengers: 'game' or 'server'
Config.Database.SeedDefaultRoutes true create the default lines if no lines exist yet
Config.Center.MaxStartDistance 70.0 start of duty only this close to the depot (checked server-side)

Tablet and dispatch

By default drivers pick their line themselves in the tablet. With Config.Dispatch.Enabled = true dispatch also sends line offers; lines nobody has driven for a long time then pay up to +25 % demand bonus.

Option Default Description
Config.Tablet.DefaultKey 'F7' key for the tablet
Config.Tablet.AcceptKey / DeclineKey 'Y' / 'N' accept / decline a dispatch offer
Config.Dispatch.Enabled false dispatch also sends offers
Config.Dispatch.OfferTimeout 30 seconds to accept
Config.Dispatch.DemandBonusMax 0.25 maximum demand bonus

Stops and schedule

Config.Stops = { Radius = 14.0, MaxStopSpeed = 1.5, BaseDwell = 4, DwellPerPassenger = 1.2, MaxDwell = 25, ... }
Config.Schedule = { ExpectedSpeed = 12.0, OnTimeTolerance = 45, EarlyLimit = 60, ... }
Option Default Description
Config.Stops.Radius 14.0 default radius of a stop (changeable per stop in the editor)
Config.Stops.MaxStopSpeed 1.5 m/s (~5 km/h) – below that the bus counts as stopped
Config.Stops.BaseDwell 4 seconds minimum dwell time …
Config.Stops.DwellPerPassenger 1.2 … plus seconds per passenger (at most MaxDwell = 25)
Config.Schedule.OnTimeTolerance 45 seconds early/late that still count as on time
Config.Schedule.EarlyLimit 60 more than 60 s early = schedule not kept
Config.PassengerDoors { 1, 3 } door slots that open at stops (changeable per bus via doors)

Passengers and pay

Option Default Description
Config.Passengers.RushHours { { 7, 9 }, { 16, 19 } } rush hours with more passengers (RushFactor 1.6)
Config.Passengers.MaxBoardPerStop 8 at most this many boarding per stop
Config.Passengers.MaxVisible 12 visible NPCs in the bus (the rest is counted)
Config.Economy.PayAccount 'bank' account for payouts
Config.Economy.GlobalMultiplier 1.0 multiplier on all payouts
Config.Economy.FarePerStop / FareBase 9 / 6 fare per passenger and stop / base amount
Config.Economy.PunctualBonus 10 bonus per punctual stop
Config.Economy.AbortPayout 0.4 on abort 40 % of the fares collected so far
Config.Economy.MinPayout 50 minimum payout per completed line

Company and admin

Option Default Description
Config.Company.AllowPurchase true players can take over the company
Config.Company.PurchasePrice 900000 purchase price
Config.Company.VehicleSpawnCost 250 operating cost per bus handed out
Config.Admin.EditorCommand 'busstop' command for stops in the editor
Config.Admin.MaxRoutes 100 maximum number of lines
Config.Admin.MaxStopsPerRoute 40 stops per line
Config.Admin.AllowTeleport true teleport to stops in the editor

Discord webhook

In config/server.lua (never sent to clients):

ServerConfig = {
    LogWebhook = '',               -- empty = off
    LogWebhookName = 'Pepper Bus',
}

Gameplay

  1. Start a shift: press E at the depot and pick an unlocked bus – it spawns on a free parking spot.
  2. Choose a line in the tablet (F7). Locked lines show the reason (level, reputation, time, wrong bus).
  3. Stop: halt inside the stop radius (below about 5 km/h) – the doors open automatically.
  4. Boarding: the HUD shows the dwell time (“Doors open”). Leave too early and passengers are left behind.
  5. Schedule: starts with the first departure; you see punctuality live in the HUD.
  6. Last stop: stars, payout, XP and reputation.
Bus Class Seats
Shuttle bus (rentalbus) shuttle 9
City bus (bus) city 16
Airport bus (airbus) airport 16
Sightseeing bus (tourbus) tour 10
Coach (coach) coach 16
Festival bus (pbus2) party 12

Line types: shuttle, city line, school bus, airport, night line, city tour, express, regional, event shuttle, party charter. Bus company: public (everyone drives, full payout) or player-owned (only owner and employees; payouts go to the company, drivers receive their share, salaries come from the company account).

Line editor

Tablet (F7) → Admin → Line editor:

  1. New line: number, name, line type and optionally a minimum level.
  2. Stops: drive the route with a bus and press “Stop at my position” at every stop – or type /busstop without opening the tablet (the open draft is kept).
  3. Fine-tuning: rename (the street name is suggested), reorder, recapture the position, set radius, passenger demand (0.2–3.0) and extra dwell time.
  4. Preview and save: “Preview on map” shows the numbered stops, “Save” makes the line available immediately (if active), “Test run” drives it without requirements or rewards, “Copy”/“Reverse direction” creates an inactive copy.

A line needs at least 2 and at most Config.Admin.MaxStopsPerRoute stops, at least 40 m apart (Config.Stops.MinStopDistance). Running trips use a copy of the line – changes apply from the next trip. “Default lines” recreates missing lines from config/routes.lua without changing existing ones. Lines live in the database – resource updates never overwrite them.

Commands and permissions

Command / key Who What
F7 / /bustablet everyone open the tablet (anywhere on duty or as admin, otherwise at the depot)
Y / /busaccept drivers on duty accept a dispatch offer
N / /busdecline drivers on duty decline a dispatch offer
/busstop admins append the current position as a stop to the open editor draft
E everyone terminal at the depot

Every player can change the keys in GTA settings → Key Bindings → FiveM.

Admin rights (always checked server-side): ESX group from Config.Admin.Groups (default superadmin, admin) or ACE pepper_bus.admin:

add_ace group.admin pepper_bus.admin allow

Config.Admin.RequireReason = true requires a reason for player and company changes (the line editor logs without a reason); everything ends up in the audit log. Permissions inside the player company depend on the rank in Config.Company.DefaultRanks.

Exports and events

All exports are server-side:

Export Returns / description
GetBusPlayerData(source) career and statistics
IsBusDriverOnDuty(source) boolean
GetBusDriverStatus(source) status, e.g. 'OFF_DUTY', 'AVAILABLE', 'AT_STOP', 'ON_ROUTE'
GetBusDriverLine(source) current line (number, label, segment, stops, passengers on board) or nil
SetPlayerCharterActive(source, active) switch a charter ride on/off – returns ok, reason
GetOnDutyDrivers() drivers on duty with their line
GetBusRoutes() all lines incl. stops (e.g. for a timetable app)
GetBusCompany() company info (label, mode, balance, employees, owner)
IsBusCompanyEmployee(sourceOrIdentifier) employee check
local line = exports.pepper_bus:GetBusDriverLine(source)

There is deliberately no export that lets other resources create money, XP or reputation. Pepper Bus offers no public events for other resources.

FAQ

The resource does not start or reports missing dependencies.

oxmysql and es_extended must come before pepper_bus in your server.cfg. The manifest requires server build 7290+ and OneSync – without OneSync the resource does not start.

The tables are missing in the database.

Keep Config.Database.AutoInstall = true or import sql/install.sql. All tables start with bus_.

Does Pepper Bus run on QBCore or Qbox?

No. The resource uses es_extended directly and is built for ESX Legacy 1.9+ only.

Do players need an ESX job?

No. Everyone can go on duty at the depot.

There are no lines in the tablet.

Admin → Line editor → “Default lines” creates the 14 lines from config/routes.lua. Alternatively create your own line and set it active.

A line is locked.

The tablet shows the reason: level, reputation, time of day or the wrong bus for the line type.

The stop is not detected.

Stop inside the radius (below about 5 km/h, Config.Stops.MaxStopSpeed). Increase the radius in the editor or set the stop again.

Passengers stay behind at the stop.

You left too early – the HUD shows the dwell time (“Doors open”). Every stop left too early costs rating (Config.Rating.EarlyDeparturePenalty).

The message “The trip was not plausible” appears.

A teleport or shortcut between two stops was detected (less than 60 % of the straight-line distance driven or faster than Config.Security.MaxPlausibleSpeed). Details are in the server console.

Why do I not get line offers from dispatch?

By default drivers pick their lines themselves (Config.Dispatch.Enabled = false). Set it to true to receive offers as well.

The admin section in the tablet is missing.

Your ESX group must be listed in Config.Admin.Groups or you need the ACE pepper_bus.admin.

Does F7 clash with Pepper Taxi or Pepper Trucking?

No – Taxi uses F6 and Trucking F9. Every player can also rebind the key.

Can I use add-on buses?

Yes. Add them to config/vehicles.lua with spawn name, class and seats; doors defines which doors open at stops.

How do I change texts?

All texts are in locales/de.lua and locales/en.lua; pick the language with Config.Locale.

How much performance does the resource need?

Measured with resmon: 0.01 ms active.

Will an update overwrite my lines?

No. Lines live in the database and are never overwritten by updates. Back up your changed files in config/ and locales/ before updating and carry your changes over to the new version.

Support

Questions and bugs: open a ticket in our Discord: https://discord.gg/6NaFJWKDYu – link your purchase with /verify first.

Permanently tested on the Pepper Scripts dev server.

Changelog

Current version: 1.0.0 (26 Sep 2026) – first release. All changes are listed in the CHANGELOG.md file in the resource folder.


Found a mistake? Report it on Discord.