> For the complete documentation index, see [llms.txt](https://code-after-sex.gitbook.io/script-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://code-after-sex.gitbook.io/script-documentation/cas-advanced-taxi-job/how-it-works.md).

# How it works

The CAS Advanced Taxi Job server model, database tables, disconnect handling and the checks that keep fares honest.

## The server decides

Shifts, calls, fares and payments live on the server. The client draws the HUD, spawns the cab and the NPC passenger and reports what the driver does; the server checks every report before it acts on it.

* **The meter** runs on the server once a second. It reads the cab's position from the server's copy of the entity, adds the distance, counts waiting time and checks the passenger is still aboard.
* **Money** only moves on the server, through the framework bridge (`vorp_core` or `rsg-core`). Every fare closes exactly once; paying twice, paying after a cancel or racing the timeout cannot move money twice.
* **Calls** are first come, first served. Two drivers taking the same call at the same moment, from a telegram and from the board, get one winner.

## The checks

* Every request from a player is rate limited (`Config.RateLimit`).
* Requests are checked against the player's shift, cab and position: the cab must be at the pickup to board, at the drop to arrive, and back at the stand to end the shift.
* A player passenger can only start the meter in their own cab, standing beside it.
* A driver cannot call a cab and is never offered their own call.
* A jump of more than 1.5 times `Dispatch.MaxSpeed` in one second is not counted. A fare with a teleport pays no tip, gives no stars, does not count towards the rank and is sent to the Discord log. NPC fares with a teleport are also printed in the server console.
* The note a player writes for the driver is cleaned of control characters and cut to `Calls.NoteMax`. It is shown, never stored.
* An own cab is checked against cas-dealership and cas-garage: it must be the driver's car and taken out of their garage.

## Database

Three tables are created on the first start (oxmysql):

| Table              | Holds                                                                                            |
| ------------------ | ------------------------------------------------------------------------------------------------ |
| `cas_taxi_drivers` | One row per character: fares, earnings, tips, rating, rank and this week's fares and earnings.   |
| `cas_taxi_shifts`  | One row per shift: cab, office, start and end, deposit, refund, fares and take.                  |
| `cas_taxi_ledger`  | One row per fare: passenger, from, to, miles, minutes, fare, tip, cut, rating and what was paid. |

Characters are keyed by the framework's character id (VORP `charIdentifier`, RSG `citizenid`).

## Disconnects

* A driver who leaves ends their shift. The deposit is lost (`Rent.RefundOnLoss`), the cab and an NPC passenger are removed. A player passenger who was still waiting gets their wire back on the line for the other drivers; one who was riding is told the driver is gone.
* A passenger who leaves during a ride pays nothing; the fare is written to the ledger as unpaid.
* A player passenger whose driver left before the fare was settled pays nothing.

## CAS RedM Cars and other models

The Tremont Taxicab comes from [CAS RedM Cars](https://codeaftersex.com/script/redm-cars), which is required. On its cars the cab uses the car's own roof flag, fuel, engine health, paint and plates, and the rear doors open for NPC passengers. Any other model listed in `Config.Vehicles` also works as a cab: the flag is a state on the vehicle set with **J**, and the doors are the game's own.
