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

# bedoflex Handling Studio

bedoflex-handling Documentation

A real-time handling editor for FiveM with permanent saves, live sync for every player, a profile library, visual flag editing and built-in telemetry.

## ------FEATURES------

* **Real-time editing.** Every change is applied to your vehicle as you drag a slider. Fields the game cannot preview live are marked `RESPAWN`.
* **Quick Tune.** Edit power, top speed, grip, brakes, drivetrain, shift speed, suspension and more with simple sliders, plus one-click presets.
* **Advanced editor.** Covers every handling field for cars, bikes, boats and aircraft. Includes search, categories, recommended ranges, `USEFUL` highlights and per-field reset.
* **Visual flags.** Toggle model, handling, damage and advanced flags bit by bit, or type the hex value.
* **Permanent saves.** Save to a single plate or to a whole model. Saves survive server restarts, and model saves apply instantly to every spawned vehicle for every player.
* **Self-healing sync.** Handling is rebuilt when a player takes over a vehicle. It is re-applied automatically if a garage, mechanic or vehicle-properties script overwrites it.
* **Saved records manager.** See and delete every saved plate and model in-game.
* **Profiles and share codes.** Save setups with a name and notes, then load them on any vehicle or share them with a single code.
* **Export.** Export to `handling.meta` XML or to a Lua table.
* **Telemetry.** Speed, gear, RPM, G-meter, 0-100 / 0-200, 1/8, 1/4 and 1/2 mile times, and a 100-0 brake test. A speed graph compares each run with your previous run.
* **Flexible permissions.** Grant access by ACE, framework group, job and grade, license, Discord, Steam or FiveM ID, or in-game with a command.
* **Framework support.** Works standalone, or with Qbox, QBCore or ESX.
* **Storage.** JSON storage needs no setup; oxmysql is optional.

## ------REQUIREMENTS------

| Requirement                                                 | Note                                         |
| ----------------------------------------------------------- | -------------------------------------------- |
| FiveM server                                                | Build 7290 or newer, OneSync enabled         |
| [ox\_lib](https://github.com/overextended/ox_lib/releases)  | Required                                     |
| [oxmysql](https://github.com/overextended/oxmysql/releases) | Only when `ServerConfig.Storage = "oxmysql"` |
| Framework                                                   | Optional: Qbox, QBCore, ESX Legacy           |

## ------INSTALLATION------

## STEP 1 - Unzip The Folder

Unzip the script folder, then copy or cut everything inside it and paste it into your server resources folder.

## STEP 2 - Add Script To Server

Add the script to your server config after `ox_lib`:

```
ensure ox_lib
ensure bedoflex-handling
```

**NOTE: Please don't change the script name or folder name.**

## STEP 3 - Script Configuration

The script has two config files. The shared config is sent to players; the server config is never sent to players.

### STEP 3.1 - General Configuration (`config/config.lua`)

```lua
Config.Locale = "en"            -- file name in locales/
Config.Framework = "auto"       -- "auto", "Qbox", "QBCore", "ESX", "none"
Config.SpeedUnit = "kmh"        -- "kmh" or "mph"
```

Choose your language, server framework and speed unit.

### STEP 3.2 - Command Configuration

```lua
Config.Commands = {
  editor = "handling",            -- open the editor (driver seat)
  telemetry = "telemetry",        -- toggle the standalone telemetry HUD
  permissions = "handlingperms",  -- permission tools
}
```

You can rename every command, or set it to `false` to disable it.

### STEP 3.3 - Storage Configuration (`config/server.lua`)

```lua
ServerConfig.Storage = "json"   -- "json" or "oxmysql"
ServerConfig.Webhook = ""       -- Discord webhook for save logs ("" = disabled)
```

`json` writes to `data/store.json` and needs no setup. `oxmysql` creates the `bedoflex_handling` table automatically on first start.

### STEP 3.4 - Permission Configuration (`config/server.lua`)

A role is granted when **any** of its rules match. Players that match `admins` have every role.

```lua
persist = {
  everyone = false,
  ace = { "bedoflex.handling.persist" },   -- add_ace group.mod bedoflex.handling.persist allow
  groups = { "mod" },                      -- Qbox / QBCore permission group, ESX group
  jobs = { mechanic = 3 },                 -- job + minimum grade
  identifiers = { "license:...", "discord:...", "steam:110000112345678" },
},
```

| Role        | Allows                                                   |
| ----------- | -------------------------------------------------------- |
| `editor`    | Open the editor, live preview, temporary saves, profiles |
| `persist`   | Plate saves and deleting plate saves                     |
| `model`     | Model saves and deleting model saves                     |
| `telemetry` | Standalone telemetry                                     |
| `profiles`  | Deleting other players' profiles                         |

## STEP 4 - Start The Server

Restart your server. The console will print:

```
[bedoflex-handling] Storage ready (json) - X plates, X models, X profiles loaded.
```

{% hint style="warning" %}
**Updating:** never overwrite the `data/` folder, because your saved handling is stored there. If `fxmanifest.lua` changed, run `refresh` before `restart bedoflex-handling`.
{% endhint %}

## ------COMMANDS------

| Command                                              | Description                                             |
| ---------------------------------------------------- | ------------------------------------------------------- |
| `/handling`                                          | Open the editor (driver seat required)                  |
| `/telemetry`                                         | Toggle the standalone telemetry HUD                     |
| `/handlingperms check [id]`                          | Show identifiers and why each role is granted or denied |
| `/handlingperms add <id\|identifier> <role>`         | Grant a role permanently (admin)                        |
| `/handlingperms remove <id\|identifier> <role\|all>` | Remove a role (admin)                                   |
| `/handlingperms list`                                | List in-game granted roles (admin)                      |

**Editor shortcuts:** `Ctrl + Z` / `Ctrl + Y` undo / redo · `Ctrl + S` save · `/` search · `ESC` close · `BACKSPACE` leave test drive · `G` reset telemetry

## ------SAVE TYPES------

| Type          | Lifetime                                                                         |
| ------------- | -------------------------------------------------------------------------------- |
| **Temporary** | Until the vehicle despawns                                                       |
| **Plate**     | Permanent. Re-applied every time this plate spawns                               |
| **Model**     | Permanent. Applies to every vehicle of the model, including already spawned ones |

All save types are synced to every player. A plate save takes priority over a model save.

## ------EXPORTS------

**Server**

```lua
exports["bedoflex-handling"]:GetPlateHandling(plate)
exports["bedoflex-handling"]:GetModelHandling(model)
exports["bedoflex-handling"]:SetPlateHandling(plate, model, data, by)
exports["bedoflex-handling"]:ClearPlateHandling(plate)
exports["bedoflex-handling"]:SetModelHandling(model, data, by)
exports["bedoflex-handling"]:ClearModelHandling(model)
exports["bedoflex-handling"]:RefreshVehicle(vehicle) -- call right after spawning from a garage
```

**Client**

```lua
exports["bedoflex-handling"]:OpenEditor()
exports["bedoflex-handling"]:IsEditorOpen()
```

## ------EDITABLE FILES------

| File                 | Purpose                                           |
| -------------------- | ------------------------------------------------- |
| `config/config.lua`  | Language, commands, keys, sync, telemetry targets |
| `config/server.lua`  | Storage, permissions, webhook                     |
| `config/presets.lua` | Quick Tune presets                                |
| `locales/*.lua`      | All texts: UI, notifications, field names         |
| `bridge/client.lua`  | Notifications, dialogs, vehicle names             |
| `bridge/server.lua`  | Framework, groups, jobs, character names          |
| `shared/fields.lua`  | Slider ranges, recommended values                 |

## ------FAQ------

**"You don't have permission" even though I'm admin.** Run `/handlingperms check`. It lists your identifiers and which rule each role matched. If your admin group is tied to a Steam identifier, it only works while Steam is running. You can add your `license:` or `discord:` identifier to `admins.identifiers` instead.

**Another player's car doesn't drive like mine.** A plate save only affects that plate. Use a model save to change every vehicle of that model.

**A field doesn't change anything live.** Fields marked `RESPAWN` are read only when the vehicle is created. Save the change, then respawn the vehicle.

## INFOS

**Tebex :** [**https://bedoflexdev.tebex.io**](https://bedoflexdev.tebex.io)

**Discord :** [**https://bedoflexdev.net/discord**](https://bedoflexdev.net/discord)

<figure><img src="https://1782391057-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHE47mDCYcwHfrPASyBXt%2Fuploads%2FfzcMrRF0p2puvQZIfaCb%2FK%C4%B1rm%C4%B1z%C4%B1%20Tipografik%20Modern%20E%20Spor%20Oyun%20Logo%20(1).png?alt=media&amp;token=539027c9-3653-45d7-a315-ddb5b0221a57" alt=""><figcaption></figcaption></figure>
