> For the complete documentation index, see [llms.txt](https://docs.fivemscripthub.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fivemscripthub.com/readme.md).

# FSH Weapon Tuner v2.1

Real-time weapon tuning system for FiveM. Adjust damage, fire rate, recoil, spread, and range per-weapon through a sleek tablet UI.

**By** [**Fivem Script Hub**](https://fivemscripthub.com)

***

## Features

* Per-weapon tuning: damage, fire rate, recoil, spread, range
* Tablet UI with glassmorphism design and real-time preview
* Preset system (save, load, delete, import/export JSON)
* Weapon browser with search and category filtering
* Side-by-side weapon comparison
* Bulk editing by category
* Test mode with floating damage numbers
* Hit multipliers (headshot/bodyshot configurable)
* Audit logging of all admin actions
* **Multi-framework**: QBCore, ESX, Standalone (auto-detect)
* **Multi-inventory**: ox\_inventory, qb-inventory, qs-inventory, codem-inventory (auto-detect)
* **Dynamic weapon loading** from inventory systems
* Keyboard shortcuts (Ctrl+Z undo, Ctrl+R refresh, Escape close)
* Dark/Light theme toggle
* Session history log
* Auto-apply mode

***

## Installation

1. Download and extract to your resources folder:

   ```
   resources/[scripts]/fsh-weapontuner/
   ```
2. Add to your `server.cfg`:

   ```cfg
   ensure fsh-weapontuner
   ```
3. **(Optional)** Add the tablet item to your inventory system — see [Tablet Item Setup](#tablet-item-setup) below.
4. Restart your server.

***

## Configuration

All configuration is in `config.lua`. This file is **not encrypted** — you can edit it freely.

### Framework Detection

```lua
Config.Permissions = {
    Framework = 'auto',              -- 'auto' | 'qbcore' | 'esx' | 'standalone'
    RequireQBCorePerms = true,
    AllowedQBCorePerms = { 'god' },  -- QBCore permission groups
    AcePerm = 'weapontuner.admin',   -- ACE permission for standalone
}
```

* **auto** (default): Tries QBCore, then ESX, then ACE permissions
* Set explicitly if auto-detection picks the wrong framework

### Weapon Detection

```lua
Config.WeaponDetection = {
    Source = 'auto',           -- 'auto' | 'ox_inventory' | 'qbcore' | 'config'
    MergeWithConfig = true,    -- merge dynamic + hardcoded lists
    TuneUnknownWeapons = true, -- apply defaults to unlisted weapons
}
```

* **auto** (default): Loads weapons from ox\_inventory items, then QBCore shared weapons, then falls back to `Config.WeaponCategories`
* Dynamic weapons are auto-categorized (Pistols, SMGs, Rifles, etc.)
* `MergeWithConfig = true` ensures your hardcoded weapons are always included

### Inventory System

```lua
Config.Inventory = {
    System = 'auto', -- 'auto' | 'ox_inventory' | 'qb-inventory' | 'qs-inventory' | 'codem-inventory' | 'esx' | 'none'
}
```

* Controls which inventory system is used to register the tablet as a usable item
* **auto** tries: ox\_inventory > qs-inventory > codem-inventory > QBCore > ESX

### Notifications

```lua
Config.Notifications = {
    System = 'auto', -- 'auto' | 'ox_lib' | 'qbcore' | 'esx' | 'standalone'
}
```

### Default Weapon Values

```lua
Config.Default = {
    damageMult = 1.0,
    fireRate   = 100,
    spread = { accuracy = 80, bloomRate = 0.50 },
    range = { effectiveRange = 100.0 },
    recoil = {
        enabled = true,
        camKickMin = 0.15, camKickMax = 0.35,
        camShake = 0.10,
        horizMin = -0.03, horizMax = 0.03,
    }
}
```

### Per-Weapon Overrides

```lua
Config.Weapons = {
    WEAPON_PISTOL = {
        damageMult = 1.00,
        fireRate = 120,
        spread = { accuracy = 75, bloomRate = 0.40 },
        range = { effectiveRange = 50.0 },
        recoil = { camKickMin = 0.10, camKickMax = 0.22, camShake = 0.08, horizMin = -0.02, horizMax = 0.02 }
    },
}
```

***

## Bridge System

The `bridge.lua` file is **not encrypted** and provides the connection between the tuner and your server's framework/inventory. You can customize:

* **Framework detection** — `Bridge.DetectFramework()`
* **Permission checks** — `Bridge.IsAdmin(src)`
* **Notifications** — `Bridge.Notify(src, message, type)` and `Bridge.ClientNotify(message, type)`
* **Inventory registration** — `Bridge.RegisterUsableItem(itemName, callback)`
* **Player loaded events** — `Bridge.OnPlayerLoaded(callback)`
* **Dynamic weapon list** — `Bridge.GetWeaponList()`

See `bridge.lua` comments for full documentation of each function.

***

## Tablet Item Setup

### QBCore (qb-core/shared/items.lua)

```lua
weapontablet = {
    name = 'weapontablet',
    label = 'Weapon Tuner Tablet',
    weight = 500,
    type = 'item',
    image = 'weapontablet.png',
    unique = true,
    useable = true,
    shouldClose = true,
    description = 'A tactical tablet for weapon tuning'
},
```

### ox\_inventory (ox\_inventory/data/items.lua)

```lua
['weapontablet'] = {
    label = 'Weapon Tuner Tablet',
    weight = 500,
    stack = false,
    description = 'A tactical tablet for weapon tuning',
},
```

### qs-inventory / codem-inventory

Add the item to your inventory's items configuration with the name `weapontablet`.

***

## Commands

| Command                 | Description                    | Permission |
| ----------------------- | ------------------------------ | ---------- |
| `/weapontablet`         | Opens the weapon tuner tablet  | Admin      |
| `/weapontest [on\|off]` | Toggle floating damage numbers | Admin      |
| `/weapondbg [on\|off]`  | Toggle debug HUD overlay       | Admin      |

***

## Permissions

### QBCore

Default: requires `god` permission. Change `Config.Permissions.AllowedQBCorePerms` to add more groups.

### ESX

Default: requires `admin` or `superadmin` group.

### Standalone (ACE)

Add to your `server.cfg`:

```cfg
add_ace group.admin weapontuner.admin allow
```

***

## Exports

### Client-side

```lua
-- Get the current weapon's key name (e.g. 'WEAPON_PISTOL')
local key = exports['fsh-weapontuner']:GetCurrentWeaponKey()

-- Get the merged config for a weapon key
local cfg = exports['fsh-weapontuner']:GetMergedConfigForKey('WEAPON_PISTOL')

-- Get all weapon categories (dynamic + config)
local categories = exports['fsh-weapontuner']:GetWeaponCategories()
```

***

## File Structure

```
fsh-weapontuner/
  fxmanifest.lua          -- Resource manifest
  config.lua              -- Configuration (editable)
  bridge.lua              -- Framework/inventory bridge (editable)
  client.lua              -- Client-side weapon logic (encrypted)
  client_tablet.lua       -- Tablet UI integration (encrypted)
  server.lua              -- Server-side logic (encrypted)
  html/                   -- React UI source
    dist/                 -- Built UI (auto-generated)
  data/
    overrides.json        -- Saved weapon overrides
    active_preset.json    -- Currently active preset
    presets/              -- Saved presets
    audit.log             -- Admin action log
  docs/                   -- GitBook documentation
```

***

## Building the UI

If you modify the UI source:

```bash
cd html
npm install
npm run build
```

***

## Support

* Website: [fivemscripthub.com](https://fivemscripthub.com)
