# Home

Official Documentation for Tworst Scripts - Premium FiveM Resources

<figure><img src="/files/AHu5DhOuVLcIIqfMSGPt" alt=""><figcaption></figcaption></figure>

<h2 align="center">Welcome to Tworst Scripts Documentation</h2>

<p align="center">Explore our comprehensive resources, including installation guides, configuration options, and support materials, to confidently set up and customize your FiveM server.</p>

### Get Started

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Getting Started</strong></td><td>Quick setup guide to get your first Tworst Script running on your server.</td><td></td><td><a href="/pages/3lcywsACHtTJtKZsC52t">/pages/3lcywsACHtTJtKZsC52t</a></td></tr><tr><td><strong>Guides</strong></td><td>In-depth tutorials and best practices for all our scripts.</td><td></td><td><a href="/pages/wASnV6ozcxeJP5kwJWer">/pages/wASnV6ozcxeJP5kwJWer</a></td></tr><tr><td><strong>FAQ</strong></td><td>Answers to commonly asked questions and troubleshooting tips.</td><td></td><td><a href="/pages/1asIsOaRxrS6QssYdE1g">/pages/1asIsOaRxrS6QssYdE1g</a></td></tr></tbody></table>

### Our Scripts

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>Tworst Admin Menu</strong></td><td>All-in-one admin suite — in-game menu, cloud web panel, and Discord bot.</td><td><a href="/pages/P9dJIBQXGnwYf4kTUp4S">/pages/P9dJIBQXGnwYf4kTUp4S</a></td><td><a href="/files/iWGJN2nC3saPwohoxdtb">/files/iWGJN2nC3saPwohoxdtb</a></td></tr><tr><td><strong>Lite Jobs Pack</strong></td><td>23 unique jobs in one pack — mining, fishing, trucking, and more.</td><td><a href="/pages/ZBBHKPf82oIctMFQJihw">/pages/ZBBHKPf82oIctMFQJihw</a></td><td><a href="/files/ityqc2JP9WQ9m2hzS90v">/files/ityqc2JP9WQ9m2hzS90v</a></td></tr><tr><td><strong>Multiplayer Scrapyard Job</strong></td><td>Scrapyard job with vehicle dismantling and part selling mechanics.</td><td><a href="/pages/OuwF758J69lqVDlPUJoU">/pages/OuwF758J69lqVDlPUJoU</a></td><td><a href="/files/2Cq92kuGHm9nF3gjZx59">/files/2Cq92kuGHm9nF3gjZx59</a></td></tr><tr><td><strong>Multiplayer Electrician Job</strong></td><td>Electrician job with route-based system.</td><td><a href="/pages/BcIjioZZQX5w37X4eFkL">/pages/BcIjioZZQX5w37X4eFkL</a></td><td><a href="/files/QvyfULsvJ3TdcT3MCwnm">/files/QvyfULsvJ3TdcT3MCwnm</a></td></tr><tr><td><strong>Multiplayer Gardener Job</strong></td><td>Gardening and landscaping job with plant care system.</td><td><a href="/pages/Z1h8BviTfLBwe50kqaEN">/pages/Z1h8BviTfLBwe50kqaEN</a></td><td><a href="/files/e3mrQniFuNDXE0gnuL2l">/files/e3mrQniFuNDXE0gnuL2l</a></td></tr><tr><td><strong>Multiplayer Garbage Job</strong></td><td>Garbage collection and recycling job system.</td><td><a href="/pages/ei7YkZvvtUo1uZtEF49o">/pages/ei7YkZvvtUo1uZtEF49o</a></td><td><a href="/files/1q8MlLX4soM40u3bdJn1">/files/1q8MlLX4soM40u3bdJn1</a></td></tr><tr><td><strong>Multiplayer Plumber Job</strong></td><td>Plumber job with pipe repair minigames.</td><td><a href="/pages/004XNpEzRkDXTAFXDoKa">/pages/004XNpEzRkDXTAFXDoKa</a></td><td><a href="/files/hq1ASjo5bksrBXMUCJGp">/files/hq1ASjo5bksrBXMUCJGp</a></td></tr><tr><td><strong>Multiplayer Fashion Print Job</strong></td><td>Fashion and clothing store job system.</td><td><a href="/pages/quf0EkzRIyIvnI1MMmMu">/pages/quf0EkzRIyIvnI1MMmMu</a></td><td><a href="/files/BuQCOsxLpeIKMYoIRk6i">/files/BuQCOsxLpeIKMYoIRk6i</a></td></tr><tr><td><strong>Multiplayer Transport Job</strong></td><td>Transport and delivery job system with multiple routes.</td><td><a href="/pages/Vj7zvw1Ef8f3Oe0brLDS">/pages/Vj7zvw1Ef8f3Oe0brLDS</a></td><td><a href="/files/AJuGkvyuUnNaRJrUB1XH">/files/AJuGkvyuUnNaRJrUB1XH</a></td></tr><tr><td><strong>Multiplayer Diving Job</strong></td><td>Underwater diving and salvage job.</td><td><a href="/pages/TAWqkxZSWhOPQD96KgmR">/pages/TAWqkxZSWhOPQD96KgmR</a></td><td><a href="/files/CDLS3zEtMAxYX03VRW4p">/files/CDLS3zEtMAxYX03VRW4p</a></td></tr></tbody></table>

### Resources

<table data-view="cards"><thead><tr><th></th><th></th><th data-type="content-ref"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>🎮 Discord Community</strong></td><td>Join our Discord for support, updates, and community discussions.</td><td></td><td><a href="https://discord.gg/tworst">https://discord.gg/tworst</a></td></tr><tr><td><strong>🛒 Store</strong></td><td>Browse and purchase our premium FiveM scripts.</td><td></td><td><a href="https://tworst.com/">https://tworst.com/</a></td></tr><tr><td><strong>🎬 YouTube</strong></td><td>Watch tutorials, previews, and updates on our YouTube channel.</td><td></td><td><a href="https://www.youtube.com/@tworstshop">https://www.youtube.com/@tworstshop</a></td></tr></tbody></table>

{% hint style="info" %}
**Need Help?** Can't find what you're looking for? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Installation Guide

This guide covers the general installation process for all Tworst Scripts.

## Downloading Your Script

After purchasing a script from [tworst.com](https://tworst.com), follow these steps to download it:

### Step 1: Go to Cfx.re Portal

Visit [portal.cfx.re](https://portal.cfx.re) and log in with your Cfx.re account (the same account linked to your Tebex purchase).

### Step 2: Navigate to Your Assets

1. Click on **"Granted Assets"** in the left sidebar
2. You will see a list of all scripts you have purchased

### Step 3: Download the Script

1. Find the script you want to download
2. Click the **"Download"** button next to it
3. The script will be downloaded as a `.zip` file

{% hint style="info" %}
**Can't see your purchase?** Make sure you're logged in with the same Cfx.re account that was linked during checkout on tworst.com. If you still have issues, open a ticket on our [Discord](https://discord.gg/tworst).
{% endhint %}

***

## Prerequisites

Before installing any Tworst Script, make sure you have:

* A working FiveM server
* ESX, QBCore, or vRP framework installed
* One of the following database resources:
  * **oxmysql** (Recommended)
  * mysql-async
  * ghmattimysql
* **PolyZone** resource (required for all scripts)

***

## Installing the Script

### Step 1: Extract Files

Extract the downloaded `.zip` file to your server's `resources` folder:

```
resources/
└── tw-scriptname/
    ├── fxmanifest.lua
    ├── insert.sql
    ├── config/
    │   ├── config.lua
    │   ├── coordinate.lua
    │   └── GetCore.lua
    ├── client/
    ├── server/
    ├── locales/
    └── html/
```

### Step 2: Database Setup

{% hint style="success" %}
**Automatic Setup:** All Tworst Scripts automatically create the required database tables when the script starts for the first time. In most cases, you don't need to manually import anything!
{% endhint %}

**Manual Installation (Optional):**

If automatic table creation fails or you prefer manual setup, you can import the `insert.sql` file:

**HeidiSQL:**

1. Connect to your database
2. Select your database
3. File → Run SQL file
4. Select the `insert.sql` file
5. Execute

**phpMyAdmin:**

1. Login to phpMyAdmin
2. Select your database
3. Go to "Import" tab
4. Choose the `insert.sql` file
5. Click "Go"

{% hint style="warning" %}
Always backup your database before importing new tables manually.
{% endhint %}

### Step 3: Configure the Script

Open `config/config.lua` and adjust settings to match your server:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'esx', 'oldesx', 'qb', 'oldqb', 'vrp'

-- Language
Config.Locale = 'en'  -- Options: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'esx_inventory', 'ox_inventory', 'qs_inventory', 'qb_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'qb-target', 'ox-target', 'drawtext'
```

{% hint style="info" %}
Each script has additional configuration options. Check the specific script documentation for details.
{% endhint %}

### Step 4: Add to Server Config

Add the following lines to your `server.cfg`:

```cfg
# Dependencies (must be started first)
ensure oxmysql
ensure es_extended  # or qb-core
ensure PolyZone

# Tworst Scripts
ensure tw-scriptname
```

{% hint style="warning" %}
Make sure to start the script **after** your framework, database, and PolyZone resources.
{% endhint %}

### Step 5: Start the Server

Restart your server or use the console commands:

```
refresh
ensure tw-scriptname
```

***

## Supported Systems

All Tworst Scripts support the following systems:

### Frameworks

| Framework               | Config Value   | Notes                 |
| ----------------------- | -------------- | --------------------- |
| QBCore                  | `'qb'`         |                       |
| QBCore (older versions) | `'oldqb'`      |                       |
| QBox                    | `'qb'`         | Use `'qb'` for QBox   |
| ESX Legacy              | `'esx'`        |                       |
| ESX (older versions)    | `'oldesx'`     |                       |
| vRP                     | `'vrp'`        |                       |
| Standalone              | `'standalone'` | No framework required |

{% hint style="info" %}
**QBox Users:** QBox is fully compatible with our scripts. Simply set `Config.Framework = 'qb'` to use QBox.
{% endhint %}

### Inventory Systems

| Inventory        | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Target Systems

| Target System        | Config Value  |
| -------------------- | ------------- |
| DrawText (no target) | `'drawtext'`  |
| qb-target            | `'qb-target'` |
| ox\_target           | `'ox-target'` |

### Vehicle Key Systems

| System          | Config Value        |
| --------------- | ------------------- |
| qb-vehiclekeys  | `'qb-vehiclekeys'`  |
| qbx-vehiclekeys | `'qbx-vehiclekeys'` |
| qs-vehiclekeys  | `'qs-vehiclekeys'`  |
| wasabi-carlock  | `'wasabi-carlock'`  |
| cd\_garage      | `'cd_garage'`       |

### Fuel Systems

| System     | Config Value   |
| ---------- | -------------- |
| LegacyFuel | `'LegacyFuel'` |
| ox\_fuel   | `'ox_fuel'`    |
| cdn-fuel   | `'cdn-fuel'`   |
| ps-fuel    | `'ps-fuel'`    |
| x-fuel     | `'x-fuel'`     |

### Clothing Systems

| System              | Config Value            |
| ------------------- | ----------------------- |
| qb-clothing         | `'qb-clothing'`         |
| illenium-appearance | `'illenium-appearance'` |
| fivem-appearance    | `'fivem-appearance'`    |
| esx\_skin           | `'esx_skin'`            |

{% hint style="info" %}
**Custom Support:** The clothing system is fully open-source. You can easily add support for other clothing scripts by modifying the code.
{% endhint %}

***

## Verification

After installation, check your server console. If you see errors:

1. Check config syntax (missing comma or bracket)
2. Verify framework detection in `Config.Framework`
3. Ensure all dependencies are started before the script
4. Check the [Troubleshooting](/guides/troubleshooting) page

***

## Need Help?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Script name and version
* Framework (ESX/QBCore)
* Full error message
* Steps to reproduce
  {% endhint %}


# Framework Support

Tworst Scripts support multiple frameworks to ensure compatibility with your server setup.

## Supported Frameworks

| Framework               | Config Value   | Support Level | Notes               |
| ----------------------- | -------------- | ------------- | ------------------- |
| QBCore                  | `'qb'`         | ✅ Full        |                     |
| QBCore (older versions) | `'oldqb'`      | ✅ Full        |                     |
| QBox                    | `'qb'`         | ✅ Full        | Use `'qb'` for QBox |
| ESX Legacy              | `'esx'`        | ✅ Full        |                     |
| ESX (older versions)    | `'oldesx'`     | ✅ Full        |                     |
| vRP                     | `'vrp'`        | ✅ Full        |                     |
| vRP2                    | `'vrp2'`       | ✅ Full        |                     |
| Standalone              | `'standalone'` | ✅ Full        |                     |

***

## Framework Support by Script

Not all scripts support every framework. Here's the compatibility matrix:

### Job Scripts (Full Support)

All multiplayer job scripts support **all frameworks**:

| Script          |  QB | QBox | ESX | vRP | Standalone |
| --------------- | :-: | :--: | :-: | :-: | :--------: |
| Gardener Job    |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Scrapyard Job   |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Transport Job   |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Electrician Job |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Plumber Job     |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Garbage Job     |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Diving Job      |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |
| Fashion Job     |  ✅  |   ✅  |  ✅  |  ✅  |      ✅     |

### Other Scripts (Limited Support)

| Script    |  QB | QBox | ESX | vRP | Standalone |
| --------- | :-: | :--: | :-: | :-: | :--------: |
| Boss Menu |  ✅  |   ✅  |  ❌  |  ❌  |      ❌     |
| Garage    |  ✅  |   ✅  |  ✅  |  ❌  |      ❌     |

***

## Configuration

### Setting Your Framework

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'qbox', 'esx', 'oldesx', 'vrp', 'standalone'
```

### QBCore Configuration

```lua
Config.Framework = 'qb'
-- or for older QBCore versions:
Config.Framework = 'oldqb'
```

### QBox Configuration

```lua
Config.Framework = 'qb'  -- QBox uses 'qb' config value
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible with our scripts. Simply set `Config.Framework = 'qb'` to use QBox.
{% endhint %}

### ESX Configuration

```lua
Config.Framework = 'esx'
-- or for older ESX versions:
Config.Framework = 'oldesx'
```

### vRP Configuration

```lua
Config.Framework = 'vrp'
```

### Standalone Configuration

```lua
Config.Framework = 'standalone'
```

{% hint style="info" %}
Standalone mode runs without any framework dependency. Player data management is handled internally by the script.
{% endhint %}

***

## Database Compatibility

All Tworst Scripts support these database resources:

| Database Resource | Config Value     | Notes          |
| ----------------- | ---------------- | -------------- |
| oxmysql           | `'oxmysql'`      | Recommended    |
| mysql-async       | `'mysql-async'`  | Legacy support |
| ghmattimysql      | `'ghmattimysql'` | Legacy support |

```lua
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

***

## Inventory Systems

| Inventory        | Config Value         |
| ---------------- | -------------------- |
| QBCore Inventory | `'qb_inventory'`     |
| ESX Inventory    | `'esx_inventory'`    |
| ox\_inventory    | `'ox_inventory'`     |
| qs-inventory     | `'qs_inventory'`     |
| tgiann-inventory | `'tgiann-inventory'` |
| codem-inventory  | `'codem-inventory'`  |

```lua
Config.Inventory = "qb_inventory"
```

{% hint style="info" %}
**Note:** Inventory systems only work with framework modes (not standalone).
{% endhint %}

***

## Target Systems

| Target System        | Config Value  |
| -------------------- | ------------- |
| DrawText (no target) | `'drawtext'`  |
| qb-target            | `'qb-target'` |
| ox\_target           | `'ox-target'` |

```lua
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'qb-target', 'ox-target'
```

{% hint style="info" %}
If you don't use a target system, set `Config.InteractionHandler = 'drawtext'` to use the built-in interaction system.
{% endhint %}

***

## Vehicle Key Systems

| System              | Config Value            |
| ------------------- | ----------------------- |
| qb-vehiclekeys      | `'qb-vehiclekeys'`      |
| qbx-vehiclekeys     | `'qbx-vehiclekeys'`     |
| qs-vehiclekeys      | `'qs-vehiclekeys'`      |
| wasabi-carlock      | `'wasabi-carlock'`      |
| cd\_garage          | `'cd_garage'`           |
| Renewed-Vehiclekeys | `'Renewed-Vehiclekeys'` |

```lua
Config.Vehiclekey = true
Config.VehicleSystem = "qb-vehiclekeys"
```

***

## Fuel Systems

| System     | Config Value   |
| ---------- | -------------- |
| LegacyFuel | `'LegacyFuel'` |
| ox\_fuel   | `'ox_fuel'`    |
| cdn-fuel   | `'cdn-fuel'`   |
| ps-fuel    | `'ps-fuel'`    |
| x-fuel     | `'x-fuel'`     |

```lua
Config.FuelSystem = "LegacyFuel"
```

***

## Clothing Systems

| System              | Config Value            |
| ------------------- | ----------------------- |
| qb-clothing         | `'qb-clothing'`         |
| illenium-appearance | `'illenium-appearance'` |
| fivem-appearance    | `'fivem-appearance'`    |
| esx\_skin           | `'esx_skin'`            |
| rcore\_clothing     | `'rcore_clothing'`      |

```lua
Config.ChangeClothesSystem = true
Config.ClothingScript = "qb-clothing"
```

{% hint style="info" %}
**Custom Support:** The clothing system is fully open-source. You can easily add support for other clothing scripts by modifying the code.
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having compatibility issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# FAQ

Common questions and answers about Tworst Scripts.

***

## Purchase & Download

### Where do I download my purchased scripts?

After purchasing from [tworst.com](https://tworst.com), download your scripts from **Cfx.re Portal**:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Log in with your Cfx.re account (same account linked during purchase)
3. Click **"Granted Assets"** in the left sidebar
4. Find your script and click **"Download"**

{% hint style="info" %}
**Can't see your purchase?** Make sure you're logged in with the same Cfx.re account that was linked during checkout. If you still have issues, open a ticket on our [Discord](https://discord.gg/tworst).
{% endhint %}

### Do scripts receive updates?

Yes! All Tworst Scripts receive free lifetime updates. Updates are available through the Cfx.re Portal. Join our [Discord](https://discord.gg/tworst) to be notified of new versions.

### Can I use scripts on multiple servers?

Each purchase is licensed for **one server**. For multi-server licensing, contact us on [Discord](https://discord.gg/tworst).

### Can I get a refund?

We offer a **5-day return period** following your purchase. Please note that returns are subject to certain conditions. If you experience any difficulties receiving support within this timeframe, we would be happy to extend the period for you.

For any issues regarding your purchase, please open a support ticket on our [Discord server](https://discord.gg/tworst).

{% hint style="warning" %}
**Note:** Open-source products are not eligible for refund requests.
{% endhint %}

### Is the open-source version fully open?

Yes, our scripts are completely open-source. Only the stream files (assets) are protected under escrow. You can easily view, modify, and adapt the code to your own framework with some modifications.

***

## Installation Issues

### Script won't start / No errors shown

1. Check if the resource is in the correct `resources` folder
2. Verify `ensure tw-scriptname` is in `server.cfg`
3. Check the resource name matches exactly (case-sensitive on Linux)
4. Make sure dependencies start **before** the script:

```cfg
# server.cfg - Correct order
ensure oxmysql
ensure es_extended  # or qb-core
ensure PolyZone
ensure tw-scriptname
```

### "attempt to index a nil value (global 'ESX')" or "QBCore not found"

Your framework isn't loading properly. Check your `config/config.lua`:

```lua
-- Make sure this matches your framework
Config.Framework = 'esx'    -- For ESX servers
Config.Framework = 'qb'     -- For QBCore servers
Config.Framework = 'qbox'   -- For QBox servers
Config.Framework = 'vrp'    -- For vRP servers
```

### "No such export" error

Missing dependency. Check that you have:

* **PolyZone** - Required for all scripts
* **oxmysql** - Or mysql-async/ghmattimysql
* Your framework (ESX/QBCore/vRP)

### SQL import fails

* Make sure you're importing to the correct database
* Check for existing tables that might conflict
* The SQL file is named `insert.sql` in the script folder

### PolyZone errors

Make sure PolyZone is installed and started before Tworst scripts:

```cfg
ensure PolyZone
ensure tw-scriptname
```

Download PolyZone from: [GitHub](https://github.com/mkafrin/PolyZone)

***

## Configuration Problems

### Changes to config don't apply

1. Save the file
2. Restart the resource: `ensure tw-scriptname`
3. Or restart the entire server
4. Check for syntax errors in config

### "attempt to call a nil value" in config

Syntax error in your config. Check for:

* Missing commas between values
* Unclosed brackets `{}` or parentheses `()`
* Mismatched quotes `"` or `'`

```lua
-- Wrong
Config.Setting = 'value'
Config.Other = true   -- Missing comma above!

-- Correct
Config.Setting = 'value',
Config.Other = true,
```

### How do I change the language?

```lua
Config.Locale = 'en'  -- English
Config.Locale = 'tr'  -- Turkish
Config.Locale = 'de'  -- German
Config.Locale = 'fr'  -- French
Config.Locale = 'pt'  -- Portuguese
Config.Locale = 'ru'  -- Russian
Config.Locale = 'ar'  -- Arabic
```

Available languages are in the `locales/` folder.

### How do I change the interaction system?

```lua
Config.InteractionHandler = 'drawtext'  -- Default (no target needed)
Config.InteractionHandler = 'qb-target' -- For qb-target users
Config.InteractionHandler = 'ox-target' -- For ox_target users
```

### How do I change the inventory system?

```lua
Config.Inventory = 'qb_inventory'   -- QBCore Inventory
Config.Inventory = 'ox_inventory'   -- ox_inventory
Config.Inventory = 'qs_inventory'   -- qs-inventory
Config.Inventory = 'esx_inventory'  -- ESX Inventory
```

***

## In-Game Issues

### UI doesn't appear

1. Press **F8** and check the NUI tab for JavaScript errors
2. Clear FiveM cache: Delete `%localappdata%/FiveM/FiveM.app/data/cache`
3. Verify `html/` folder exists in the resource
4. Check if another script is blocking NUI

### Job menu doesn't open

1. Check if you're at the correct location (coordinates in config)
2. Verify your interaction system is configured correctly
3. Enable `Config.Debug = true` to see console messages
4. Check if blips/markers are showing

### Markers/Blips don't show

1. Check coordinates in `config/coordinate.lua`
2. Verify blip settings are enabled
3. Check for coordinate conflicts with other scripts

### Vehicles don't spawn

1. Check vehicle model names are correct
2. Verify vehicle key system is configured:

```lua
Config.Vehiclekey = true
Config.VehicleSystem = "qb-vehiclekeys"  -- Your vehicle key resource
```

### Database not saving

1. Check oxmysql/mysql-async is running
2. Verify database credentials in `server.cfg`
3. Check server console for SQL errors
4. Make sure the table was imported from `insert.sql`

***

## Performance

### Script causing lag

1. Set `Config.Debug = false` in production
2. Check for conflicts with other resources
3. Reduce draw distances if configurable
4. Use `resmon` command to check resource usage

### High resource monitor (resmon) usage

Higher usage is normal during:

* Initial script load
* Many players using the script simultaneously
* Debug mode enabled

If usage remains high, check for conflicts or contact support.

***

## Framework Specific

### ESX: Player data not loading

Make sure ESX is exporting correctly:

```lua
Config.Framework = 'esx'
-- For older ESX versions:
Config.Framework = 'oldesx'
```

### QBCore: Functions not working

Make sure QBCore is configured:

```lua
Config.Framework = 'qb'
-- For older QBCore versions:
Config.Framework = 'oldqb'
```

### QBox: Compatibility issues

QBox is fully supported:

```lua
Config.Framework = 'qbox'
```

### vRP: Integration problems

vRP support is available for job scripts:

```lua
Config.Framework = 'vrp'
```

***

## Support

### How can I contact support?

The fastest way to get help is through our [Discord server](https://discord.gg/tworst) where we're available 7 days a week.

**Contact Options:**

* **Discord** - Fastest way to get one-on-one support, 7 days a week
* **Email** - Send us an email at <support@tworst.com> (3-5 business days)
* **YouTube** - Watch video tutorials and installation guides

### The script is not working, what should I do?

1. Check this FAQ and our troubleshooting guides
2. Make sure all dependencies are installed correctly
3. If the issue persists, join our [Discord server](https://discord.gg/tworst) and create a support ticket with your server console errors

### What information should I include in a support ticket?

* **Script name** and version
* **Framework** (ESX/QBCore/QBox/vRP) and version
* **Full error message** from server console (F8)
* **Steps to reproduce** the issue
* **Config changes** you made
* **Screenshots** if applicable

{% hint style="warning" %}
Support tickets without proper information may take longer to resolve. Please provide all relevant details.
{% endhint %}

***

## Still Need Help?

{% hint style="info" %}
Can't find your answer? Join our [Discord server](https://discord.gg/tworst) and open a support ticket. Our team is available 7 days a week!
{% endhint %}


# Configuration Basics

Learn how to configure Tworst Scripts for your server.

## Config File Structure

All Tworst Scripts use a `config/config.lua` file for configuration. Here's the basic structure:

```lua
Config = {}

-- Framework Selection
-- 'standalone' = No framework required, money system only (no inventory script needed)
-- Other options: esx, oldesx, qb, oldqb, vrp, vrp2
Config.Framework = 'qb'

-- Language
Config.Locale = 'en'  -- Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System (only for framework modes)
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory', 'codem-inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target', 'qb-target'

-- Debug Mode
Config.Debug = false  -- Set to true for development
```

***

## Framework Settings

### Selecting Your Framework

```lua
-- QBCore
Config.Framework = 'qb'

-- QBCore (older versions)
Config.Framework = 'oldqb'

-- QBox (uses 'qb' config value)
Config.Framework = 'qb'

-- ESX Legacy
Config.Framework = 'esx'

-- ESX (older versions)
Config.Framework = 'oldesx'

-- vRP
Config.Framework = 'vrp'

-- vRP2
Config.Framework = 'vrp2'

-- Standalone (no framework required)
Config.Framework = 'standalone'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible with our scripts. Simply set `Config.Framework = 'qb'` to use QBox.
{% endhint %}

{% hint style="info" %}
**Standalone Mode:** In standalone mode, there is no inventory system. Rewards are handled through the money system only.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System
Config.Inventory = "qb_inventory"

-- Inventory Image Path (change based on your inventory system)
Config.InventoryImagePath = "nui://qb-inventory/html/images/"

-- Default/fallback image when item image not found
Config.DefaultItemImage = "nui://tw-scriptname/html/img/default.png"
```

### Supported Inventory Systems

| System           | Config Value         |
| ---------------- | -------------------- |
| QBCore Inventory | `'qb_inventory'`     |
| ESX Inventory    | `'esx_inventory'`    |
| ox\_inventory    | `'ox_inventory'`     |
| qs-inventory     | `'qs_inventory'`     |
| tgiann-inventory | `'tgiann-inventory'` |
| codem-inventory  | `'codem-inventory'`  |

{% hint style="warning" %}
Inventory systems only work with framework modes (not standalone).
{% endhint %}

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target', 'qb-target'
```

| System     | Config Value  | Description                           |
| ---------- | ------------- | ------------------------------------- |
| DrawText   | `'drawtext'`  | Built-in text prompts (no dependency) |
| qb-target  | `'qb-target'` | QBCore target system                  |
| ox\_target | `'ox-target'` | Overextended target system            |

***

## Clothing System

If your script supports job clothing:

```lua
Config.ChangeClothesSystem = true  -- Enable/disable job clothing
Config.ClothingScript = "qb-clothing"
```

### Supported Clothing Scripts

| System              | Config Value            |
| ------------------- | ----------------------- |
| qb-clothing         | `'qb-clothing'`         |
| illenium-appearance | `'illenium-appearance'` |
| fivem-appearance    | `'fivem-appearance'`    |
| esx\_skin           | `'esx_skin'`            |
| rcore\_clothing     | `'rcore_clothing'`      |

***

## Vehicle Key System

For scripts that use vehicles:

```lua
Config.Vehiclekey = true  -- Enable/disable vehicle key system
```

The script automatically detects your vehicle key system. Supported systems:

| System              | Auto-detected |
| ------------------- | ------------- |
| qb-vehiclekeys      | ✅             |
| qbx-vehiclekeys     | ✅             |
| qs-vehiclekeys      | ✅             |
| wasabi-carlock      | ✅             |
| cd\_garage          | ✅             |
| Renewed-Vehiclekeys | ✅             |

***

## Fuel System

For scripts that spawn vehicles:

```lua
-- The script automatically detects your fuel system
-- Supported: LegacyFuel, x-fuel, ox_fuel, cdn-fuel, ps-fuel
```

***

## Job Settings

Common job-related settings:

```lua
-- Server Name (displayed in UI)
Config.ServerName = "TWORST"  -- Max 10 characters

-- Money Settings
Config.MoneyType = "$"      -- Currency symbol
Config.MoneyType2 = "bank"  -- Payment type: 'bank' or 'cash'

-- Job Cooldown
Config.jobCoolDownHours = 0  -- Hours between jobs (0 = no cooldown)

-- Max Players in Lobby
Config.MaxPlayersInLobby = 4

-- Job Level System
Config.jobLevelCheck = false  -- Enable/disable level requirements
```

***

## Debug Settings

```lua
-- Enable debug mode for development
Config.Debug = false

-- Enable debug commands (for testing)
Config.DebugCommands = false
```

{% hint style="warning" %}
Always set `Config.Debug = false` on production servers for better performance.
{% endhint %}

***

## Commands

Most scripts include configurable commands:

```lua
Config.Command = {
    jobReset = "jobreset",        -- Reset job progress
    jobLeave = "jobleave",        -- Leave current job
    openTutorial = "opentutorial" -- Open tutorial menu
}
```

***

## UI Positions

Some scripts allow you to customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
}
```

***

## Best Practices

1. **Always backup** your config before making changes
2. **Test changes** on a development server first
3. **Read comments** in the config file for guidance
4. **Check console** for errors after changes
5. **Use correct config values** - refer to the tables above

{% hint style="warning" %}
After modifying `config.lua`, restart the resource with `ensure [script-name]` or restart the server.
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Database Setup

Guide for setting up database tables for Tworst Scripts.

***

## Automatic Setup

{% hint style="success" %}
**Good News!** All Tworst Scripts **automatically create** the required database tables when the script starts for the first time. In most cases, you don't need to do anything manually!
{% endhint %}

When you start your server with a Tworst Script for the first time, the script will:

1. Check if the required tables exist
2. Create any missing tables automatically
3. Set up the correct table structure

**You should see a message in your server console confirming the tables were created.**

***

## Prerequisites

Before the automatic setup can work, make sure you have one of these database resources running:

| Database Resource | Config Value     | Notes          |
| ----------------- | ---------------- | -------------- |
| oxmysql           | `'oxmysql'`      | Recommended    |
| mysql-async       | `'mysql-async'`  | Legacy support |
| ghmattimysql      | `'ghmattimysql'` | Legacy support |

Set your database resource in `config/config.lua`:

```lua
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="warning" %}
Make sure your database resource starts **before** any Tworst Scripts in your `server.cfg`.
{% endhint %}

***

## Manual Setup (Optional)

In rare cases where automatic table creation fails, you can manually import the SQL tables.

### When to Use Manual Setup

* Automatic creation failed due to permission issues
* You prefer to review the table structure before creation
* You're migrating from another script

### How to Import Manually

Each Tworst Script includes an `insert.sql` file in the root folder:

```
tw-scriptname/
├── insert.sql  ← SQL file for manual import
├── fxmanifest.lua
├── config/
└── ...
```

#### Method 1: HeidiSQL

1. Connect to your database
2. Select your database from the left panel
3. Go to **File → Run SQL file**
4. Select the `insert.sql` file from the script folder
5. Click **Execute**

#### Method 2: phpMyAdmin

1. Login to phpMyAdmin
2. Select your database from the left panel
3. Go to the **Import** tab
4. Click **Choose File** and select the `insert.sql` file
5. Click **Go**

#### Method 3: Command Line

```bash
mysql -u username -p database_name < insert.sql
```

{% hint style="warning" %}
**Always backup your database** before manually importing tables, especially on production servers.
{% endhint %}

***

## Table Naming Convention

All Tworst Scripts use a consistent naming convention for database tables:

```
tw_[scriptname]_[table]
```

**Examples:**

| Script        | Table Name             |
| ------------- | ---------------------- |
| Scrapyard Job | `tw_scrapyard_players` |
| Gardener Job  | `tw_gardener_players`  |
| Transport Job | `tw_transport_players` |

This naming convention helps you:

* Easily identify which tables belong to which script
* Avoid conflicts with other resources
* Manage your database more efficiently

***

## Common Issues

| Error                | Cause                  | Solution                                                      |
| -------------------- | ---------------------- | ------------------------------------------------------------- |
| Table already exists | Previous installation  | Safe to ignore, or drop existing table if you want fresh data |
| Access denied        | Database permissions   | Check your database user has CREATE TABLE permissions         |
| Unknown database     | Database doesn't exist | Create the database first in your MySQL client                |
| Connection failed    | Wrong credentials      | Verify database credentials in your `server.cfg`              |

### Checking Database Connection

Make sure your `server.cfg` has the correct database connection string:

```cfg
set mysql_connection_string "mysql://user:password@localhost/database_name?charset=utf8mb4"
```

***

## Resetting Data

If you want to reset all data for a script:

{% hint style="danger" %}
**Warning:** This will delete all player progress and data for that script!
{% endhint %}

1. Stop your server
2. Open your database management tool
3. Find the tables starting with `tw_[scriptname]_`
4. Drop (delete) those tables
5. Start your server - tables will be recreated automatically

***

## Need Help?

{% hint style="info" %}
Having database issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Your database resource (oxmysql, mysql-async, etc.)
* The error message from server console
* Your `Config.SQL` setting
  {% endhint %}


# Troubleshooting

Common issues and solutions for Tworst Scripts.

***

## Script Won't Start

### Check Resource Name

Resource names are **case-sensitive** on Linux servers:

```cfg
# Correct
ensure tw-scrapyard

# Wrong (case sensitive on Linux)
ensure TW-Scrapyard
ensure Tw-scrapyard
```

### Check Load Order

Make sure dependencies start **before** Tworst Scripts:

```cfg
# server.cfg - Correct order
ensure oxmysql          # Database (must be first)
ensure es_extended      # or qb-core (framework)
ensure PolyZone         # Required for all Tworst Scripts
ensure tw-scriptname    # Tworst Scripts last
```

{% hint style="warning" %}
**PolyZone** is required for all Tworst Scripts. Make sure it's installed and started before the script.
{% endhint %}

### Check Resource Folder

1. Verify the resource is in the correct `resources` folder
2. Check that the folder name matches exactly (no spaces or special characters)
3. Make sure all files were extracted properly

### Check Console for Errors

* Press **F8** in-game to see client console
* Check server console for red error messages
* Look for specific error messages to identify the issue

***

## Framework Issues

### "ESX not found" or "QBCore not found"

Your framework setting doesn't match your server:

```lua
-- config/config.lua

-- For QBCore servers:
Config.Framework = 'qb'

-- For older QBCore versions:
Config.Framework = 'oldqb'

-- For QBox servers (uses 'qb'):
Config.Framework = 'qb'

-- For ESX Legacy servers:
Config.Framework = 'esx'

-- For older ESX versions:
Config.Framework = 'oldesx'

-- For vRP servers:
Config.Framework = 'vrp'

-- For vRP2 servers:
Config.Framework = 'vrp2'

-- For standalone (no framework):
Config.Framework = 'standalone'
```

### "attempt to index a nil value (global 'ESX')"

1. Check if your framework is starting properly
2. Verify the framework resource name in your `server.cfg`
3. Make sure `Config.Framework` matches your actual framework

### "No such export" Error

Missing dependency. Check that you have:

* **PolyZone** - Required for all scripts
* **oxmysql** (or mysql-async/ghmattimysql) - Database resource
* Your framework (ESX/QBCore/vRP)

***

## UI Not Showing

### Step 1: Clear FiveM Cache

Delete the FiveM cache folder:

```
%localappdata%/FiveM/FiveM.app/data/cache
```

Or in FiveM settings, click **"Clear Cache"**.

### Step 2: Check NUI Files

Verify the `html/` folder exists in the resource and contains all files.

### Step 3: Check Browser Console

1. Press **F8** in-game
2. Go to the **NUI** tab
3. Look for JavaScript errors (red text)

### Step 4: Check for Conflicts

Another script might be blocking NUI. Try disabling other UI scripts temporarily.

***

## Database Issues

### Tables Not Creating Automatically

{% hint style="info" %}
Tworst Scripts automatically create database tables on first start. If this fails:
{% endhint %}

1. Check your database resource is running (`oxmysql`, `mysql-async`, or `ghmattimysql`)
2. Verify `Config.SQL` matches your database resource
3. Check database connection in `server.cfg`
4. Manually import `insert.sql` as a last resort

### "Table doesn't exist"

If automatic creation failed:

1. Find the `insert.sql` file in the script folder
2. Import it using HeidiSQL, phpMyAdmin, or command line
3. Restart the server

### "Connection refused" / "Access denied"

Check your database connection string in `server.cfg`:

```cfg
set mysql_connection_string "mysql://user:password@localhost/database_name?charset=utf8mb4"
```

Make sure:

* Username and password are correct
* Database exists
* User has proper permissions

***

## In-Game Issues

### Job Menu Doesn't Open

1. Check if you're at the correct location (see `config/coordinate.lua`)
2. Verify your interaction system is configured correctly:

   ```lua
   Config.InteractionHandler = 'drawtext'  -- or 'ox-target', 'qb-target'
   ```
3. Enable debug mode to see console messages:

   ```lua
   Config.Debug = true
   ```
4. Check if blips/markers are showing on the map

### Markers/Blips Don't Show

1. Check coordinates in `config/coordinate.lua`
2. Verify blip settings are enabled in config
3. Check for coordinate conflicts with other scripts

### Vehicles Don't Spawn

1. Check vehicle model names are correct in config
2. Verify vehicle key system is configured:

   ```lua
   Config.Vehiclekey = true
   ```
3. The script auto-detects your vehicle key system

### Items Not Given / Inventory Issues

1. Check `Config.Inventory` matches your inventory system:

   ```lua
   Config.Inventory = "qb_inventory"  -- or 'ox_inventory', 'esx_inventory', etc.
   ```
2. Make sure items exist in your inventory system
3. Check `Config.InventoryImagePath` for correct image paths

***

## Config Syntax Errors

### "attempt to call a nil value" in config

You have a syntax error. Check for:

* Missing commas between values
* Unclosed brackets `{}` or parentheses `()`
* Mismatched quotes `"` or `'`

```lua
-- Wrong (missing comma)
Config.Setting = 'value'
Config.Other = true

-- Correct
Config.Setting = 'value',
Config.Other = true,
```

### Changes to Config Don't Apply

1. **Save the file** (Ctrl+S)
2. **Restart the resource**: `ensure tw-scriptname`
3. Or restart the entire server
4. Check for syntax errors preventing load

***

## Performance Issues

### High Resource Usage (resmon)

1. **Disable debug mode** in production:

   ```lua
   Config.Debug = false
   Config.DebugCommands = false
   ```
2. Check for conflicts with other resources
3. Reduce draw distances if configurable

### Lag Spikes

1. Check database query efficiency
2. Monitor with `resmon` command in F8 console
3. Ensure database resource is optimized

{% hint style="info" %}
Some higher usage is normal during:

* Initial script load
* Many players using the script simultaneously
* Debug mode enabled
  {% endhint %}

***

## Common Error Messages

| Error Message                                    | Cause                  | Solution                                         |
| ------------------------------------------------ | ---------------------- | ------------------------------------------------ |
| `attempt to index a nil value (global 'ESX')`    | Framework not detected | Check `Config.Framework` setting                 |
| `attempt to index a nil value (global 'QBCore')` | Framework not detected | Check `Config.Framework` setting                 |
| `No such export`                                 | Missing dependency     | Install required resource (PolyZone, etc.)       |
| `SCRIPT ERROR: @tw-...`                          | Script error           | Check full error message, report to support      |
| `Table 'tw_...' doesn't exist`                   | Database issue         | Import `insert.sql` or check database connection |

***

## Debug Mode

Enable debug mode to get more information about issues:

```lua
Config.Debug = true
Config.DebugCommands = true  -- Enables debug commands
```

Debug mode will show:

* Console messages for each action
* Coordinate information
* State changes

{% hint style="warning" %}
**Remember:** Always disable debug mode on production servers for better performance.
{% endhint %}

***

## Still Need Help?

{% hint style="info" %}
Can't solve your issue? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* **Script name** and version
* **Framework** (ESX/QBCore/QBox/vRP) and version
* **Full error message** from server console (F8)
* **Steps to reproduce** the issue
* **Config changes** you made
* **Screenshots** if applicable

Our team is available **7 days a week**!
{% endhint %}


# Tworst Admin Menu

<figure><img src="/files/BZbQfxPD7ZDbdqFRGcR2" alt=""><figcaption></figcaption></figure>

## Overview

**Tworst Admin Menu** is an all-in-one administration suite for FiveM. It combines a powerful in-game NUI menu with an optional cloud web panel and an optional self-hosted Discord bot — giving your staff complete control over players, vehicles, and the server from anywhere.

{% hint style="success" %}
**Three ways to manage your server, one system:** the in-game menu, the **Tworst Cloud** web panel, and a **Discord bot** — all sharing the same roles, permissions, and data.
{% endhint %}

***

## The Three Components

| Component                    | What it is                                                                                                                                                                                     | Where it runs                                |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| **Admin Menu (script)**      | The in-game NUI admin panel — the core product you install on your server.                                                                                                                     | Your FiveM server (`tw-adminmenu`)           |
| **Tworst Cloud (web panel)** | A cloud-hosted browser panel that mirrors the in-game menu for remote management. Hosted by Tworst — nothing to deploy. Also available as a **Discord Activity** to open right inside Discord. | [panel.tworst.com](https://panel.tworst.com) |
| **Discord Bot**              | An open-source bot you self-host and connect to your own Discord application — run admin actions and receive logs from Discord.                                                                | Your own hosting                             |

They all share the **same roles and permissions** — a staff member's in-game role determines what they can do in the panel, in the Discord Activity, and from the bot.

```
                    ┌─────────────────────┐
   In-game menu ───▶│                     │
   Web panel ──────▶│   Your FiveM server │"""
   Discord bot ────▶│     (tw-adminmenu)  │
                    └─────────────────────┘
        all share roles · permissions · logs
```

***

## Feature Highlights

### Player Management

* Kick, warn, jail, community service, ban (temp/perm), blacklist, unban
* Teleport / bring / goto, freeze, handcuff, mute, heal, kill, strip weapons
* Spectate, **Live View** (WebRTC screen watch with proximity audio), screenshots
* Give items, edit inventory, set cash/bank/dirty money, set model, edit identity
* Player records, notes, and full per-player action history

### Vehicle Management

* Spawn with custom plate + auto keys, repair, edit/wipe mods, change plate
* Transfer to garage, impound, delete, vehicle notes, vehicle inventory explorer

### Server Management

* Live console + command execution, graceful restart/stop, whitelist toggle
* Real-time metrics (FPS, CPU, RAM, per-resource usage), resource manager

### Monitoring & Tools

* Live player monitor, spectate, Live View, replay clips (auto on death/gunfire)
* Discord mugshots, dashboard with system metrics & history

### Staff, Logs & Data

* Role-based staff management with custom roles
* Comprehensive audit logging (60+ event types) with per-category Discord webhooks
* Data explorers: items, rich list, bans, jail list, community service, whitelist, player profiles

### Engagement & Admin Extras

* Tickets (with voice notes), announcements, polls, events calendar, blips, jobs & grades, teams, invoices
* **Quick Actions** — 17 toggles (noclip, godmode, invisibility, super jump, infinite ammo, and more)
* **Troll Menu** — 39 fun actions for events and moderation

***

## Requirements

| Resource  | Required | Notes                                              |
| --------- | -------- | -------------------------------------------------- |
| oxmysql   | ✅ Yes    | Database driver — must start before `tw-adminmenu` |
| Framework | ✅ Yes    | QBCore or ESX                                      |

{% hint style="info" %}
The Admin Menu auto-detects most of your server's other systems (inventory, garages, fuel, vehicle keys, clothing, jail, etc.) — no manual wiring needed in most cases.
{% endhint %}

***

## Supported Systems

### Frameworks

| Framework | Config Value |
| --------- | ------------ |
| QBCore    | `"QBCore"`   |
| ESX       | `"ESX"`      |

### Auto-Detected Integrations

| Category           | Supported (auto-detected)                                                                                                                                |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inventory          | qb-inventory, ox\_inventory, qs-inventory, codem-inventory, tgiann-inventory, origen\_inventory, core\_inventory, chezza-inventory, ak47\_inventory, esx |
| Garage             | qb-garages, okokGarage, cd\_garage, jg-advancedgarages, qs-advancedgarages, codem-garage, op-garages, esx\_garage, tgiann-realparking                    |
| Fuel               | LegacyFuel, ox\_fuel, cdn-fuel, ti\_fuel, okokGasStation, qs-fuelstations, bigDaddy-Fuel, x-fuel, ps-fuel, Renewed-Fuel, lc\_fuel, qb-fuel               |
| Vehicle Keys       | qb-vehiclekeys, wasabi\_carlock, MrNewbVehicleKeys                                                                                                       |
| Clothing           | illenium-appearance, fivem-appearance, qb-clothing, esx\_skin, tgiann-clothing, 0r-clothingv2, rcore\_clothing, ak47\_qb\_clothing, crm-appearance       |
| Jail               | qb-prison, DHS-PrisonSim, pickle\_prisons, rcore\_prison                                                                                                 |
| Revive / Ambulance | framework native, wasabi\_ambulance, 0r-ambulancejob                                                                                                     |
| Community Service  | savana-communityservice, qb-communityservice, randol                                                                                                     |
| Invoices / Billing | qb-phone, g-billing, esx\_billing, codem-billing, codem-billing v2, codem-mphone, wasabi\_billing, bablo-billing, okokBilling                            |
| Phone Number       | metadata, qs-smartphone, qs-smartphone-pro, custom                                                                                                       |
| Weather/Time       | qb-weathersync, cd\_easytime, renewed-weathersync, av\_weather, self (native)                                                                            |

{% hint style="info" %}
Running something not on the list? **Every bridge has a `custom` adapter** — set the system to `"custom"` and wire your own integration in the matching `bridge/<domain>/adapters/custom.lua`.
{% endhint %}

### Languages

13 languages included: **EN, TR, DE, FR, ES, PT, RU, PL, NL, IT, RO, AR, TH (ไทย)**

{% hint style="info" %}
**Add your own language:** You can add a custom language to the panel **without editing the UI or rebuilding** — copy `locales/en.json`, translate the values, and register it in `locales/custom_languages.json`. Full steps: [Adding a Custom Language](/admin-menu/admin-menu/configuration#adding-a-custom-language).
{% endhint %}

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Install the in-game resource</td><td><a href="/pages/kUXby6bH45vRefu6qxbH">/pages/kUXby6bH45vRefu6qxbH</a></td></tr><tr><td><strong>Configuration</strong></td><td>Full config reference</td><td><a href="/pages/K49ZvQYW0ttCncfyCmiI">/pages/K49ZvQYW0ttCncfyCmiI</a></td></tr><tr><td><strong>Permissions &#x26; Roles</strong></td><td>Roles, permissions &#x26; god access</td><td><a href="/pages/B77ksvrMepyILmIFHLFu">/pages/B77ksvrMepyILmIFHLFu</a></td></tr><tr><td><strong>Features</strong></td><td>Complete feature reference</td><td><a href="/pages/G4OrKaCtd2mA7sCCqwVb">/pages/G4OrKaCtd2mA7sCCqwVb</a></td></tr><tr><td><strong>Web Panel (Tworst Cloud)</strong></td><td>Pair &#x26; use the cloud panel</td><td><a href="/pages/n2MeWrqzavyPHn6rZosd">/pages/n2MeWrqzavyPHn6rZosd</a></td></tr><tr><td><strong>Discord Activity</strong></td><td>Open the panel inside Discord</td><td><a href="/pages/F8yqUI2zzz79qtPT5qDr">/pages/F8yqUI2zzz79qtPT5qDr</a></td></tr><tr><td><strong>Discord Bot</strong></td><td>Self-host the Discord bot</td><td><a href="/pages/HSyNNz85LJcUNnUwknfe">/pages/HSyNNz85LJcUNnUwknfe</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Tworst Admin Menu from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the **Tworst Admin Menu** in-game resource on your FiveM server.

{% hint style="info" %}
This page covers the **in-game script** only. To use the cloud panel, see [Web Panel (Tworst Cloud)](/admin-menu/admin-menu/web-panel). To set up the Discord bot, see [Discord Bot](/admin-menu/admin-menu/discord-bot).
{% endhint %}

***

## Prerequisites

Before installing, make sure you have:

| Requirement      | Description                                 |
| ---------------- | ------------------------------------------- |
| **Framework**    | QBCore or ESX                               |
| **oxmysql**      | Required — must start before `tw-adminmenu` |
| **FiveM Server** | Recent artifact build recommended           |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-adminmenu** in your purchased assets
4. Click **Download** to get the latest version

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. Place the **`tw-adminmenu`** folder in your server's `resources` directory

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** With `TW.AutoSql = true` (default), the script automatically creates and migrates all required database tables on first start. No manual SQL import needed.
{% endhint %}

If you prefer a manual import (or disabled auto-migration), run the included `sql/install.sql` against your database.

***

## Step 4: Configure the Framework

Open `shared/config.lua` and set your framework and language:

```lua
TW.Framework = "QBCore"   -- "QBCore" or "ESX"
TW.Locale = "en"          -- en, tr, de, fr, es, pt, ru, pl, nl, it, ro, ar
TW.AutoSql = true         -- Auto-create/migrate database tables
```

{% hint style="info" %}
**QBox users:** set `TW.Framework = "QBCore"` — QBox is QBCore-compatible.
{% endhint %}

{% hint style="info" %}
Most other integrations (inventory, garage, fuel, vehicle keys, clothing, jail, etc.) are left on `"auto"` and detected automatically. See [Configuration](/admin-menu/admin-menu/configuration) for all options.
{% endhint %}

***

## Step 5: Grant First (God) Access

Before anyone can use the menu, give yourself **God** access so you can manage staff and roles in-game.

In `shared/config.lua`:

```lua
TW.GodRole = "owner"            -- The top-tier role name
TW.GodIdentifiers = {
    "fivem:1234567",            -- your fivem: id
    "discord:123456789012345",  -- and/or your discord: id
}
```

{% hint style="warning" %}
Add **your own** identifier here first. Anyone listed in `TW.GodIdentifiers` is automatically provisioned with the God role and full access on join.
{% endhint %}

***

## Step 6: Discord Token & Webhooks

For full functionality, configure your Discord integrations in `shared/server_config.lua` and `shared/webhooks.lua`.

### Discord Bot Token

Set your Discord bot token so the panel can resolve Discord avatars and member/role info:

```lua
-- shared/server_config.lua
TW_Server.DiscordBotToken = "YOUR_DISCORD_BOT_TOKEN"
```

{% hint style="warning" %}
Without a valid `DiscordBotToken`, Discord avatars and role/member lookups won't work. The token must belong to a bot that is **in your Discord server**.
{% endhint %}

### Logging Webhooks

Open `shared/webhooks.lua` and fill in a webhook URL for **every** log category you want recorded. Anything left blank falls back to `default` — and if `default` is also empty, those logs are **not sent anywhere**.

```lua
-- shared/webhooks.lua
TW_Webhooks.enabled = true
TW_Webhooks.urls = {
    punishments = "https://discord.com/api/webhooks/...",
    player      = "https://discord.com/api/webhooks/...",
    inventory   = "https://discord.com/api/webhooks/...",
    economy     = "https://discord.com/api/webhooks/...",
    vehicles    = "https://discord.com/api/webhooks/...",
    staff       = "https://discord.com/api/webhooks/...",
    server      = "https://discord.com/api/webhooks/...",
    world       = "https://discord.com/api/webhooks/...",
    tickets     = "https://discord.com/api/webhooks/...",
    spectate    = "https://discord.com/api/webhooks/...",
    notes       = "https://discord.com/api/webhooks/...",
    troll       = "https://discord.com/api/webhooks/...",
    security    = "https://discord.com/api/webhooks/...",
    default     = "https://discord.com/api/webhooks/...",  -- catch-all fallback
}
```

{% hint style="danger" %}
**Don't skip this.** If you leave webhooks empty, admin actions in those categories won't be logged to Discord and you'll have gaps in your audit trail. At minimum, set the `default` webhook so nothing is lost.
{% endhint %}

{% hint style="info" %}
A quick way to cover everything: set `default` first, then add dedicated channels for the categories you care most about (e.g. `punishments`, `economy`, `security`). See the full reference in [Configuration → webhooks](/admin-menu/admin-menu/configuration#shared-webhooks-lua).
{% endhint %}

***

## Step 7: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-adminmenu)
ensure oxmysql
ensure qb-core          # or es_extended (your framework)

# Tworst Admin Menu
ensure tw-adminmenu

# Required ACE permissions (for server commands & profiler)
add_ace resource.tw-adminmenu command allow
add_ace resource.tw-adminmenu command.profiler allow
```

{% hint style="warning" %}
**Load Order:** `oxmysql` and your framework must start **before** `tw-adminmenu`.
{% endhint %}

{% hint style="info" %}
The `add_ace` lines let the Admin Menu run server commands and the profiler (used by the dashboard/console features). Add them or those tools won't work.
{% endhint %}

***

## Step 8: Restart & Open the Menu

1. Save all configuration changes
2. Restart your server completely
3. Join the server with an account listed in `TW.GodIdentifiers`
4. Open the admin menu (use your configured keybind/command — you can also bind a key in the FiveM **Settings → Key Bindings → FiveM** menu)

{% hint style="success" %}
On first open, the built-in **onboarding tour** (`TW.Onboarding`) walks you through the panel and initial setup.
{% endhint %}

***

## Verification

After starting the server, verify the installation:

### Check Console

* Database tables created successfully (first run only)
* No error messages related to `tw-adminmenu`

### In-Game Test

1. Open the admin menu as a God user
2. Confirm the dashboard loads with live server stats
3. Open the **Online Players** page and confirm players are listed
4. Open **Admin → Staff/Roles** and add your first staff member

***

## Troubleshooting

### Menu won't open / "No access"

* Confirm your `fivem:` or `discord:` identifier is in `TW.GodIdentifiers`
* Make sure you restarted the server after editing the config

### Database errors

* Verify oxmysql is started **before** `tw-adminmenu`
* Confirm your database connection string in `server.cfg` is correct

### Framework not detected

* Make sure `TW.Framework` matches your framework (`"QBCore"` or `"ESX"`)
* Verify the framework resource starts before `tw-adminmenu`

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `TW.Framework` setting
* Screenshots of any issues
  {% endhint %}


# Configuration

The Admin Menu is configured through four files in the `shared/` folder:

| File                        | Purpose                                                             |
| --------------------------- | ------------------------------------------------------------------- |
| `shared/config.lua`         | Framework, appearance, access, economy, integrations, features      |
| `shared/server_config.lua`  | API keys, exports, Live View, Tworst Cloud uplink                   |
| `shared/webhooks.lua`       | Discord webhook logging routes                                      |
| `shared/open_functions.lua` | Integration hooks (vehicle keys, spectate, noclip, custom clothing) |

{% hint style="info" %}
Defaults are sensible — in most cases you only need to set your framework, locale, god access, the Discord token, and your webhooks to get started.
{% endhint %}

***

## shared/config.lua

### Framework & General

```lua
TW.Framework = "QBCore"   -- "QBCore" or "ESX"
TW.Locale = "en"          -- en, tr, de, fr, es, pt, ru, pl, nl, it, ro, ar, th
TW.AutoSql = true         -- Auto-create/migrate database tables on start
```

| Setting        | What it does                                                                                                                                                                  |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TW.Framework` | Your server framework. Use `"QBCore"` for **both QBCore and QBox** (QBox is QBCore-compatible), or `"ESX"` for ESX.                                                           |
| `TW.Locale`    | Panel language. 13 languages are built in: en, tr, de, fr, es, pt, ru, pl, nl, it, ro, ar, th (ไทย). Want another? See [Adding a Custom Language](#adding-a-custom-language). |
| `TW.AutoSql`   | When `true`, all database tables are created/migrated automatically on start. Set `false` only if you import `sql/install.sql` manually.                                      |

### Adding a Custom Language

The panel ships with 13 built-in languages. You can add your own **without editing the UI or rebuilding** — just two files inside the resource's `locales/` folder.

#### Step 1 — Create the translation file

Copy `locales/en.json` and rename it to your language code (ISO 639-1, e.g. `hu` for Hungarian):

```
locales/hu.json
```

Open it and translate the **values only** — never change the keys (the text on the left):

```json
{
  "header.hi": "Szia,",
  "header.onDuty": "Szolgálatban",
  "header.offDuty": "Szolgálaton kívül"
}
```

{% hint style="info" %}
Keep every key. Any value you leave in English simply shows in English — nothing breaks.
{% endhint %}

#### Step 2 — Register the language

Open `locales/custom_languages.json` and add an entry to the list so it appears in the picker:

```json
[
  { "code": "hu", "name": "Magyar" }
]
```

* `code` → must match your JSON filename (`hu` → `hu.json`)
* `name` → the label shown in the language menu (write it in the language itself)

Add more the same way:

```json
[
  { "code": "hu", "name": "Magyar" },
  { "code": "cs", "name": "Čeština" }
]
```

{% hint style="warning" %}

* **Don't list the built-in languages here** — they're always available.
* Only add a language whose `<code>.json` file exists, otherwise it shows up empty (falls back to English).
* Lines starting with `//` in that file are comments and are ignored.
  {% endhint %}

#### Step 3 — Apply

Restart `tw-adminmenu`, then open **Panel → Settings → Language** — your language is now selectable.

### Appearance

```lua
TW.DefaultTheme        = "dark"      -- "dark" | "gray" | "light"
TW.DefaultPrimaryColor = "#4189e5"   -- accent color (hex)
```

The **default** theme and accent color applied the first time an admin opens the panel. If an admin later changes them in **Settings → Appearance**, their personal choice (saved in their browser) overrides these defaults.

### Onboarding

```lua
TW.Onboarding = { enabled = true }
```

A short first-open setup (language + theme) and feature tour, shown **once per admin**. Set `enabled = false` to disable it entirely (everyone is treated as already onboarded).

### Access & Duty

```lua
TW.GodRole       = "owner"     -- role assigned to god identifiers
TW.GodIdentifiers = { }        -- 'fivem:xxx' / 'discord:xxx' get full access automatically
TW.DefaultOnDuty = false       -- admins join off-duty (recommended)
TW.OffDutyAccess = "full"      -- "full" | "readonly" | "duty"
```

| Setting             | What it does                                                                                                                                    |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `TW.GodRole`        | The top-tier role granted to god identifiers.                                                                                                   |
| `TW.GodIdentifiers` | Identifiers that always get full access on join — your owners/devs.                                                                             |
| `TW.DefaultOnDuty`  | `false` = admins must turn duty on manually (recommended); `true` = on-duty the moment they connect.                                            |
| `TW.OffDutyAccess`  | What an off-duty admin can do — `full` (everything, just shows offline), `readonly` (view only, no actions), or `duty` (nothing until on-duty). |

See [Permissions & Roles](/admin-menu/admin-menu/permissions) for the full role system.

### Whitelist

```lua
TW.WhitelistDefaultEnabled = false
TW.WhitelistKickReason = "This server is in whitelist mode. You are not authorized to join."
```

| Setting                      | What it does                                                                                                       |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `TW.WhitelistDefaultEnabled` | Whether whitelist mode is active on server boot. The in-game toggle is one-shot — a restart reverts to this value. |
| `TW.WhitelistKickReason`     | Message shown to non-whitelisted players when they're blocked at connect.                                          |

### Player Display

```lua
TW.PlayerNameMode = "fivem"        -- "fivem" | "character"
TW.HandcuffAllowWalk = true
TW.NotifyTargetOnAction = true
```

| Setting                   | What it does                                                                                                                        |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `TW.PlayerNameMode`       | How names show on the Online Players page — `character` (character name first, FiveM name in parentheses) or `fivem` (the reverse). |
| `TW.HandcuffAllowWalk`    | `true` = handcuffed players can walk slowly (no sprint/attack); `false` = fully locked in place.                                    |
| `TW.NotifyTargetOnAction` | `true` = the target player gets a pop-up when an admin acts on them (heal, freeze, jail, etc.); `false` = silent admin actions.     |

### Avatars & Phone

```lua
TW.AvatarSource = "discord"        -- "discord" | "steam" | "custom" | "none"
TW.PhoneSource = "metadata"        -- "metadata" | "custom" | "none"
TW.PhoneMetadataKey = "phone"
```

| Setting               | What it does                                                                                                                                                                                            |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TW.AvatarSource`     | Where player avatars come from. The chosen source is tried first, then falls back (e.g. `discord` → steam → placeholder). `discord`/`steam` need the matching API key/token set in `server_config.lua`. |
| `TW.AvatarCustom`     | Only used when `AvatarSource = "custom"` — an SQL table/column to read an avatar URL from.                                                                                                              |
| `TW.PhoneSource`      | How the player's phone number is resolved — `metadata` (reads framework metadata, works for ESX/qb-phone), `custom` (SQL lookup for gksphone/lb-phone/etc.), or `none` (hidden).                        |
| `TW.PhoneMetadataKey` | The metadata key the phone number is stored under (default `phone`).                                                                                                                                    |

***

### Economy

The economy block tells the panel **how your server stores money** so that balances display correctly and "set money" actions write to the right place. Configure it to match your framework/inventory.

```lua
TW.Currency = "$"   -- "$" | "€" | "₺" | "£" | "¥" | "₽" | "₹"
```

`TW.Currency` is just the symbol shown before every amount across the UI (PlayerDetail, RichList, invoices, set-money, etc.).

#### Cash & Dirty Money

```lua
TW.Cash = {
    mode = "account",                 -- "account" | "item" | "disabled"
    accountNames = { "cash", "money" },
    itemName = "cash",
}

TW.DirtyMoney = {
    mode = "account",
    accountNames = { "crypto", "black_money" },
    itemName = "black_money",
}
```

**Choosing `mode`:**

| Mode       | When to use it                                                                                                                                                             |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `account`  | **Most servers.** Money is a standard framework account (QBCore `PlayerData.money`, ESX `accounts`). This is the default.                                                  |
| `item`     | Your server tracks money as an **inventory item** (e.g. ox\_inventory item-as-cash, Renewed-Cash, marked bills). The panel reads/writes the item count via your inventory. |
| `disabled` | Hide this money type from the panel entirely.                                                                                                                              |

**`accountNames` (for `mode = "account"`):** the panel uses the **first matching name** in the list. Defaults cover QBCore and ESX out of the box (`cash`/`money`, `crypto`/`black_money`). If your server renamed the account, **put your custom name first** — e.g. `accountNames = { "dirty_money", "black_money" }`.

**`itemName` (for `mode = "item"`):** the inventory item name to read/write. Works automatically with whichever inventory system is active.

{% hint style="info" %}
**Quick guide:** Standard QBCore/ESX server? Leave everything on `account` — it just works. Using an item-based cash system? Switch `mode = "item"` and set `itemName`. Don't use dirty money at all? Set `TW.DirtyMoney.mode = "disabled"`.
{% endhint %}

***

### Integration Bridges (Auto-Detected)

Compatibility bridges for your other resources. Leave each on `"auto"` to detect the running script automatically, or pin an exact key to force a specific provider.

```lua
TW.InventorySystem        = "auto"   -- qb-inventory | ox_inventory | qs-inventory | codem-inventory | tgiann-inventory | origen_inventory | core_inventory | ps-inventory | chezza-inventory | esx
TW.WeatherSystem          = "auto"
TW.VehicleKeysSystem      = "auto"
TW.GarageSystem           = "auto"
TW.InvoicesSystem         = "auto"   -- qb-phone | g-billing | esx_billing | codem-billing | codem-billingv2 | codem-mphone | wasabi_billing | bablo-billing | okokBilling
TW.FuelSystem             = "auto"
TW.JailSystem             = "auto"
TW.ClothingSystem         = "auto"
TW.CommunityServiceSystem = "savana-communityservice"
```

{% hint style="warning" %}
For `"auto"` to work, the integration resource must start **before** `tw-adminmenu` in your `server.cfg`. If it starts after, pin the exact key here instead. (This is why `CommunityServiceSystem` is pinned by default — auto-detect would otherwise miss it.)
{% endhint %}

{% hint style="info" %}
**Custom adapters:** every bridge accepts `"custom"` — set it (e.g. `TW.JailSystem = "custom"`) and implement your own integration in the matching `bridge/<domain>/adapters/custom.lua`.
{% endhint %}

See the [supported systems table](/admin-menu/admin-menu#supported-systems) for every detectable provider.

### Garage, Dimensions & Dashboard

```lua
TW.GarageConfig = {
    defaultGarage = "pillboxgarage",   -- where "Send to Garage" puts vehicles
    impoundLot    = "impoundlot",      -- where "Impound" sends vehicles
    depotPrice    = 500,               -- impound retrieval fee
    perSystem = { --[[ per-garage-script overrides ]] },
}
```

The garage IDs **must match what your garage script actually uses**, or admin "Send to Garage / Impound" actions will assign vehicles to a garage that doesn't exist. The flat values are fallbacks; `perSystem` overrides them for specific garage scripts. Copy the real IDs from your garage script's own config if you renamed them.

```lua
TW.DimensionPresets = {
    { label = "Default World", value = 0 },
    { label = "Admin World",  value = 999 },
    { label = "Staff Area",   value = 500 },
}
```

Named routing buckets (dimensions) selectable in the player actions menu — handy for private staff areas or events.

```lua
TW.Dashboard = {
    serverJoinUrl = "cfx.re/join/abc123",   -- shown on the dashboard
    enableSystemMetrics = true,             -- CPU/RAM/tick monitoring
    historyRetentionDays = 30,              -- how long metric history is kept
    pushIntervalMs = 5000,                  -- how often live stats refresh
}
```

### Tickets, Chat, Noclip, Replay, Troll

```lua
TW.Chat.retentionDays = 7              -- how long chat history is stored
TW.Tickets.maxActivePerPlayer = 3      -- max open tickets a player can have

TW.Noclip.Speeds = { 15.0, 45.0, 100.0, 220.0, 450.0 }   -- noclip speed tiers (m/s)
TW.Noclip.SnapToGroundOnExit = true    -- drop to ground when leaving noclip

TW.Replay = {
    enabled = true,
    durationSec = 8,                   -- clip length
    cooldownSec = 90,                  -- min time between auto-clips
    autoCapture = true,                -- auto-record on triggers below
    triggers = { shooting = true, death = true },
}

TW.Troll.LocalSpawns = true            -- spawn troll entities only on the target's screen (anticheat-safe)
TW.Troll.SpawnTimeoutMs = 30000        -- auto-delete spawned entities after 30s
```

***

## shared/server\_config.lua

### API Keys

```lua
TW_Server.DiscordBotToken = ""   -- enables Discord avatars + member/role lookups
TW_Server.SteamApiKey     = ""   -- enables Steam avatars/profile data
```

{% hint style="warning" %}
Set `DiscordBotToken` for Discord avatars and role/member info to work. The token must belong to a bot that is a member of your Discord server. (This is separate from the standalone Discord bot — see [Discord Bot](/admin-menu/admin-menu/discord-bot).)
{% endhint %}

### File Exports

```lua
TW_Server.exportPublicHost = "http://YOUR_SERVER_IP:30120"
TW_Server.exportTtlSec     = 300       -- download link validity (seconds)
TW_Server.exportViaCloud   = true      -- serve exports via Tworst cloud CDN
```

Controls the temporary download links the panel generates for data exports (player data, logs, etc.).

### Mugshots & Voice

```lua
TW_Server.mugshotWebhook     = ""      -- Discord webhook for mugshots
TW_Server.ticketVoiceWebhook = ""      -- Discord webhook for ticket voice notes
```

### Live View (WebRTC Screen Watching)

```lua
TW_Server.liveViewDefaultPreset = "medium"   -- low | medium | high | extra | source
TW_Server.liveViewAudio = {
    enabled = true,                           -- false = disable player listening entirely
    radiusMeters = 15.0,                      -- proximity voice mix radius
}
```

`liveViewDefaultPreset` sets the starting stream quality (480p → native 60fps). `liveViewAudio` mixes in nearby in-game voices so you can hear what's happening around the player you're watching.

{% hint style="info" %}
Set `liveViewAudio.enabled = false` to **disable listening server-wide** — players are no longer prompted for mic access and admins see a "disabled" notice instead.
{% endhint %}

### Auto Web Permissions

```lua
-- Kept ABOVE the Cloud block on purpose so re-pairing (which replaces the Cloud
-- block) never wipes this setting.
TW_Server.autoWebPermissions = false   -- default false (opt-in)
```

When `true`, granting someone **in-game** staff (who has a Discord identifier) also gives them **web-panel access** with the same role — and editing/removing their in-game staff mirrors to the web. The link key is the Discord ID, and it's self-healing (existing admins are back-filled on their next connection). Manual web-only grants you added by hand in the panel are never touched. See [Web Panel → Invite Your Staff](/admin-menu/admin-menu/web-panel#step-3-invite-your-staff).

### Tworst Cloud Uplink

```lua
TW_Server.Cloud = {
    enabled = false,                          -- enable remote web panel access
    url = "wss://panel.tworst.com/agent",
    tenantId = "",                            -- from the panel's pairing snippet
    serverId = "",
    secret = "",
}
```

{% hint style="info" %}
Get `tenantId`, `serverId`, and `secret` from the pairing snippet in the web panel. Full steps in [Web Panel (Tworst Cloud)](/admin-menu/admin-menu/web-panel).
{% endhint %}

***

## shared/webhooks.lua

Route in-game admin logs to Discord. **Fill a webhook for every category you want logged** — anything blank falls back to `default`, and if `default` is also blank those logs go nowhere.

```lua
TW_Webhooks.enabled = true
TW_Webhooks.botName = "TW Admin Logs"
TW_Webhooks.botAvatar = ""

TW_Webhooks.urls = {
    punishments = "",   -- kicks, warns, jails, bans, CS, blacklist
    player      = "",   -- heal, freeze, teleport, model changes
    inventory   = "",   -- item give/remove, metadata edits
    economy     = "",   -- money changes
    vehicles    = "",   -- spawn, delete, repair, mods
    staff       = "",   -- role changes, job assignments, duty toggles
    server      = "",   -- exports, dashboard actions
    world       = "",   -- weather, time, freeze
    tickets     = "",   -- ticket create/claim/close
    ticketsOpen = "",   -- (optional) ticket OPEN events only
    ticketsClose= "",   -- (optional) ticket CLOSE events only (with transcript link)
    spectate    = "",   -- Live View, screenshots, spectate
    notes       = "",   -- player/vehicle notes
    troll       = "",   -- troll menu actions
    security    = "",   -- denied RPC / permission failures
    default     = "",   -- catch-all fallback
}
```

{% hint style="danger" %}
Leaving webhooks empty means those actions won't be logged. At minimum, set the `default` webhook so nothing is lost — then add dedicated channels for the categories you care most about (e.g. `punishments`, `economy`, `security`).
{% endhint %}

{% hint style="success" %}
Logs are posted as rich Discord embeds with color coding, timestamps, and actor/target details.
{% endhint %}

{% hint style="info" %}
**Ticket logging (no bot required):** Ticket open & close events — including a transcript link on close — post straight to Discord via these webhooks. Leave everything under `tickets` for one channel, or split them into two channels with `ticketsOpen` and `ticketsClose`.
{% endhint %}

***

## shared/open\_functions.lua

This file holds **integration hooks** — small functions that run at key moments so you can wire the Admin Menu into your server's other systems. Edit the function bodies; leave the signatures as they are.

### `AfterVehicleSpawn(vehicle, plate)`

Runs on the client right after an admin spawns a vehicle. Use it to hand the vehicle keys to your key system (or any post-spawn logic).

```lua
function TW.OpenFunctions.AfterVehicleSpawn(vehicle, plate)
    -- qb-vehiclekeys:
    TriggerEvent('vehiclekeys:client:SetOwner', plate)
    -- qs-vehiclekeys:   exports['qs-vehiclekeys']:GiveKeys(plate)
    -- wasabi_carlock:   exports.wasabi_carlock:GiveKey(plate)
end
```

### `OnSpectateStart(targetServerId)` / `OnSpectateStop(targetServerId)`

Run on the spectating admin's machine when spectate starts/stops — e.g. to hide a HUD or notify scripts while spectating.

```lua
function TW.OpenFunctions.OnSpectateStart(targetServerId)
    TriggerEvent('myhud:disable')
end
function TW.OpenFunctions.OnSpectateStop(targetServerId)
    TriggerEvent('myhud:enable')
end
```

### `OnNoclipStart()` / `OnNoclipStop()`

Run on the admin's machine when noclip is toggled — useful for whitelisting them in your anticheat or bypassing collision/zone scripts.

```lua
function TW.OpenFunctions.OnNoclipStart()
    exports['my-anticheat']:Whitelist(true)
end
function TW.OpenFunctions.OnNoclipStop()
    exports['my-anticheat']:Whitelist(false)
end
```

### `OpenClothingMenu(ped)`

Only used when `TW.ClothingSystem = "custom"`. Called when the Quick Action **Clothing** button is clicked, so you can open your own appearance script. (In the built-in modes — illenium/fivem/qb/esx — the bridge handles this and the hook is ignored.)

```lua
function TW.OpenFunctions.OpenClothingMenu(ped)
    exports.rcore_clothing:openClothing()
end
```

{% hint style="info" %}
The same spectate/noclip state can be read by other resources via exports/events — see [Features → Exports & Events](/admin-menu/admin-menu/features#exports-events).
{% endhint %}


# Permissions & Roles

The Admin Menu uses a **role-based permission system**. Each staff member has a role, and that role defines exactly what they can see and do — in-game, in the web panel, and from the Discord bot.

{% hint style="success" %}
Roles and permissions are shared across all three components. A "moderator" has the same powers whether they act in-game, on the web panel, or via Discord.
{% endhint %}

***

## Built-in Roles

The Admin Menu ships with 5 ready-to-use roles, ordered from highest to lowest rank:

| Role          | Rank    | Color  | Scope                                                |
| ------------- | ------- | ------ | ---------------------------------------------------- |
| **owner**     | Highest | Red    | Full access — manage staff, roles, and every feature |
| **admin**     | High    | Purple | Most features — can manage staff                     |
| **moderator** | Medium  | Blue   | Moderate players, view data                          |
| **support**   | Low     | Green  | Support & tickets focused                            |
| **trial**     | Lowest  | Yellow | View-only, no actions                                |

### Role Priority (Ranking)

Each role has a **priority** that determines its rank — a higher-priority role outranks a lower one (e.g. an admin can manage a moderator, but not the other way around).

{% hint style="info" %}
You don't edit priority numbers by hand. On the in-game **Admin → Roles** page, simply **drag roles up or down** to reorder them — the higher a role sits in the list, the higher its rank. The order applies everywhere (in-game, web panel, Discord bot).
{% endhint %}

{% hint style="info" %}
Built-in roles are **protected** — they can't be deleted, but you can reorder them and create custom roles alongside them.
{% endhint %}

***

## God Access

God access bypasses the role system entirely and grants full control — use it for owners and lead developers.

```lua
TW.GodRole = "owner"            -- The role assigned to god users
TW.GodIdentifiers = {
    "fivem:1234567",
    "discord:123456789012345",
}
```

Anyone whose `fivem:` or `discord:` identifier is listed in `TW.GodIdentifiers` is automatically provisioned with the God role and full access when they join.

{% hint style="warning" %}
Set up at least one god identifier during installation — it's how you bootstrap the first admin and start adding staff.
{% endhint %}

***

## Permission Groups

Permissions are organized into groups. A role grants any combination of permissions across these groups:

| Group                               | Covers                                                                    |
| ----------------------------------- | ------------------------------------------------------------------------- |
| **home**                            | Dashboard access                                                          |
| **player**                          | All player actions (kick, ban, teleport, heal, money, etc.)               |
| **vehicle**                         | Vehicle spawn, repair, mods, impound, delete                              |
| **server**                          | Console, commands, restart, stop, database backup                         |
| **admin**                           | Staff & role management                                                   |
| **resources**                       | View & manage server resources                                            |
| **logs**                            | View/delete logs, force duty                                              |
| **data**                            | Items, rich list, ban list, jail list, whitelist, exports, replays        |
| **tickets**                         | Ticket handling                                                           |
| **world**                           | Weather, time, world flags                                                |
| **events / polls / announcements**  | Engagement tools                                                          |
| **blips / jobs / teams / invoices** | Map markers, jobs, groups, billing                                        |
| **troll**                           | Troll menu actions                                                        |
| **quick menu**                      | Which Quick Actions / self-toggles (noclip, godmode, etc.) a role may use |
| **dashboard**                       | Server metrics & history                                                  |

***

## High-Risk Permissions

Certain permissions are flagged as **high-risk** and are always written to the audit log when used — for example: `command`, `ban`, `ip_ban`, `give_item`, `wipe_inventory`, `kill`, `set_money`, `edit_identity`, `live_view`, `restart`, `stop`, `manage_staff`, `manage_roles`, and `delete`.

{% hint style="info" %}
**`player.ip_ban`** is a separate permission from `ban`. Assign it to let a staff member optionally ban a player's **IP** alongside the normal ban.
{% endhint %}

{% hint style="info" %}
High-risk actions can also be routed to a dedicated Discord webhook channel — see [Configuration → webhooks](/admin-menu/admin-menu/configuration#shared-webhooks-lua).
{% endhint %}

***

{% hint style="info" %}
**Quick Menu permissions (auto-filled on update):** when this feature was added, existing roles were back-filled automatically — roles that already had risky permissions (ban, console, etc.) got the full Quick Menu set, others got a safe subset (coords, names, clothing, etc.). Adjust any of it in the role editor; **no manual SQL needed.**
{% endhint %}

## Custom Roles

From the in-game **Admin → Roles** page (or the web panel), users with `manage_roles` can:

* **Create** a new role with a custom permission matrix
* **Edit** a role's name, color, and permissions
* **Reorder** roles by dragging them up/down to set their rank
* **Delete** custom roles (built-in roles are protected)

Then, on the **Admin → Staff** page, assign roles to staff by identifier and optionally grant or revoke individual permissions to override the role.

***

## Off-Duty Access

Control what admins can do while off-duty:

```lua
TW.DefaultOnDuty = false      -- New admins start off-duty
TW.OffDutyAccess = "full"     -- "full" | "readonly" | "duty"
```

| Mode       | Behavior off-duty                               |
| ---------- | ----------------------------------------------- |
| `full`     | Full access regardless of duty status           |
| `readonly` | Can view everything, but cannot perform actions |
| `duty`     | Must go on-duty before using the menu           |


# Features

A complete reference of everything the Admin Menu can do. Every feature respects the [role permissions](/admin-menu/admin-menu/permissions) of the staff member using it.

***

## Dashboard

* Server status summary (online players, uptime)
* Real-time FPS, CPU, RAM, and event-loop metrics
* Recent logs feed with filtering
* Active staff list with duty status
* Quick server actions (restart, stop, toggle whitelist)

***

## Player Management

### Player Info

* Name, ID, identifiers (license, discord, steam, citizenid)
* Playtime, job & grade, first joined / last seen
* Avatar (Discord / Steam / custom) and phone number

### Actions

* **Punishment:** kick, warn, jail, community service, ban (temp/perm, optional IP ban), blacklist, unban, lift punishment
* **Movement:** teleport, bring, goto, dimension/bucket
* **Observation:** spectate, Live View (WebRTC), screenshots
* **Inventory:** give item, remove item, clear inventory, edit metadata
* **State:** heal, kill, freeze, handcuff, mute, strip weapons, reset stats, slap, explode
* **Appearance:** set model, reset skin, open clothing menu, edit identity
* **Economy:** set cash, set bank, set dirty money
* **Vehicle:** give vehicle keys
* **Records:** notes, warnings, full per-player action history

### Quick Actions (Hotbar)

Heal · Kill · Kick · Handcuff · Freeze · Strip Weapons · Teleport · Give Item · Open Clothing

***

## Vehicle Management

* Spawn any vehicle with custom plate + automatic keys
* Repair (engine, body, doors, windows, tires)
* Edit mods / wipe all mods
* Change plate, transfer to garage, impound, delete
* Vehicle notes & vehicle inventory explorer
* **Offline vehicle management** — grant or remove vehicles for a player even while they're offline (writes to their database record) via the Player Detail → Vehicles page

***

## Server Management

* Live console output + execute server commands
* Graceful restart / stop (with kick message)
* Enable/disable whitelist mode
* System metrics: live FPS, CPU %, RAM, per-resource CPU & memory
* Resource manager (view / start / stop / restart resources)
* **Database Backup** — take a full compressed backup on demand from the Server page, or schedule it to run automatically (guarded by its own permission)

***

## Staff, Logs & Data

### Staff & Roles

* Manage staff (add, change role, grant/revoke permissions, suspend, remove)
* Create & edit custom roles with priority and color

### Logs & Audit

* Comprehensive audit log (60+ event types) with search & filters
* Per-player and per-admin action history
* Duty-force logs

### Data Explorers

* **Item Explorer** — searchable item catalog (with live images from your inventory system) plus **Players / Vehicles / Storages** tabs showing exactly who or what holds an item, and a **Wipe from all** action
* **Rich List** — daily wealth snapshots & top players
* **Ban List** — active/expired, reason, appeals, evidence
* **Jail List** — currently jailed, release timers, bulk release
* **Community Service** — active assignments, bulk complete
* **Whitelist** — manage entries & toggle whitelist mode
* **Player Profiles** — searchable catalog of everyone who's joined

***

## Engagement Tools

* **Tickets** — categories, priority, claim/assign, internal notes, voice notes (open the ticket admin view with `/ticketadmin`)
* **Announcements** — broadcast info/warning/critical messages
* **Polls** — multi-option voting with live results
* **Events** — calendar with assignments and recurrence
* **Blips** — custom map markers (sprite, color, display mode)
* **Jobs & Grades** — view jobs, manage grades/salaries, assign jobs (Unemployed is assignable too)
* **Teams** — create groups, manage members, team notes
* **Invoices** — view/create invoices (qb-phone / g-billing)

***

## Monitoring & Observation

* **Live Player Monitor** — real-time player list with coordinates & filters; players on the same spot group into a single map marker
* **Spectate** — follow a player and see their view (toggle player ID/name tags with **N**)
* **Live View** — WebRTC screen watching with quality presets (480p → native 60fps) and proximity voice audio
* **Screenshots** — capture player screens (saved server-side / to Discord)
* **Mugshots** — Discord-posted mugshots
* **Replay Clips** — auto-record on death/gunfire (configurable), plus manual `/adminclip`

***

## Quick Actions (Self Toggles)

17 self toggles for admins:

Noclip (5 speed tiers) · Godmode · Invisibility · Show Names · Super Jump · Infinite Stamina · Fast Run · Auto Heal · Head Lights · Show Coords · Show Hitbox · Night Vision · No Ragdoll · Infinite Ammo · Entity Inspector · Duty Toggle

***

## Troll Menu

A collection of **39 fun actions** for events and light moderation, grouped below. Spawned entities can be kept local to the target's screen for safety.

| Type                 | Examples                                                                                                                                                                                                                                    |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **One-click pranks** | Ragdoll, screen shake, launch to sky, set on fire, flip vehicle, strip clothes, slow motion, super speed, confetti, nuke siren, break wheel, shockwave, ghost, clone circle, UFO kidnap, fart sounds                                        |
| **Composite**        | Force control (forward/back/jump), change model, attach prop, spawn animals, player size (shrink/enlarge)                                                                                                                                   |
| **Toggles**          | Drunk mode, magnet mode, upside-down cam, mirror controls, snow weather, ultra fog, disable lights, low gravity, random time, door spam, FOV oscillator, flicker invisible, ultra slow walk, low poly, fake lag, clone follow, 2D game mode |

```lua
TW.Troll.LocalSpawns = true        -- Spawn entities only on the target's screen (anticheat-safe)
TW.Troll.SpawnTimeoutMs = 30000    -- Auto-clean spawned entities after 30s
```

{% hint style="warning" %}
Troll actions are powerful and visible to players. Restrict the `troll` permission group to trusted staff and keep `LocalSpawns` enabled to avoid anticheat issues.
{% endhint %}

***

## Exports & Events

The script exposes a few client exports/events for integration:

```lua
exports['tw-adminmenu']:IsSpectating()        -- boolean
exports['tw-adminmenu']:GetSpectateTarget()   -- targetServerId | nil
exports['tw-adminmenu']:IsNoclipping()        -- boolean
```

Events: `tw-admin:spectate:started` · `tw-admin:spectate:stopped` · `tw-admin:noclip:started` · `tw-admin:noclip:stopped`


# Web Panel (Tworst Cloud)

**Tworst Cloud** is a cloud-hosted web panel that mirrors your in-game Admin Menu in the browser. Manage your server from anywhere — the same players, bans, logs, tickets, and tools you have in-game, in real time.

{% hint style="success" %}
Nothing to host or deploy. Tworst Cloud runs at [panel.tworst.com](https://panel.tworst.com) — you simply pair your server and log in.
{% endhint %}

{% hint style="info" %}
Prefer to work without leaving Discord? The same panel is available as a [**Discord Activity**](/admin-menu/admin-menu/discord-activity) — open it right inside a voice channel.
{% endhint %}

***

## How It Works

The panel connects to your FiveM server through a secure uplink built into the `tw-adminmenu` resource. Once paired:

* Your server pushes live state (players, stats, logs) to the panel
* Admin actions you take in the browser are sent back to your server and executed
* Everything respects the **same roles and permissions** as the in-game menu

***

## Step 1: Pair Your Server

1. Log in to [panel.tworst.com](https://panel.tworst.com) with **Discord**
2. Click **Add Server** — the panel generates a pairing snippet containing your `tenantId`, `serverId`, and `secret`
3. Open `shared/server_config.lua` on your server and paste the values into the Cloud block:

```lua
TW_Server.Cloud = {
    enabled = true,                          -- turn the uplink on
    url = "wss://panel.tworst.com/agent",
    tenantId = "your-tenant-id",             -- from the pairing snippet
    serverId = "your-server-id",
    secret = "your-pairing-secret",
}
```

4. Restart `tw-adminmenu` (or your server)
5. Back on the panel, your server should now show as **connected**

{% hint style="warning" %}
The pairing **secret** is shown only once. Keep it private — treat it like a password. If you lose it, generate a new one from the panel.
{% endhint %}

***

## Step 2: Log In

Tworst Cloud uses **Discord login**. Sign in with the Discord account you want to own the workspace — you'll land on your dashboard with your paired server(s).

***

## Step 3: Invite Your Staff

1. In the panel, open **Staff**
2. Invite a team member by their **Discord ID**
3. Assign them a role (or custom permissions)

When that person logs in with Discord, they get exactly the access their role allows — the same permissions they'd have in-game.

{% hint style="success" %}
**Auto web permissions (opt-in):** Set `TW_Server.autoWebPermissions = true` and anyone you make **in-game** staff (with a Discord ID) automatically gets matching web-panel access — no need to add them here by hand. Editing/removing their in-game staff mirrors to the web too. Manual grants you add in the panel are always preserved. See [Configuration → Auto Web Permissions](/admin-menu/admin-menu/configuration#auto-web-permissions).
{% endhint %}

The **Staff** list shows each admin's web-access state at a glance: 🟢 has access & has signed in · 🟡 granted but not yet signed in · ⚪ no web access.

{% hint style="info" %}
Staff roles and permissions are shared between the in-game menu, the web panel, and the Discord bot. Manage them once; they apply everywhere.
{% endhint %}

***

## What You Can Do in the Panel

The web panel mirrors the in-game menu. Main sections include:

| Section           | Description                                          |
| ----------------- | ---------------------------------------------------- |
| **Dashboard**     | Live server stats, uptime, resource health           |
| **Players**       | Online players + actions (kick, ban, spectate, etc.) |
| **Player Detail** | Per-player info, inventory, jobs, records            |
| **Vehicles**      | Spawned vehicles & details                           |
| **Bans**          | Ban management (revoke, edit, blacklist)             |
| **Logs**          | Searchable server audit logs                         |
| **Tickets**       | Support ticket queue                                 |
| **Staff**         | Manage admins, roles & permissions                   |
| **Monitor**       | Real-time player activity                            |
| **Live View**     | In-game camera / spectate feed                       |
| **Console**       | Execute commands (if permitted)                      |
| **Announcements** | Broadcast messages to the server                     |
| **Polls**         | Create in-game polls                                 |
| **Blips**         | Manage map markers                                   |
| **Rich List**     | Player wealth rankings                               |
| **Jobs**          | Active jobs & grades                                 |
| **Teams**         | Factions / groups                                    |
| **Events**        | Event calendar                                       |
| **Whitelist**     | Whitelist management                                 |
| **Replays**       | Incident recordings                                  |

{% hint style="success" %}
**Real-time:** Every connected admin sees the same live data instantly. Actions taken in the browser apply on the server within moments.
{% endhint %}

***

## Multi-Server

You can pair more than one server to the same workspace and switch between them in the panel — useful if you run multiple servers or a test environment.

***

## Need Help?

{% hint style="info" %}
Pairing trouble or panel questions? Join our [Discord server](https://discord.gg/tworst) and open a support ticket. Make sure `TW_Server.Cloud.enabled = true` and your `tenantId` / `serverId` / `secret` match the pairing snippet exactly.
{% endhint %}


# Discord Activity

The **Tworst Admin Discord Activity** lets you open the full Tworst Admin web panel **directly inside Discord** — right in a voice channel, no browser needed. It's the same panel as [panel.tworst.com](https://panel.tworst.com), embedded in Discord, so you can moderate and manage your FiveM server without leaving your voice call.

{% hint style="success" %}
Same panel, same permissions — just launched inside Discord. You sign in automatically with your Discord account; no password is shared.
{% endhint %}

***

## Requirements

Before using the Activity, make sure:

* You own an active Tworst Admin license and your FiveM server is **connected to the panel** (see [Web Panel (Tworst Cloud)](/admin-menu/admin-menu/web-panel)).
* You have signed in to [panel.tworst.com](https://panel.tworst.com) **with Discord** at least once — the Activity logs you in using that same Discord account. If your Discord account isn't a registered Tworst account with access to a server, the Activity won't load your panel.
* You have the **Manage Server** permission in the Discord server (needed to add the app the first time).
* You're on Discord **desktop, mobile, or web** (Activities are supported on all three).

***

## Step 1: Add the Activity to Your Discord Server

1. Open this install link:

   ```
   https://discord.com/oauth2/authorize?client_id=1508572621007093912
   ```
2. Choose **Add to Server** and select the Discord server you want.
3. Confirm/authorize. The **Tworst Admin** app is added to that server.

{% hint style="info" %}
You only need to do this **once per server**. The app is public — everyone uses the same install link.
{% endhint %}

***

## Step 2: Launch the Activity

1. Join any **voice channel** in that server.
2. Open the **Activity launcher** (the rocket / "Activities" icon in the voice channel controls).
3. Find and select **Tworst Admin Menu**.
4. The panel opens inside Discord.

***

## Step 3: Sign In (Automatic)

* The first time, Discord asks you to authorize the app — tap **Authorize**.
* The Activity then signs you in automatically with your Discord account and loads your dashboard. **No password needed.**
* If you have access to more than one server, pick the one you want to manage from the built-in server picker.

***

## Using the Panel

Once loaded, you get the full admin panel — player moderation, server monitoring, teams, whitelist, and every other tool — scoped to the server you selected. It behaves exactly like [panel.tworst.com](/admin-menu/admin-menu/web-panel), and respects the [same roles and permissions](/admin-menu/admin-menu/permissions) as the in-game menu.

***

## Troubleshooting

### The Activity isn't in the launcher

Make sure the app was **added to the server** (Step 1) and that you're **inside a voice channel**. Try reopening the activity launcher.

### It loads but won't log me in / shows no server

Your Discord account must be a **registered Tworst account with server access**. Sign in to [panel.tworst.com](https://panel.tworst.com) with Discord first, and make sure you have a license (or are added as staff on a server).

### Blank screen or stuck loading

Close the Activity and relaunch it.

### Wrong server shown

Use the **server picker** inside the Activity to switch servers.

***

## Notes

* The Activity is the same secure panel as the browser version — your session stays inside Discord and no password is shared.
* Works on Discord **Desktop, Web, and Mobile**.

{% hint style="info" %}
Need help? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Discord Bot

The **Tworst Admin Bot** lets your staff run admin actions and receive live logs directly from Discord. It connects to your server through Tworst Cloud and enforces the **same roles and permissions** as the in-game menu.

{% hint style="info" %}
The bot is **open-source and self-hosted** — you run it on your own machine/VPS and connect it to **your own** Discord bot application. You're in full control of the token and hosting.
{% endhint %}

***

## What It Does

* **Remote player admin** — kick, ban, warn, jail, freeze, heal, revive, give items/money, and more (via slash commands)
* **Server info** — live status, online player list
* **Announcements** — broadcast to the server from Discord
* **Bans & whitelist** — manage bans and whitelist entries
* **Event logging** — post event announcements to your channels
* **Role sync (optional)** — mirror in-game staff roles to Discord roles, bidirectionally
* **5 languages** — EN, TR, DE, FR, ES

{% hint style="info" %}
**Ticket logging** is handled in-game via Discord webhooks (Admin Menu v1.0.3+), not by the bot. See [Admin Menu → Configuration](/admin-menu/admin-menu/configuration#shared-webhooks-lua).
{% endhint %}

***

## How It Connects

```
Discord  ──▶  Tworst Admin Bot  ──▶  Tworst Cloud  ──▶  Your FiveM server
                                                          (tw-adminmenu)
```

The bot talks to your server through the same Tworst Cloud uplink the web panel uses. Every action carries the Discord user's identity, so the server enforces **that user's in-game staff permissions** — there's no separate permission list to maintain.

***

## Prerequisites

| Requirement                      | Notes                                                                                                |
| -------------------------------- | ---------------------------------------------------------------------------------------------------- |
| **Node.js 20+**                  | Required to run the bot                                                                              |
| **A Discord application**        | Your own bot token (free, created at the Discord Developer Portal)                                   |
| **A paired Tworst Cloud server** | The bot uses your cloud credentials — set up the [Web Panel](/admin-menu/admin-menu/web-panel) first |
| **Hosting**                      | Any machine/VPS that can stay online 24/7                                                            |

{% hint style="info" %}
You download the bot's source code from its GitHub repository: [github.com/tworst46/twadminmenu\_bot](https://github.com/tworst46/twadminmenu_bot)
{% endhint %}

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Setup</strong></td><td>Step-by-step self-host guide</td><td><a href="/pages/2vIGcj8qWKhkiQI06fDC">/pages/2vIGcj8qWKhkiQI06fDC</a></td></tr><tr><td><strong>Configuration</strong></td><td>Full .env reference</td><td><a href="/pages/IaX7scihVbNfxW5C56yh">/pages/IaX7scihVbNfxW5C56yh</a></td></tr><tr><td><strong>Commands</strong></td><td>All slash commands</td><td><a href="/pages/0yUPZNYa3qmyErJqFIRX">/pages/0yUPZNYa3qmyErJqFIRX</a></td></tr></tbody></table>


# Setup

A step-by-step guide to self-host the Tworst Admin Bot and connect it to your server.

{% hint style="info" %}
Set up the [Web Panel (Tworst Cloud)](/admin-menu/admin-menu/web-panel) first — you'll need your cloud credentials (`tenantId`, `serverId`, bot `secret`) to connect the bot.
{% endhint %}

***

## Step 1: Create a Discord Application & Bot

1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)
2. Click **New Application**, give it a name (e.g. "TW Admin Bot")
3. Open the **Bot** tab → **Reset/Copy Token** → this is your `DISCORD_BOT_TOKEN`
4. Copy the **Application ID** from the **General Information** tab → this is your `DISCORD_BOT_CLIENT_ID`

***

## Step 2: Invite the Bot to Your Server

1. In the application, open **OAuth2 → URL Generator**
2. Select scopes: **`bot`** and **`applications.commands`**
3. Select bot permissions: **Manage Roles**, **Manage Channels**, **Send Messages**, **Embed Links**, **Read Message History**, **Mention @everyone, @here, and All Roles**
4. Open the generated URL, pick your Discord server, and authorize

{% hint style="info" %}
**Manage Roles / Manage Channels** are only needed if you plan to use role sync and the event/ticket logging features. You can grant a narrower set if you don't.
{% endhint %}

***

## Step 3: Get Your Tworst Cloud Credentials

From [panel.tworst.com](https://panel.tworst.com), open your server's settings and note:

* **Tenant ID** (`BOT_TENANT_ID`)
* **Server ID** / slug (`BOT_SERVER_ID`)
* **Bot Secret** (`BOT_SECRET`)

***

## Step 4: Download & Install

```bash
git clone https://github.com/tworst46/twadminmenu_bot
cd twadminmenu_bot
npm install
```

***

## Step 5: Configure `.env`

Copy the example and fill in your values:

```bash
cp .env.example .env
```

At minimum, set:

```
DISCORD_BOT_TOKEN=your-bot-token
DISCORD_BOT_CLIENT_ID=your-application-id
BOT_AGENT_URL=wss://panel.tworst.com/bot
BOT_SECRET=your-cloud-bot-secret
BOT_TENANT_ID=your-tenant-id
BOT_SERVER_ID=your-server-slug
```

See [Configuration](/admin-menu/admin-menu/discord-bot/configuration) for every available option (role sync, event/ticket channels, language, etc.).

***

## Step 6: Register Slash Commands

```bash
npm run deploy-commands
```

This registers all `/` commands with Discord. Guild-scoped commands appear instantly.

***

## Step 7: Start the Bot

```bash
npm start
```

You should see output similar to:

```
[bot] tw-adminmenu Discord Bot starting...
[bot] Agent bridge connecting...
[bot] Discord ready as YourBotName#0000
[bot] Bot is running. Press Ctrl+C to stop.
```

Test it by running **`/status`** in your Discord server — you should see your server's live status.

***

## Step 8 (Optional): Channels & Role Sync

* **Event announcements:** create a channel, then run `/event-channel set #events`
* **Role sync:** set `BOT_ROLE_SYNC=1` and `BOT_GUILD_ID` in `.env`, restart, then run `/sync`

{% hint style="info" %}
**Ticket logs** are configured in-game, not via the bot — set the ticket webhooks in `shared/webhooks.lua`. See [Admin Menu → Configuration](/admin-menu/admin-menu/configuration#shared-webhooks-lua).
{% endhint %}

***

## Hosting Tips

{% hint style="info" %}
The bot must stay running 24/7. For production, run it on a VPS with a process manager (e.g. `pm2`) so it restarts automatically. Running it on your PC only works while that PC is on.
{% endhint %}

***

## Troubleshooting

### Bot won't start

* Confirm `.env` is in the project root with all required fields filled in
* Check Node.js version: `node --version` (must be 20+)
* Make sure `npm install` finished without errors

### Bot online but commands fail / "not connected"

* Double-check `BOT_SECRET`, `BOT_TENANT_ID`, `BOT_SERVER_ID`
* Confirm your server is paired and **connected** in the web panel
* Set `BOT_DEBUG_BRIDGE=1` for verbose connection logs

### Slash commands don't appear

* Run `npm run deploy-commands` again
* Global commands can take up to an hour to propagate; guild-scoped are instant

### Role sync not working

* Ensure `BOT_ROLE_SYNC=1` and `BOT_GUILD_ID` are set, then restart
* Make sure the bot has **Manage Roles** permission and its role is high enough in the Discord role list
* Run `/sync` to trigger a manual sync

***

## Need Help?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with your console output (enable `BOT_DEBUG_BRIDGE=1` first).
{% endhint %}


# Configuration

The bot is configured through a `.env` file in the project root. Some settings can also be changed at runtime with slash commands (they persist to the `data/` folder).

***

## Environment Variables

### Required

| Variable                | Description                                                  |
| ----------------------- | ------------------------------------------------------------ |
| `DISCORD_BOT_TOKEN`     | Your Discord bot token (Developer Portal → Bot)              |
| `DISCORD_BOT_CLIENT_ID` | Your Discord application ID (for registering slash commands) |
| `BOT_AGENT_URL`         | Tworst Cloud bot endpoint — `wss://panel.tworst.com/bot`     |
| `BOT_SECRET`            | Bot secret from your Tworst Cloud server settings            |
| `BOT_TENANT_ID`         | Your tenant ID from the dashboard                            |
| `BOT_SERVER_ID`         | Your server slug (set when you created the server)           |

### Role / Staff Sync (Optional)

| Variable          | Default | Description                                                                             |
| ----------------- | ------- | --------------------------------------------------------------------------------------- |
| `BOT_ROLE_SYNC`   | `0`     | `1` enables bidirectional role mirroring + `/sync`, `/teamsync`, `/setrole`, `/unstaff` |
| `BOT_GUILD_ID`    | —       | Discord server ID where roles are synced (required when sync is on)                     |
| `BOT_ROLE_PREFIX` | `TW \|` | Prefix for synced roles (e.g. "TW \| Admin")                                            |

### Events (Optional)

| Variable                    | Default | Description                                                   |
| --------------------------- | ------- | ------------------------------------------------------------- |
| `BOT_EVENT_CHANNEL_ID`      | —       | Channel for event announcements (or set via `/event-channel`) |
| `BOT_EVENT_MENTION_ROLE_ID` | —       | Role to mention on event posts                                |
| `BOT_EVENT_DM_STAFF`        | `1`     | `0` = DM each staff member on events, `1` = channel-only      |

{% hint style="info" %}
**Ticket logging is no longer handled by the bot.** As of Admin Menu v1.0.3, ticket open/close logs are posted directly from the game via `shared/webhooks.lua` (`tickets` / `ticketsOpen` / `ticketsClose`) — no bot required. See [Configuration → webhooks](/admin-menu/admin-menu/configuration#shared-webhooks-lua).
{% endhint %}

### Other (Optional)

| Variable           | Default | Description                                                            |
| ------------------ | ------- | ---------------------------------------------------------------------- |
| `BOT_LOCALE`       | `en`    | Bot language: `en`, `tr`, `de`, `fr`, `es` (or change via `/language`) |
| `BOT_DEBUG_BRIDGE` | `0`     | `1` = verbose WebSocket logging (troubleshooting only)                 |

***

## Role Sync Explained

By default (`BOT_ROLE_SYNC=0`) the bot only provides moderation/info commands. Setting **`BOT_ROLE_SYNC=1`** unlocks:

* **Bidirectional mirroring** — assign an in-game staff role and the matching Discord role is applied automatically, and vice-versa
* **`/sync`** — perform a full role sync and view current mappings
* **`/teamsync`** — sync Discord team members with in-game teams
* **`/setrole`** / **`/unstaff`** — manage in-game staff directly from Discord

Synced Discord roles are named using `BOT_ROLE_PREFIX` (e.g. `TW | Admin`). Leave sync off if you don't want Discord to control in-game staff.

***

## Runtime Configuration

These settings are stored in the `data/` folder and can be changed without editing `.env`:

| File                     | Set via          | Stores                           |
| ------------------------ | ---------------- | -------------------------------- |
| `data/bot-config.json`   | `/language set`  | Bot language                     |
| `data/event-config.json` | `/event-channel` | Event channel + mention role     |
| `data/role-mapping.json` | auto (role sync) | Game role → Discord role mapping |

These files are created automatically on first use. Delete them to reset to your `.env` defaults.

***

## Permissions Model

{% hint style="success" %}
The bot does **not** use a separate allowlist. Action commands are authorized by the **in-game staff role** of the Discord user who runs them. If a user isn't staff (or lacks the permission) in-game, the action is denied.
{% endhint %}

The only exceptions are the configuration commands (`/language`, `/event-channel`), which require the Discord **Manage Server** permission.

***

## `.env.example` Reference

```env
# --- Discord Bot ---
DISCORD_BOT_TOKEN=
DISCORD_BOT_CLIENT_ID=

# --- Tworst Cloud Connection ---
BOT_AGENT_URL=wss://panel.tworst.com/bot
BOT_SECRET=
BOT_TENANT_ID=
BOT_SERVER_ID=

# --- Role / Staff Sync (optional, off by default) ---
BOT_ROLE_SYNC=0
BOT_GUILD_ID=
BOT_ROLE_PREFIX=TW |

# --- Events (optional) ---
BOT_EVENT_CHANNEL_ID=
BOT_EVENT_MENTION_ROLE_ID=
BOT_EVENT_DM_STAFF=1

# --- Bot Language (optional) ---
BOT_LOCALE=en

# --- Debug (optional) ---
BOT_DEBUG_BRIDGE=0
```


# Commands

All slash commands provided by the Tworst Admin Bot, grouped by category.

{% hint style="info" %}
Every action command is authorized by the Discord user's **in-game staff role**. If a user lacks the permission in-game, the command is denied. Commands marked **(role sync)** require `BOT_ROLE_SYNC=1`.
{% endhint %}

***

## Server

| Command                      | Description                                          |
| ---------------------------- | ---------------------------------------------------- |
| `/status`                    | Show server status (player count, uptime, health)    |
| `/players`                   | List online players (name, ID, ping)                 |
| `/announce <message> [type]` | Send a server announcement (banner / popup / toast)  |
| `/sync`                      | Sync game roles & staff with Discord **(role sync)** |

***

## Player Moderation

| Command                             | Description                      |
| ----------------------------------- | -------------------------------- |
| `/kick <player> [reason]`           | Kick a player                    |
| `/ban <player> <reason> [duration]` | Ban a player (temp or permanent) |
| `/unban <player> [reason]`          | Unban a player                   |
| `/warn <player> <reason>`           | Warn a player                    |
| `/jail <player> [time]`             | Jail a player                    |
| `/unjail <player>`                  | Release a jailed player          |
| `/freeze <player>`                  | Freeze a player                  |
| `/unfreeze <player>`                | Unfreeze a player                |
| `/stripweapons <player>`            | Remove all weapons from a player |

***

## Player Actions

| Command                               | Description                        |
| ------------------------------------- | ---------------------------------- |
| `/heal <player>`                      | Heal a player to full HP           |
| `/revive <player>`                    | Revive a downed/dead player        |
| `/kill <player>`                      | Kill a player                      |
| `/slap <player> [force]`              | Slap a player (knockback)          |
| `/explode <player>`                   | Explode a player                   |
| `/giveitem <player> <item> [count]`   | Give an inventory item             |
| `/givemoney <player> <amount> [type]` | Give cash or bank money            |
| `/givemodel <player> <model>`         | Change a player's model/appearance |

***

## Vehicle

| Command                          | Description                     |
| -------------------------------- | ------------------------------- |
| `/spawnvehicle <player> <model>` | Spawn a vehicle for a player    |
| `/vlookup <model>`               | Look up a vehicle by model name |

***

## Information

| Command            | Description                           |
| ------------------ | ------------------------------------- |
| `/banlist [limit]` | Show recent bans (default 10, max 25) |
| `/lookup <player>` | Fetch detailed player information     |

***

## Teams

| Command                        | Description                                                  |
| ------------------------------ | ------------------------------------------------------------ |
| `/teamlist`                    | List all active teams with stats                             |
| `/teaminfo <team_id>`          | Show detailed team info                                      |
| `/teamadd <team_id> <user>`    | Add a Discord user to a team                                 |
| `/teamremove <team_id> <user>` | Remove a Discord user from a team                            |
| `/teamsync`                    | Sync Discord team members with in-game teams **(role sync)** |

***

## Whitelist

| Command                                                     | Description                          |
| ----------------------------------------------------------- | ------------------------------------ |
| `/whitelistadd [identifier] [discord_user] [name] [reason]` | Add to whitelist                     |
| `/whitelistlist [limit]`                                    | Show whitelisted identifiers         |
| `/whitelistremove <identifier>`                             | Remove from whitelist                |
| `/whitelistmode <enabled>`                                  | Enable/disable whitelist enforcement |

***

## Events

| Command                           | Description                                             |
| --------------------------------- | ------------------------------------------------------- |
| `/events [status]`                | List events (upcoming / active / completed / cancelled) |
| `/event-detail <event_id>`        | Show detailed event info                                |
| `/event-channel <set\|show\|off>` | Configure the event announcement channel                |

***

## System

| Command                 | Description                                         |
| ----------------------- | --------------------------------------------------- |
| `/language <set\|show>` | Change or display the bot language (en/tr/de/fr/es) |

***

## Staff Management (role sync)

| Command                  | Description                                                    |
| ------------------------ | -------------------------------------------------------------- |
| `/setrole <user> <role>` | Assign an in-game staff role to a Discord user **(role sync)** |
| `/unstaff <user>`        | Remove a Discord user from staff **(role sync)**               |

{% hint style="info" %}
`/language` and `/event-channel` require the Discord **Manage Server** permission. All other commands rely on your in-game staff permissions.
{% endhint %}

{% hint style="info" %}
**Ticket logging** is handled in-game via Discord webhooks (Admin Menu v1.0.3+), not by the bot — the `/ticket-channel` command was removed. See [Admin Menu → Configuration](/admin-menu/admin-menu/configuration#shared-webhooks-lua).
{% endhint %}


# Changelog

Version history and updates for the Tworst Admin Menu.

***

## Current Version: 1.1.3

{% hint style="success" %}
You are using the latest version of Tworst Admin Menu.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-adminmenu**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `shared/config.lua`
   * Save your `shared/server_config.lua`
   * Save your `shared/webhooks.lua`
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.1.3

## New

* **Custom integration adapters for every bridge** — set any system to `"custom"` and write your own in `bridge/<domain>/adapters/custom.lua`.
* **Quick Menu permissions** — control which Quick Actions each role may use.
* Item Explorer → **"Wipe from all"**.
* **okokBilling** and **rcore\_prison** support.
* qs-inventory: vehicle trunk & glovebox editing.
* Map: players on the same spot now group into one marker.
* Spectate: player ID/name tags (toggle with **N**).
* Unemployed is now assignable.

## Fixes

* qs-advancedgarages send to garage / impound.
* Admin menu double-press after spectate.
* General hardening.

{% hint style="info" %}
**Quick Menu permissions are auto-filled on update.** Roles that already had risky permissions (ban, console, etc.) get the full set; others get a safe subset (coords, names, clothing, etc.). Adjust in the role editor — **no manual SQL needed.**
{% endhint %}

{% hint style="warning" %}
**Keep your own `shared/server_config.lua`, `shared/config.lua` & `shared/webhooks.lua`** when updating. Replace the whole `ui/dist/` folder and the other changed files.
{% endhint %}

## Changed Files

* **New:** `bridge/*/adapters/custom.lua` (all domains), `bridge/inventory/custom.lua`
* **New:** `bridge/invoices/adapters/okokbilling.lua`, `bridge/jail/adapters/rcore-prison.lua`
* **New:** `sql/migrations/006_add_quickmenu_perms.sql`
* `fxmanifest.lua`, `shared/config.lua`, `shared/permissions.lua`, `sql/install.sql`
* `bridge/registry.lua`, `bridge/garage/providers.lua`, `bridge/inventory/qs-inventory.lua`
* `bridge/clothing/adapters/custom.lua`, `bridge/revive/system.lua`
* `client/main.lua`, `client/quickActions.lua`, `client/spectate.lua`
* `server/helpers.lua`, `server/auth/manager.lua`, `server/cloud/handlers.lua`
* `server/core/{qbcore,esx}/jobs.lua`
* `server/data/items/{system,handlers}.lua`, `server/data/playerblips/handlers.lua`, `server/data/quick_actions/defaults.lua`
* `locales/*.json` (all 13)
* `ui/dist/**` (replace the whole folder)


# v1.1.2

## New

* **QBox** support.
* `/ticketadmin` command.

## Fixes

* ox\_inventory: Item Explorer, Give Item and item lookups fixed.
* Admin menu double-press after spectate.
* General hardening.

{% hint style="warning" %}
**Keep your own `shared/server_config.lua`, `shared/config.lua` & `shared/webhooks.lua`** when updating. Replace the whole `ui/dist/` folder and the other changed files.
{% endhint %}

## Changed Files

* `fxmanifest.lua`
* `bridge/inventory/ox-inventory.lua`
* `client/main.lua`, `client/spectate.lua`
* `server/auth/handlers.lua`, `server/auth/helpers.lua`
* `server/cloud/handlers.lua`
* `server/core/qbcore/jobs.lua`
* `server/data/console/handlers.lua`
* `server/data/export/system.lua`
* `server/data/tickets/transcript.lua`
* `ui/dist/**` (replace the whole folder)


# v1.1.1

## New

* **IP ban** — optionally ban a player's IP too (permission-gated: `player.ip_ban`).
* **Live View listening can be disabled per-server** (config) — when off, players aren't prompted for mic access and admins get a "disabled" notice.

## Fixes & Improvements

* Live View "target offline" on busy servers — players now resolve reliably.
* Live View relay hardening (fewer black screens on strict networks).
* Localization updates across all 13 languages.

{% hint style="warning" %}
**Keep your own `shared/server_config.lua`, `shared/config.lua` & `shared/webhooks.lua`** when updating. Replace the whole `ui/dist/` folder (rebuilt) and the other changed files.
{% endhint %}

## Config

* `server_config.lua` → `liveViewAudio.enabled = false` to disable player listening.
* **AddBan:** new `player.ip_ban` permission — assign it in-game to allow IP bans.

## Changed Files

* `fxmanifest.lua`, `shared/permissions.lua`
* `client/liveview.lua`
* `server/ban/{handlers,system}.lua`
* `server/cloud/handlers.lua`
* `server/core/{esx,qbcore}/player.lua`
* `server/data/liveview/system.lua`
* `locales/*.json` (all 13)
* `ui/dist/**` (rebuilt — replace the whole `ui/dist` folder)


# v1.1.0

## New

* **Auto web-panel access** — grant staff in-game, they get panel access automatically (opt-in, `TW_Server.autoWebPermissions`).
* Staff list shows each admin's web-access status at a glance (🟢 signed in · 🟡 granted, not signed in · ⚪ none).
* New integrations: **AV Weather** · **Randol** community service · **Bablo** billing.
* **Offline vehicle management** — grant/remove vehicles for offline players.
* Item Explorer: storage view + cleaner large-number formatting.

## Fixes & Improvements

* Ticket alerts: no duplicates, correct ticket number, richer info on web.
* Codem inventory: vehicle trunk/glovebox items now shown.
* Jail, garage & several framework bridges hardened.
* Thai language + updates across all 13 locales.

{% hint style="warning" %}
**Keep your own `shared/server_config.lua` & `shared/config.lua`** when updating. Replace `ui/dist/**` (rebuilt) and the other changed files.
{% endhint %}

## Config

`shared/server_config.lua` gained `TW_Server.autoWebPermissions` (default `false`), placed **above** the `Cloud` block so re-pairing the cloud no longer wipes it.

## Changed Files

* **New:** `bridge/communityservice/adapters/randol_service.lua`, `randol_service_client.lua`
* **New:** `bridge/invoices/adapters/bablo-billing.lua`
* **New:** `bridge/world/adapters/av_weather.lua`
* `fxmanifest.lua`, `bridge/registry.lua`
* `bridge/clothing/adapters/illenium-appearance.lua`
* `bridge/communityservice/{handlers,system}.lua`
* `bridge/garage/{facade,providers}.lua`
* `bridge/inventory/codem-inventory.lua`
* `bridge/jail/**` (pickle-prisons, qb-prison, client, handlers, system)
* `client/{trollDefaults,vehicles}.lua`
* `server/auth/handlers.lua`, `server/cloud/{handlers,uplink}.lua`
* `server/core/**` (esx/vehicles, qbcore/{queries,sync\_hooks,vehicles})
* `server/data/{tickets,vehicles}/handlers.lua`, `server/player/actions.lua`
* `locales/*.json` (all 13)
* `ui/dist/**` (rebuilt — replace)


# v1.0.9

## Added

* **Database Backup** — take a full backup from the panel (Server page), or let it run automatically. Compressed, with its own permission.
* **Item Explorer: new "Storages" tab** — see which stashes hold an item, next to Players and Vehicles.
* **Custom languages** — add your own language without touching the UI (see `locales/custom_languages.json`).
* **Revive support** — 0r-ambulancejob.

## Fixed

* codem-inventory: vehicle trunk & glovebox items now show up everywhere.
* Item Explorer performance and loading improvements.
* Item images and large item counts display correctly.
* Owner accounts no longer miss newly added panel features.

## Changed Files

* `server/backup/*` • `server/bridge/db_backup.js` • `server/cloud/handlers.lua` • `server/log/formatters/server.lua` • `bridge/inventory/*` • `bridge/revive/*` • `shared/config.lua` • `shared/permissions.lua` • `locales/*` • `ui/dist/*` • `fxmanifest.lua`


# v1.0.8

## Added

* **Custom languages** — add your own language to the panel without editing the UI (see `locales/custom_languages.json`).
* **Revive support** — 0r-ambulancejob.
* **codem-inventory** — full vehicle trunk & glovebox support in the Item Explorer.

## Fixed

* Fixed panel actions occasionally failing with "target offline" for online players.
* Panel item images now load reliably and match your in-game inventory.
* Item Explorer: fixed large item counts overflowing, and made vehicle rows clickable.
* Various performance and stability improvements.

## Changed Files

* `bridge/inventory/*` • `bridge/revive/*` • `bridge/registry.lua` • `server/cloud/handlers.lua` • `server/core/*` • `shared/config.lua` • `locales/*` • `ui/dist/*` • `fxmanifest.lua`


# v1.0.7

## Added

* **Live item images** — the web panel now shows the exact item images from your own inventory resource.
* **Inventory support** — ak47\_inventory.
* **Jail support** — pickle\_prisons.
* **Clothing support** — ak47\_qb\_clothing, crm-appearance.

## Fixed

* Web panel "Set Job" now lists the server's real jobs.

## Changed Files

* `bridge/inventory/*` • `bridge/jail/*` • `bridge/clothing/*` • `bridge/registry.lua` • `server/cloud/handlers.lua` • `server/player/actions.lua` • `server/data/quick_actions/defaults.lua` • `shared/config.lua` • `fxmanifest.lua`


# v1.0.6

## Added

* **New language** — ไทย (Thai). 13 languages total.
* **Revive support** — wasabi\_ambulance.
* **Jail support** — DHS-PrisonSim.
* **Invoice support** — wasabi\_billing.
* **Vehicle key support** — MrNewbVehicleKeys.
* **Clothing support** — rcore\_clothing.
* **Phone number support** — qs-smartphone / qs-smartphone-pro.

## Fixed

* Fixed panel actions occasionally failing with "target offline" for players who were online.
* Item Explorer now includes offline players' items on more inventory setups.
* Minor inventory and billing compatibility improvements.

## Changed Files

* `bridge/revive/*` • `bridge/jail/*` • `bridge/invoices/*` • `bridge/vehiclekeys/*` • `bridge/clothing/*` • `bridge/inventory/*` • `bridge/registry.lua` • `server/core/*` • `server/cloud/handlers.lua` • `shared/config.lua` • `fxmanifest.lua` • `ui/dist/*` • `locales/*`


# v1.0.5

## Fixed

* Live View issues fixed and improved.
* Fixed "Send to Impound" deleting the vehicle without impounding it on some garage systems.
* Fixed item actions failing on some inventory setups.

## Changed Files

* `bridge/garage/providers.lua` • `bridge/inventory/chezza-inventory.lua` • `server/core/esx/vehicles.lua` • `server/core/qbcore/vehicles.lua` • `server/data/liveview/system.lua` • `server/cloud/handlers.lua` • `fxmanifest.lua` • `ui/dist/*` • `locales/*`


# v1.0.4

## Added

* **Inventory support** — chezza-inventory.

## Fixed

* Fixed the Give Item picker showing no results on some inventory setups.
* Fixed garage actions (send to garage / impound) on some garage systems.
* Fixed staff removal not applying immediately.
* Minor localization improvements.

## Changed Files

* `bridge/inventory/*` • `bridge/garage/*` • `bridge/registry.lua` • `server/auth/handlers.lua` • `server/helpers.lua` • `ui/dist/*` • `locales/*`


# v1.0.3

## Added

* **Ticket logging via Discord webhook** — ticket open & close events (with a transcript link) now post straight to a Discord channel you set in `shared/webhooks.lua`. **No bot required.** Split them into separate channels with `ticketsOpen` / `ticketsClose`.
* **Inventory support** — tgiann-inventory.
* **Garage support** — tgiann-realparking (vehicle state, read-only).
* **Invoice support** — codem-mphone (mPhone v2 newbilling).

## Fixed

* `/ticket` — players without admin permission now open the player ticket menu instead of an empty screen.
* **Dashboard** — removed leftover placeholder text on the Online Players card.

## Changed Files

* `server/data/tickets/transcript.lua` • `server/data/tickets/system.lua` • `server/cloud/handlers.lua` • `shared/webhooks.lua` • `bridge/inventory/tgiann-inventory.lua` • `bridge/inventory/_export_provider.lua` • `bridge/garage/adapters/tgiann-realparking.lua` • `bridge/invoices/adapters/codem-mphone.lua` • `bridge/invoices/handlers.lua` • `bridge/registry.lua` • `shared/config.lua` • `fxmanifest.lua` • `ui/dist/*` • `locales/*`


# v1.0.2

## Fixed

* Fixed staff assignment related issues.

## Changed Files

* `server/auth/helpers.lua` • `server/auth/handlers.lua` • `server/auth/manager.lua` • `server/player/profile.lua`


# v1.0.1

## Added

* **Billing / Invoices** — new provider support: **ESX Billing**, **Codem Billing** & **Codem Billing v2** (on top of qb-phone & g-billing). View and manage player invoices from the panel across all of them.
* **Auto-detect** — the compatibility bridge picks up the active billing resource automatically (`TW.InvoicesSystem`).

## Changed Files

* `bridge/invoices/adapters/*` (esx\_billing, codem-billing, codem-billingv2 — new)
* `bridge/registry.lua`
* `fxmanifest.lua`
* `shared/config.lua`


# v1.0

Initial release.

**Includes:**

* In-game NUI admin menu (QBCore, QBox & ESX) with auto-detected integrations
* Role-based permissions with 5 built-in roles + custom roles
* Player, vehicle, and server management
* Monitoring: live monitor, spectate, Live View (WebRTC + proximity audio), replay clips, mugshots
* Tickets, announcements, polls, events, blips, jobs, teams, invoices
* Quick Actions (17 self toggles) and Troll Menu (39 actions)
* Comprehensive audit logging with per-category Discord webhooks
* Tworst Cloud web panel uplink
* Companion Discord bot support
* 13 languages


# Multiplayer Scrapyard Job

<figure><img src="/files/2Cq92kuGHm9nF3gjZx59" alt=""><figcaption></figcaption></figure>

## Overview

**TW Scrapyard Job** is a fully immersive multiplayer scrapyard job system where players can collect, process, and sell scrap materials. Work alone or team up with up to 4 players to complete missions, earn money, and level up your scrapyard career.

{% hint style="success" %}
**Multiplayer Support:** Up to 4 players can work together in a lobby, sharing tasks and rewards!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with up to 4 players in cooperative gameplay
* **Vehicle Rental System** - Rent work vehicles to collect and transport scrap
* **Scrap Collection** - Pick up various scrap objects from designated areas
* **Press Machine** - Compress collected scrap into compact forms
* **Shredding System** - Break down compressed scrap into smaller pieces
* **Furnace & Melting** - Melt shredded materials into molten metal
* **Rail System** - Advanced bucket and rail mechanism for material transport
* **Crafting Tables** - Pour molten metal into molds to create items

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **Daily Missions** - Complete daily tasks for bonus rewards
* **Illegal Weapon Crafting** - Craft weapons from scrap parts (configurable)
* **Legal Item Crafting** - Create legitimate items for sale
* **Sell NPCs** - Legal and illegal buyers for your products
* **Reconnection System** - Players can reconnect to lobbies after disconnection
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the scrapyard NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Rent a Vehicle

Rent a work vehicle from the designated area. The vehicle is used to transport collected scrap.

### Step 3: Collect Scrap

Travel to the scrap collection area and pick up various scrap objects (microwaves, TVs, washing machines, etc.).

### Step 4: Process the Scrap

1. **Press** - Place scrap in the press machine to compress it
2. **Shred** - Put compressed scrap into the shredder
3. **Melt** - Pour shredded material into the furnace
4. **Pour** - Use the rail system to collect molten metal and pour into molds

### Step 5: Collect Rewards

Sell your crafted items to NPCs or complete missions for money and XP rewards.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | ✅ Yes    | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | ✅ Yes    | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | ✅ Yes    | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command                  | Description             |
| ------------------------ | ----------------------- |
| `/jobresetscrapyard`     | Reset your current job  |
| `/jobleavescrapyard`     | Leave the current lobby |
| `/openTutorialscrapyard` | Open the tutorial menu  |

***

## Items

The script includes the following items that need to be added to your inventory system:

| Item           | Label         | Description                |
| -------------- | ------------- | -------------------------- |
| `iron`         | Iron          | Processed metal from scrap |
| `gold_dust`    | Gold Dust     | Rare material from scrap   |
| `pistol_part1` | Pistol Part 1 | Weapon component           |
| `pistol_part2` | Pistol Part 2 | Weapon component           |
| `pistol_part3` | Pistol Part 3 | Weapon component           |
| `pistol_part4` | Pistol Part 4 | Weapon component           |

{% hint style="info" %}
Item definitions for QBCore and ox\_inventory are included in the `ITEM/` folder.
{% endhint %}

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/LXebP4ZrxEsCaCPkFUvb">/pages/LXebP4ZrxEsCaCPkFUvb</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/4A5KTfp5hxKQ0mlPcWNt">/pages/4A5KTfp5hxKQ0mlPcWNt</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/QGPHJnYuzne55Q2hM2sO">/pages/QGPHJnYuzne55Q2hM2sO</a></td></tr></tbody></table>

***

## Preview

{% embed url="<https://www.youtube.com/watch?v=YOUR_VIDEO_ID>" %}
Watch the Scrapyard Job preview
{% endembed %}

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Scrapyard Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Scrapyard Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-scrapyard** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-scrapyard` - Main script
   * `tw_scrapyard_stream` - Stream assets (maps, props, vehicles)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-scrapyard/              ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   ├── ITEM/
│   └── fxmanifest.lua
└── tw_scrapyard_stream/       ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr              # 3D models
    │   ├── *.yft              # Fragment models
    │   ├── *.ytd              # Textures
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains custom maps, props, and vehicle models. Without it, the job location will be invisible and vehicles won't spawn correctly!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

### If Automatic Setup Fails

In rare cases where automatic creation fails, you can manually import:

1. Find `insert.sql` in the script folder (if available)
2. Import it using HeidiSQL, phpMyAdmin, or command line

```bash
mysql -u username -p database_name < insert.sql
```

***

## Step 4: Add Items to Inventory

### For QBCore / QBox

Add these items to `qb-core/shared/items.lua`:

```lua
-- Scrapyard Job Items
gold_dust = { name = 'gold_dust', label = 'Golden Dust', weight = 100, type = 'item', image = 'gold_dust.png', unique = false, useable = false, shouldClose = true, description = 'A golden dust seems like the jackpot to me!' },
iron = { name = 'iron', label = 'Iron', weight = 100, type = 'item', image = 'iron.png', unique = false, useable = false, shouldClose = false, description = 'Handy piece of metal that you can probably use for something' },
pistol_part1 = { name = 'pistol_part1', label = 'Pistol Part 1', weight = 100, type = 'item', image = 'pistol_part1.png', unique = false, useable = false, shouldClose = true, description = '' },
pistol_part2 = { name = 'pistol_part2', label = 'Pistol Part 2', weight = 100, type = 'item', image = 'pistol_part2.png', unique = false, useable = false, shouldClose = true, description = '' },
pistol_part3 = { name = 'pistol_part3', label = 'Pistol Part 3', weight = 100, type = 'item', image = 'pistol_part3.png', unique = false, useable = false, shouldClose = true, description = '' },
pistol_part4 = { name = 'pistol_part4', label = 'Pistol Part 4', weight = 100, type = 'item', image = 'pistol_part4.png', unique = false, useable = false, shouldClose = true, description = '' },
```

### For ox\_inventory

Add these items to `ox_inventory/data/items.lua`:

```lua
["gold_dust"] = {
    label = "Gold Dust",
    weight = 1,
    stack = true,
    close = true,
},
["iron"] = {
    label = "Iron",
    weight = 1,
    stack = true,
    close = true,
},
["pistol_part1"] = {
    label = "Pistol Part 1",
    weight = 1,
    stack = true,
    close = true,
},
["pistol_part2"] = {
    label = "Pistol Part 2",
    weight = 100,
    stack = true,
    description = 'A component used in assembling a pistol.',
},
["pistol_part3"] = {
    label = "Pistol Part 3",
    weight = 100,
    stack = true,
    description = 'A component used in assembling a pistol.',
},
["pistol_part4"] = {
    label = "Pistol Part 4",
    weight = 100,
    stack = true,
    description = 'A component used in assembling a pistol.',
},
```

### Item Images

Copy the item images from `tw-scrapyard/ITEM/` folder to your inventory's image folder:

* **QBCore:** `qb-inventory/html/images/`
* **ox\_inventory:** `ox_inventory/web/images/`

***

## Step 5: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/scrapyard-job/configuration) page for all available options.

***

## Step 6: Configure Database Resource

### For oxmysql (Recommended)

Make sure this line is in your `fxmanifest.lua`:

```lua
server_scripts {
    '@oxmysql/lib/MySQL.lua',
    -- other files...
}
```

### For mysql-async

Uncomment the mysql-async line and comment out oxmysql:

```lua
server_scripts {
    '@mysql-async/lib/MySQL.lua',  -- Uncomment this
    -- '@oxmysql/lib/MySQL.lua',   -- Comment this out
    -- other files...
}
```

***

## Step 7: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-scrapyard)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_scrapyard_stream
ensure tw-scrapyard
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_scrapyard_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 8: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-scrapyard

### In-Game Test

1. Go to the scrapyard location (default: El Burro Heights)
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Create a lobby and start a job

***

## File Structure

```
tw-scrapyard/
├── config/
│   ├── config.lua         # Main configuration
│   ├── coordinate.lua     # Location coordinates
│   └── GetCore.lua        # Framework detection
├── client/
│   ├── main.lua           # Main client script
│   ├── vehicle.lua        # Vehicle system
│   ├── press.lua          # Press machine
│   ├── shredding.lua      # Shredding system
│   ├── furnace.lua        # Furnace system
│   ├── rail.lua           # Rail system
│   └── ...
├── server/
│   ├── server.lua         # Main server script
│   ├── lobby.lua          # Lobby management
│   ├── mission.lua        # Mission system
│   └── ...
├── locales/
│   ├── en.lua             # English
│   ├── tr.lua             # Turkish
│   ├── de.lua             # German
│   └── ...
├── html/                  # UI files
├── ITEM/                  # Item images & definitions
└── fxmanifest.lua
```

***

## Troubleshooting

### Script Won't Start

1. Check resource name is exactly `tw-scrapyard` (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Invisible Location

1. Make sure `tw_scrapyard_stream` is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors
4. The stream folder must contain `.ydr`, `.yft`, and `.ytd` files

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-scrapyard
3. Check framework resource name matches expected names

### Items Not Working

1. Verify items are added to your inventory system
2. Check item names match exactly (case-sensitive)
3. Restart both the inventory resource and tw-scrapyard

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Scrapyard Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'

-- Inventory Images Path (adjust based on your inventory)
Config.InventoryImagePath = "nui://qb-inventory/html/images/"

-- Default/Fallback Image
Config.DefaultItemImage = "nui://tw-scrapyard/html/img/gun.png"
```

### Image Path Examples

| Inventory        | Image Path                          |
| ---------------- | ----------------------------------- |
| QBCore Inventory | `"nui://qb-inventory/html/images/"` |
| ox\_inventory    | `"nui://ox_inventory/web/images/"`  |
| qs-inventory     | `"nui://qs-inventory/html/images/"` |

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

| System     | Config Value  | Description                           |
| ---------- | ------------- | ------------------------------------- |
| DrawText   | `'drawtext'`  | Built-in text prompts (no dependency) |
| ox\_target | `'ox-target'` | Overextended target system            |

***

## Server & Display Settings

```lua
-- Server Name (displayed in UI)
Config.ServerName = "TWORST"  -- Max 10 characters

-- Money Settings
Config.MoneyType = "$"        -- Currency symbol in UI
Config.MoneyType2 = "bank"    -- Payment type: 'bank' or 'cash'

-- Profile Picture (displayed in UI)
Config.ExampleProfilePicture = "https://r2.fivemanage.com/biv23I9cFWICSObhZsr4C/LogoNEW.png"
```

***

## Job Settings

### Lobby & Players

```lua
-- Maximum Players in Lobby
Config.MaxPlayersInLobby = 4  -- 1-4 players per lobby

-- Job Cooldown (hours between jobs)
Config.jobCoolDownHours = 0  -- 0 = no cooldown

-- Level Requirement Check
Config.jobLevelCheck = false  -- true = check player levels before starting
```

### Commands

```lua
Config.Command = {
    jobReset = "jobresetscrapyard",      -- Reset current job
    jobLeave = "jobleavescrapyard",      -- Leave lobby
    openTutorial = "openTutorialscrapyard", -- Open tutorial menu
}
```

***

## Clothing System

```lua
-- Enable Job Clothing
Config.ChangeClothesSystem = false  -- true/false

-- Clothing Script
Config.ClothingScript = "qb-clothing"
-- Options: 'qb-clothing', 'illenium-appearance', 'fivem-appearance', 'esx_skin', 'rcore_clothing'
```

### Job Uniforms

Customize the job uniform in `Config.JobClothes`:

```lua
Config.JobClothes = {
    male = {
        { jacket = 97,   texture = 0 },
        { shirt = 59,    texture = 0 },
        { arms = 0,      texture = 0 },
        { legs = 9,      texture = 6 },
        { shoes = 12,    texture = 3 },
        -- ... more clothing items
    },
    female = {
        { jacket = 239,  texture = 8 },
        { shirt = 15,    texture = 0 },
        -- ... more clothing items
    }
}
```

***

## Vehicle Key System

```lua
-- Enable Vehicle Keys
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

The script **auto-detects** your vehicle key system:

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Job Location

Configure the main job NPC location:

```lua
Config.Job = {
    ['coords'] = {
        ['intreactionCoords'] = vector3(1213.85, -1251.17, 36.32),
        ['ped'] = true,
        ['pedCoords'] = vector3(1213.85, -1251.17, 36.32),
        ['pedHeading'] = 87.43,
        ['pedHash'] = 0xC5FEFADE  -- Ped model
    },
    ['job'] = 'all',  -- Job requirement: 'all' = anyone can use
    ['blip'] = {
        show = true,
        blipName = Locales[Config.Locale]['jobName'],
        blipType = 317,
        blipColor = 17,
        blipScale = 0.70
    },
}
```

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "El Burro Heights",
            regionJobTask = Locales[Config.Locale]['regionJobTask'],
            regionImage = "region.png",
            regionMinimumLevel = 0  -- Minimum level required
        },
        regionAwards = {
            money = 5000,           -- Base money reward
            xp = 1000,              -- Base XP reward
            onlineJobExtraAwards = 1,  -- Multiplayer bonus multiplier
            bonusExtraMoney = 500,  -- Bonus money for teamwork
            bonusExtraXP = 200,     -- Bonus XP for teamwork
        },
    },
}
```

***

## Daily Missions

Configure daily missions for extra rewards:

```lua
Config.Job['dailyMission'] = {
    {
        name = 'jobtask_one',
        header = Locales[Config.Locale]['jobtask'] .. " 1",
        label = Locales[Config.Locale]['dailyjobone'],
        count = 50,    -- Tasks to complete
        xp = 2500,     -- XP reward
        money = 1000,  -- Money reward
    },
    {
        name = 'jobtask_two',
        header = Locales[Config.Locale]['jobtask'] .. " 2",
        label = Locales[Config.Locale]['dailyjobtwo'],
        count = 10,
        xp = 1000,
        money = 3000
    },
    -- ... more missions
}
```

***

## Crafting Settings

### Weapon Crafting (Illegal)

```lua
-- Enable Illegal Weapon Crafting
Config.Job['craftWeaponEnabled'] = true
```

### Item Crafting (Legal)

```lua
-- Enable Legal Item Crafting
Config.Job['craftLegalEnabled'] = false
```

***

## Sell NPCs

Configure legal and illegal sell NPCs:

```lua
Config.Job['sellNPCs'] = {
    -- Legal NPC (sells normal items: iron, gold_dust)
    ['legal'] = {
        enabled = true,
        coords = vector3(1158.79, -1311.61, 33.75),
        heading = 172.89,
        pedModel = 'a_m_m_business_01',
        drawText = Locales[Config.Locale]['sell_scrap_items'],
        blip = {
            enabled = false,
            sprite = 473,
            color = 2,
            scale = 0.7,
            name = Locales[Config.Locale]['legal_scrap_buyer']
        }
    },

    -- Illegal NPC (black market dealer)
    ['illegal'] = {
        enabled = true,
        coords = vector3(1165.4, -1311.26, 33.87),
        heading = 160.67,
        pedModel = 's_m_y_dealer_01',
        drawText = Locales[Config.Locale]['black_market_dealer'],
        blip = {
            enabled = false,
            sprite = 486,
            color = 1,
            scale = 0.7,
            name = Locales[Config.Locale]['black_market_dealer_blip']
        }
    }
}
```

***

## Door Lock System

Control access to the illegal crafting area:

```lua
Config.Job['illegalDoor'] = {
    enabled = false,                             -- Enable door lock
    doorHash = 1300820402,                       -- Door model hash
    coords = vector3(1163.42, -1251.99, 34.57),  -- Door position
    locked = true,                               -- Initial state
    distance = 2.0,                              -- Interaction distance
    interactionKey = 47,                         -- G key
    authorizedJobs = {},                         -- Empty = everyone
    checkCarryingItem = true,                    -- Block if carrying items
    checkRequiredItem = false,                   -- Require item to open
    requiredItem = 'iron',                       -- Required item
    requiredAmount = 1,                          -- Amount required
}
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,                    -- Enable reconnection
    gracePeriodSeconds = 0,            -- 0 = unlimited until lobby closes
    maxReconnectAttempts = 3,          -- Max reconnection attempts
    resetAttemptsAfterSeconds = 300,   -- Reset after 5 minutes stable
    autoCleanupExpired = true,         -- Auto-remove expired players

    ownerTransfer = {
        enabled = true,                -- Transfer ownership if owner disconnects
        allowRejoinAsMember = true,    -- Owner can rejoin as member
        prioritizeByScore = true,      -- Highest score becomes owner
        minimumLobbyTime = 60,         -- Min time to be eligible for transfer
    },

    notifications = {
        notifyOnDisconnect = true,
        notifyOnReconnect = true,
        notifyAttemptsRemaining = true,
    },
}
```

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
    dumpsterInfo = { top = '1.3542vw', left = '50%' }
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Mission Completion Items

Give items to players when they complete missions:

```lua
Config.Job['missioncompletedItems'] = {
    giveItemPlayer = false,  -- Enable item rewards
    itemList = {
        { item = "sandwich", count = math.random(1, 4) },
        { item = "sandwich", count = 1 },
    },
}
```

***

## Custom Functions

### Start Job Function

Run custom code when a player starts a job:

```lua
Config.startJobFunction = function(source, owneridentifier)
    -- Example: Check if player has specific job
    -- local Player = GetPlayer(source)
    -- if Player and Player.job and Player.job.name == "mechanic" then
    --     return true
    -- end
    -- return false

    return true  -- Default: Allow everyone
end
```

### End Job Function

Run custom code when a player completes a job:

```lua
Config.endJobFunction = function(source, owneridentifier, scoreAmount)
    -- Add custom rewards, logging, etc.
end
```

***

## Coordinate Configuration

The `coordinate.lua` file contains all location data:

* Scrap spawn locations
* Vehicle spawn/return points
* Machine positions (press, shredder, furnace)
* Rail system coordinates
* Crafting table positions

{% hint style="warning" %}
**Advanced:** Only modify `coordinate.lua` if you want to change the physical job location. Incorrect coordinates may break the job!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Scrapyard Job.

***

## Current Version: 1.10

{% hint style="success" %}
You are using the latest version of Multiplayer Scrapyard Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-scrapyard**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.10

## Optimized

* Resmon / performance improvements across the script.

## Changed Files

* `client/item_pickup.lua`
* `client/main.lua`
* `client/press.lua`
* `client/shredding.lua`
* `client/furnace.lua`
* `client/rail.lua`
* `fxmanifest.lua`


# v1.09

## Added

* TMC (The Migration Core) Framework support

## Changed Files

* `shared/GetCore.lua`
* `shared/config.lua`
* `server/server.lua`
* `server/utility.lua`
* `client/utility.lua`
* `fxmanifest.lua`


# v1.05

**Changes:**

* Added configurable invite keybinds (Config.Keys) — accept/decline keys now editable from config
* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global missioncompletedItems config with dropMode + chance system
* Added per-region missioncompletedItems to region 1
* Added furnace\_close\_valve locale key in all 7 languages
* Hardcoded furnace interaction labels replaced with locale keys (Close Valve, Take Empty Bucket, Drop Bucket)
* Hardcoded press area labels replaced with locale keys (place/full count format)
* Fixed Press Machine names from Turkish "Press Makinesi" to English "Press Machine"
* Removed SetBlipCategory from blip creation

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `config/coordinate.lua`, `server/lobby.lua`, `client/main.lua`, `client/furnace.lua`, `client/press.lua`, `client/utility.lua`, `locales/en.lua`, `locales/tr.lua`, `locales/de.lua`, `locales/fr.lua`, `locales/ar.lua`, `locales/pt.lua`, `locales/ru.lua`


# v1.03

Initial documented release.


# Multiplayer Garbage Job

## Overview

**TW Garbage Job** is a comprehensive multiplayer garbage collection system where players work as sanitation workers, cleaning up the city. Work alone or team up with up to 4 players to collect trash, clean dumpsters, and earn rewards.

{% hint style="success" %}
**Multiplayer Support:** Up to 4 players can work together in a lobby, sharing tasks and rewards!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with up to 4 players in cooperative gameplay
* **Vehicle Rental System** - Rent garbage trucks to transport collected waste
* **Dumpster Cleaning** - Empty and clean dumpsters throughout the city
* **Bag Collection** - Pick up garbage bags from designated areas
* **Trash Pickup** - Collect loose trash items from the streets
* **Dumpster Conversion** - Convert full dumpsters for processing

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **Daily Missions** - Complete daily tasks for bonus rewards (5 tiers)
* **3 Work Regions** - El Burro Heights, Paleto Bay, Sandy Shores
* **Reconnection System** - Players can reconnect to lobbies after disconnection
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the garbage job NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Rent a Vehicle

Rent a garbage truck from the vehicle spawn point. The truck is used to transport collected waste.

### Step 3: Complete Tasks

Travel to marked locations and complete various tasks:

1. **Dumpster Cleaning** - Empty full dumpsters (2-9 per region)
2. **Bag Collection** - Pick up garbage bags (3-14 per region)
3. **Trash Pickup** - Collect loose trash items (2-16 per region)
4. **Dumpster Conversion** - Process full dumpsters

### Step 4: Collect Rewards

Complete all tasks in a region to earn money, XP, and progress toward daily missions.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command                | Description             |
| ---------------------- | ----------------------- |
| `/jobresetgarbage`     | Reset your current job  |
| `/jobleavegarbage`     | Leave the current lobby |
| `/openTutorialgarbage` | Open the tutorial menu  |

***

## Work Regions

| Region   | Location         | Tasks             |
| -------- | ---------------- | ----------------- |
| Region 1 | El Burro Heights | Beginner friendly |
| Region 2 | Paleto Bay       | Medium difficulty |
| Region 3 | Sandy Shores     | Advanced tasks    |

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/4GKkG6tRs8x6VHx1DwhJ">/pages/4GKkG6tRs8x6VHx1DwhJ</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/7htxVexrpwJd9ZNsMf8u">/pages/7htxVexrpwJd9ZNsMf8u</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/geu47IRaWw9rnFsoQt2K">/pages/geu47IRaWw9rnFsoQt2K</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Garbage Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Garbage Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-garbagev2** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-garbagev2` - Main script
   * `tw_garbage_stream` - Stream assets (maps, props, vehicles)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-garbagev2/              ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── tw_garbage_stream/         ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains custom maps, props, and the garbage truck model. Without it, vehicles won't spawn correctly!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/garbage-job/configuration) page for all available options.

***

## Step 5: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-garbagev2)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_garbage_stream
ensure tw-garbagev2
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_garbage_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 6: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-garbagev2

### In-Game Test

1. Go to the garbage job location
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Create a lobby and start a job

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Vehicles Not Spawning

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-garbagev2
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Garbage Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'

-- Inventory Images Path (adjust based on your inventory)
Config.InventoryImagePath = "nui://qb-inventory/html/images/"

-- Default/Fallback Image
Config.DefaultItemImage = "nui://tw-garbagev2/html/img/garbage.png"
```

### Image Path Examples

| Inventory        | Image Path                          |
| ---------------- | ----------------------------------- |
| QBCore Inventory | `"nui://qb-inventory/html/images/"` |
| ox\_inventory    | `"nui://ox_inventory/web/images/"`  |
| qs-inventory     | `"nui://qs-inventory/html/images/"` |

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

| System     | Config Value  | Description                           |
| ---------- | ------------- | ------------------------------------- |
| DrawText   | `'drawtext'`  | Built-in text prompts (no dependency) |
| ox\_target | `'ox-target'` | Overextended target system            |

***

## Server & Display Settings

```lua
-- Server Name (displayed in UI)
Config.ServerName = "TWORST"  -- Max 10 characters

-- Money Settings
Config.MoneyType = "$"        -- Currency symbol in UI
Config.MoneyType2 = "bank"    -- Payment type: 'bank' or 'cash'

-- Profile Picture (displayed in UI)
Config.ExampleProfilePicture = "https://r2.fivemanage.com/biv23I9cFWICSObhZsr4C/LogoNEW.png"
```

***

## Job Settings

### Lobby & Players

```lua
-- Maximum Players in Lobby
Config.MaxPlayersInLobby = 4  -- 1-4 players per lobby

-- Job Cooldown (hours between jobs)
Config.jobCoolDownHours = 0  -- 0 = no cooldown

-- Level Requirement Check
Config.jobLevelCheck = false  -- true = check player levels before starting
```

### Commands

```lua
Config.Command = {
    jobReset = "jobresetgarbage",      -- Reset current job
    jobLeave = "jobleavegarbage",      -- Leave lobby
    openTutorial = "openTutorialgarbage", -- Open tutorial menu
}
```

***

## Vehicle Settings

```lua
-- Work Vehicle
Config.Vehicle = "tolgartur"  -- Garbage truck model

-- Vehicle Key System
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

The script **auto-detects** your vehicle key system:

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

***

## Clothing System

```lua
-- Enable Job Clothing
Config.ChangeClothesSystem = false  -- true/false

-- Clothing Script
Config.ClothingScript = "qb-clothing"
-- Options: 'qb-clothing', 'illenium-appearance', 'fivem-appearance', 'esx_skin', 'rcore_clothing'
```

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "El Burro Heights",
            regionJobTask = Locales[Config.Locale]['regionJobTask'],
            regionImage = "region.png",
            regionMinimumLevel = 0  -- Minimum level required
        },
        regionAwards = {
            money = 5000,           -- Base money reward
            xp = 1000,              -- Base XP reward
            onlineJobExtraAwards = 1,  -- Multiplayer bonus multiplier
            bonusExtraMoney = 500,  -- Bonus money for teamwork
            bonusExtraXP = 200,     -- Bonus XP for teamwork
        },
    },
    -- Region 2: Paleto Bay
    -- Region 3: Sandy Shores
}
```

***

## Task Configuration

Configure tasks per region:

```lua
['dumpsterCleaning'] = {
    taskCount = 5,  -- Number of dumpsters to clean
},
['bagCleaning'] = {
    taskCount = 8,  -- Number of bags to collect
},
['trashCollection'] = {
    taskCount = 10, -- Number of trash items to pick up
},
['dumpsterConversion'] = {
    taskCount = 1,  -- Number of dumpsters to convert
},
```

***

## Daily Missions

Configure daily missions for extra rewards:

```lua
Config.Job['dailyMission'] = {
    {
        name = 'jobtask_one',
        header = Locales[Config.Locale]['jobtask'] .. " 1",
        label = Locales[Config.Locale]['dailyjobone'],
        count = 50,    -- Tasks to complete
        xp = 2500,     -- XP reward
        money = 1000,  -- Money reward
    },
    -- Up to 5 daily mission tiers
}
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,                    -- Enable reconnection
    gracePeriodSeconds = 0,            -- 0 = unlimited until lobby closes
    maxReconnectAttempts = 3,          -- Max reconnection attempts
    resetAttemptsAfterSeconds = 300,   -- Reset after 5 minutes stable
    autoCleanupExpired = true,         -- Auto-remove expired players

    ownerTransfer = {
        enabled = true,                -- Transfer ownership if owner disconnects
        allowRejoinAsMember = true,    -- Owner can rejoin as member
        prioritizeByScore = true,      -- Highest score becomes owner
        minimumLobbyTime = 60,         -- Min time to be eligible for transfer
    },

    notifications = {
        notifyOnDisconnect = true,
        notifyOnReconnect = true,
        notifyAttemptsRemaining = true,
    },
}
```

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Garbage Job.

***

## Current Version: 2.06

{% hint style="success" %}
You are using the latest version of Multiplayer Garbage Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-garbagev2**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v2.06

**Changes:**

* Added configurable invite keybinds (Config.Keys) — accept/decline keys now editable from config
* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global missioncompletedItems config with dropMode + chance system
* Added per-region missioncompletedItems to all 3 regions
* Removed SetBlipCategory from blip creation
* Minor code formatting improvements in canOpen function

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `server/server.lua`, `client/main.lua`, `client/utility.lua`


# v2.05

Initial documented release.


# Multiplayer Gardener Job

## Overview

**TW Gardener Job** is a comprehensive multiplayer landscaping system where players work as professional gardeners. Mow lawns, prune grass, collect branches, plant flowers, and maintain beautiful gardens across Los Santos.

{% hint style="success" %}
**Multiplayer Support:** Work together with other players in cooperative gameplay to complete landscaping tasks!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with other players in cooperative gameplay
* **Vehicle Rental System** - Rent landscaping vehicles and equipment
* **Lawn Mowing** - Mow grass using specialized mower equipment
* **Grass Pruning** - Trim and prune overgrown grass
* **Branch Collection** - Gather fallen branches
* **Flower Planting** - Plant flowers in designated areas
* **Watering System** - Water newly planted flowers

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **4 Work Regions** - Multiple regions with progressive difficulty
* **Bonus Tasks** - Extra tasks for bonus rewards (watering, branch collection)
* **Interactive Equipment** - Use mowers and gardening tools
* **Reconnection System** - Players can reconnect to lobbies after disconnection
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the gardener job NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Rent Equipment

Rent a landscaping truck and mower from the equipment area.

### Step 3: Complete Tasks

Travel to marked locations and complete various gardening tasks:

1. **Lawn Mowing** - Use the mower to cut grass (20-30 tasks per region)
2. **Grass Pruning** - Trim overgrown grass (10-30 tasks per region)
3. **Branch Collection** - Pick up fallen branches (4-9 tasks per region)
4. **Flower Planting** - Plant flowers in designated spots (1-5 tasks per region)
5. **Watering** - Water the planted flowers (bonus task)

### Step 4: Collect Rewards

Complete all tasks in a region to earn money, XP, and unlock higher-level regions.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command                   | Description             |
| ------------------------- | ----------------------- |
| `/jobresetgardenerv2`     | Reset your current job  |
| `/jobleavegardenerv2`     | Leave the current lobby |
| `/openTutorialgardenerv2` | Open the tutorial menu  |

***

## Work Regions

| Region   | Difficulty | Tasks               |
| -------- | ---------- | ------------------- |
| Region 1 | Beginner   | Basic lawn care     |
| Region 2 | Easy       | More mowing tasks   |
| Region 3 | Medium     | Added pruning tasks |
| Region 4 | Advanced   | Full landscaping    |

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/RWnWVtyGkuXccrcEB6Od">/pages/RWnWVtyGkuXccrcEB6Od</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/xMPj9B6Xq6pYQQER6f3O">/pages/xMPj9B6Xq6pYQQER6f3O</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/6Oh9YUTcyJGUFU2wfRNB">/pages/6Oh9YUTcyJGUFU2wfRNB</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Gardener Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Gardener Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-gardenerv2** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-gardenerv2` - Main script
   * `tw_gardener_stream` - Stream assets (maps, props, vehicles, mower)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-gardenerv2/             ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── tw_gardener_stream/        ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains custom maps, props, the mower vehicle, and landscaping equipment models. Without it, the job won't function correctly!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/gardener-job/configuration) page for all available options.

***

## Step 5: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-gardenerv2)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_gardener_stream
ensure tw-gardenerv2
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_gardener_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 6: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-gardenerv2

### In-Game Test

1. Go to the gardener job location
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Rent a vehicle and mower
5. Start mowing and complete tasks

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Mower Not Spawning

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-gardenerv2
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Gardener Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'

-- Inventory Images Path (adjust based on your inventory)
Config.InventoryImagePath = "nui://qb-inventory/html/images/"
```

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

***

## Server & Display Settings

```lua
-- Server Name (displayed in UI)
Config.ServerName = "TWORST"  -- Max 10 characters

-- Money Settings
Config.MoneyType = "$"        -- Currency symbol in UI
Config.MoneyType2 = "bank"    -- Payment type: 'bank' or 'cash'
```

***

## Job Settings

### Commands

```lua
Config.Command = {
    jobReset = "jobresetgardenerv2",      -- Reset current job
    jobLeave = "jobleavegardenerv2",      -- Leave lobby
    openTutorial = "openTutorialgardenerv2", -- Open tutorial menu
}
```

***

## Vehicle Settings

```lua
-- Work Vehicles
Config.Vehicles = {
    pickup = "tolsadler",  -- Landscaping pickup truck
    mower = "mower",       -- Lawn mower vehicle
}

-- Vehicle Key System
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

The script **auto-detects** your vehicle key system:

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

***

## Clothing System

```lua
-- Enable Job Clothing
Config.ChangeClothesSystem = true  -- true/false

-- Clothing Script
Config.ClothingScript = "qb-clothing"
-- Options: 'qb-clothing', 'illenium-appearance', 'fivem-appearance', 'esx_skin', 'rcore_clothing'
```

***

## Sound Settings

```lua
-- Enable Script Sounds
Config.Sounds = true  -- Mowing sounds, etc.
```

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Region 1",
            regionJobTask = Locales[Config.Locale]['regionJobTask'],
            regionImage = "region.png",
            regionMinimumLevel = 0  -- Minimum level required
        },
        regionAwards = {
            money = 5000,           -- Base money reward
            xp = 1000,              -- Base XP reward
            onlineJobExtraAwards = 1,  -- Multiplayer bonus multiplier
            bonusExtraMoney = 500,  -- Bonus money for teamwork
            bonusExtraXP = 200,     -- Bonus XP for teamwork
        },
    },
    -- Region 2-4 with increasing rewards
}
```

***

## Task Configuration

Configure tasks per region:

```lua
['mowing'] = {
    taskCount = 25,  -- Number of lawn areas to mow
},
['pruning'] = {
    taskCount = 15,  -- Number of grass areas to prune
},
['branchCollection'] = {
    taskCount = 6,   -- Number of branches to collect
},
['flowerPlanting'] = {
    taskCount = 3,   -- Number of flowers to plant
},
['watering'] = {
    taskCount = 3,   -- Number of flowers to water (bonus)
},
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,                    -- Enable reconnection
    gracePeriodSeconds = 0,            -- 0 = unlimited until lobby closes
    maxReconnectAttempts = 3,          -- Max reconnection attempts
    resetAttemptsAfterSeconds = 300,   -- Reset after 5 minutes stable
    autoCleanupExpired = true,         -- Auto-remove expired players

    ownerTransfer = {
        enabled = true,                -- Transfer ownership if owner disconnects
        allowRejoinAsMember = true,    -- Owner can rejoin as member
        prioritizeByScore = true,      -- Highest score becomes owner
        minimumLobbyTime = 60,         -- Min time to be eligible for transfer
    },
}
```

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Gardener Job.

***

## Current Version: 1.3.1

{% hint style="success" %}
You are using the latest version of Multiplayer Gardener Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-gardenerv2**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.3.1

## Fixed

* Coop delivery paid out twice if two members hit E at once → now one payout per job (server-locked).
* TMC Framework: name/item/money calls fixed to the real API.

## Improved

* Single interaction setting — `InteractionHandler` removed, all via `Config.TargetSystem`.

## Changed Files

* `config.lua` • `utility.lua` • `main.lua` • `target_system.lua` • `server.lua` • `server/utility.lua`


# v1.3

## Security & Fixes

* **Task completion exploit patched** (injected event spam no longer works)
* Server-side position validation on all task types (mower, branch, flower, prunegrass)
* `FinishJob` event blocked from client-side trigger
* `LeaveVehicle` payout requires delivery point proximity
* Cross-lobby event manipulation prevented
* Mission table & job status writes restricted to whitelisted keys

## Performance

* Server resmon optimized (embedded interaction system removed)
* Interaction system refactored to target-based component

## Changed Files

* **Client:** `main.lua`, `utility.lua`, `interaction/{entities, interactions, interacts}.lua`, `components/target_system.lua`
* **Server:** `server.lua`, `editable.lua`
* **Config:** `config.lua`, `fxmanifest.lua`
* **NUI:** `index.html`, `js/app.js`, `main.css`
* **Stream:** `tw_gardenerv2_stream` updated

{% hint style="warning" %}
**Stream resource also updated** — make sure to replace `tw_gardenerv2_stream` alongside the main script.
{% endhint %}


# v1.20

**Changes:**

* Fixed mower vehicle keys not being removed when returning/finishing the job
* Added fallback key removal using stored plate data for cases where the mower entity is out of streaming range
* Improved vehicle key cleanup across all job-end scenarios (leave, reset, remove)

**Changed Files:**

`client/main.lua` • `fxmanifest.lua`


# v1.19

**Changes:**

* Added retry mechanism to manual mower attach/detach for improved reliability across all players
* Fixed vehicle delivery interaction not appearing — removed owner-only restriction so all lobby members can now deliver
* Added informative DrawText3D messages at the delivery point when conditions aren't met (e.g. wrong vehicle, vehicles not nearby)
* Fixed job cooldown crash caused by missing cooldownremaining notification config entry
* Job cooldown now applies to all lobby members, preventing cooldown bypass by joining another player's lobby
* Fixed race condition where delivery interaction wouldn't start even though blip was visible

**Changed Files:**

`client/main.lua` • `client/utility.lua` • `config/config.lua` • `server/server.lua` • `locales/en.lua` • `locales/tr.lua` • `locales/ar.lua` • `locales/de.lua` • `locales/fr.lua` • `locales/pt.lua` • `locales/ru.lua`


# v1.17

**Changes:**

* Refactored vehicle interactions from AddModelInteraction to AddEntityInteraction (netId-based) — fixes coop sync issues
* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global + per-region missioncompletedItems config with dropMode + chance system to all 5 regions
* Added start job cooldown to prevent rapid job restart abuse
* Fixed vehicle registration to use correct lobby identifier
* Added tgiann-inventory support
* Simplified entity scanning — removed over-engineered incremental scan system for cleaner, more reliable approach
* Improved interaction entity caching with netId validation and deterministic sort
* Enhanced job access checks and canOpen validation
* Expanded RefreshSkin and sendNotification functions
* Added new XP tier requirements
* Updated Arabic locale translations
* Expanded server/utility.lua with better framework compatibility (HasItem, addItem, removeItem)

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `server/server.lua`, `server/utility.lua`, `client/main.lua`, `client/utility.lua`, `client/interaction/entities.lua`, `client/interaction/interactions.lua`, `client/interaction/interacts.lua`, `locales/ar.lua`


# v1.0

Initial documented release.


# Multiplayer Fashion & Print Job

## Overview

**TW Fashion Job** is an immersive multiplayer clothing manufacturing and delivery system. Players work in a textile factory, crafting t-shirts and sweaters, then delivering boxed products to stores across the city.

{% hint style="success" %}
**Multiplayer Support:** Work together with other players in cooperative gameplay to run a clothing production line!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with other players in cooperative gameplay
* **Clothing Crafting** - Create t-shirts and sweaters in multiple colors
* **Textile Production** - Full production workflow from raw materials to finished products
* **Box Loading** - Pack finished clothing into delivery boxes
* **Delivery System** - Transport and deliver to various locations
* **Market System** - Buy raw materials (wool, dyes) from the market

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **4 Difficulty Levels** - Progressive regions with increasing complexity
* **5 Color Options** - Dark Blue, Purple, Black, White, Blue
* **Multiple Workstations** - 4 independent workstations
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the fashion job NPC at the factory and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Buy Materials

Visit the market to purchase:

* Wool
* Dyes (Dark Blue, Purple, Black, White, Blue)

### Step 3: Craft Clothing

At the factory workstations:

1. **T-Shirt Crafting** - Create t-shirts in chosen colors (1-3 shirts)
2. **Sweater Crafting** - Create sweaters in chosen colors (1-3 sweaters)
3. **Fold & Pack** - Fold clothing and prepare for boxing

### Step 4: Load & Deliver

1. **Box Loading** - Pack finished clothing into delivery boxes
2. **Delivery** - Transport boxes to various store locations (2-5 deliveries per run)

### Step 5: Collect Rewards

Complete deliveries to earn money, XP, and per-item bonuses.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command                | Description             |
| ---------------------- | ----------------------- |
| `/jobresetfashion`     | Reset your current job  |
| `/jobleavefashion`     | Leave the current lobby |
| `/openTutorialfashion` | Open the tutorial menu  |

***

## Market Items

| Item          | Price |
| ------------- | ----- |
| Wool          | $150  |
| Dark Blue Dye | $250  |
| Purple Dye    | $250  |
| Black Dye     | $250  |
| White Dye     | $250  |
| Blue Dye      | $250  |

***

## Rewards by Region

| Region   | Level | Money   | XP    |
| -------- | ----- | ------- | ----- |
| Region 1 | 0     | $5,000  | 1,000 |
| Region 2 | 2     | $10,000 | 2,000 |
| Region 3 | 4     | $15,000 | 3,000 |
| Region 4 | 6     | $20,000 | 4,000 |

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/vmEFtPTRdRYSWyIHtfqe">/pages/vmEFtPTRdRYSWyIHtfqe</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/ayfOuttRxpI6dc0Wt66N">/pages/ayfOuttRxpI6dc0Wt66N</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/tmVqUgXZltUKOaiYWBJX">/pages/tmVqUgXZltUKOaiYWBJX</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Fashion & Print Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Fashion & Print Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-fashion** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-fashion` - Main script
   * `tw_fashion_stream` - Stream assets (factory interior, props, delivery van)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-fashion/                ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── tw_fashion_stream/         ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains the factory interior, textile props, and delivery vehicle models. Without it, the job location will be incomplete!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/fashion-job/configuration) page for all available options.

***

## Step 5: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-fashion)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_fashion_stream
ensure tw-fashion
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_fashion_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 6: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-fashion

### In-Game Test

1. Go to the fashion factory location
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Visit the market and buy some materials
5. Start crafting and complete tasks

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Factory Interior Not Loading

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-fashion
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Fashion & Print Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'

-- Inventory Images Path (adjust based on your inventory)
Config.InventoryImagePath = "nui://qb-inventory/html/images/"
```

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

***

## Server & Display Settings

```lua
-- Server Name (displayed in UI)
Config.ServerName = "TWORST"  -- Max 10 characters

-- Money Settings
Config.MoneyType = "$"        -- Currency symbol in UI
Config.MoneyType2 = "bank"    -- Payment type: 'bank' or 'cash'
```

***

## Job Settings

### Factory Settings

```lua
-- Maximum Clothes Waiting
Config.MaxWaitingClothes = 4  -- Max items in queue

-- Enable Script Sounds
Config.Sounds = true
```

### Commands

```lua
Config.Command = {
    jobReset = "jobresetfashion",      -- Reset current job
    jobLeave = "jobleavefashion",      -- Leave lobby
    openTutorial = "openTutorialfashion", -- Open tutorial menu
}
```

***

## Location Settings

```lua
-- Main Factory Location
Config.FactoryLocation = vector3(722.07, -976.57, 24.13)

-- Market Location
Config.MarketLocation = vector3(452.32, -787.34, 27.36)
```

***

## Vehicle Settings

```lua
-- Delivery Vehicle
Config.Vehicle = "burrito4"  -- Delivery van model

-- Vehicle Key System
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

The script **auto-detects** your vehicle key system:

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

***

## Clothing System

```lua
-- Enable Job Clothing
Config.ChangeClothesSystem = false  -- true/false

-- Clothing Script
Config.ClothingScript = "qb-clothing"
-- Options: 'qb-clothing', 'illenium-appearance', 'fivem-appearance', 'esx_skin', 'rcore_clothing'
```

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Market Items Configuration

Configure items available in the market:

```lua
Config.MarketItems = {
    { item = "wool", price = 150, label = "Wool" },
    { item = "dye_darkblue", price = 250, label = "Dark Blue Dye" },
    { item = "dye_purple", price = 250, label = "Purple Dye" },
    { item = "dye_black", price = 250, label = "Black Dye" },
    { item = "dye_white", price = 250, label = "White Dye" },
    { item = "dye_blue", price = 250, label = "Blue Dye" },
}
```

***

## Available Colors

```lua
Config.Colors = {
    "darkblue",
    "purple",
    "black",
    "white",
    "blue"
}
```

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Beginner",
            regionMinimumLevel = 0
        },
        regionAwards = {
            money = 5000,
            xp = 1000,
        },
        tasks = {
            tshirtCount = 1,
            sweaterCount = 1,
            colorCount = 1,
            deliveryCount = 2,
        },
    },
    {
        regionID = 2,
        regionInfo = {
            regionName = "Intermediate",
            regionMinimumLevel = 2
        },
        regionAwards = {
            money = 10000,
            xp = 2000,
        },
        tasks = {
            tshirtCount = 2,
            sweaterCount = 2,
            colorCount = 3,
            deliveryCount = 3,
        },
    },
    -- Regions 3-4 with increasing tasks and rewards
}
```

***

## Task Configuration

Configure tasks per region:

```lua
['tshirtCrafting'] = {
    taskCount = 2,      -- Number of t-shirts to make
    colorCount = 3,     -- Number of different colors
},
['sweaterCrafting'] = {
    taskCount = 2,      -- Number of sweaters to make
    colorCount = 3,     -- Number of different colors
},
['boxLoading'] = {
    taskCount = 4,      -- Number of boxes to load
},
['delivery'] = {
    taskCount = 4,      -- Number of deliveries to make
},
```

***

## Delivery Bonuses

Configure per-item delivery bonuses:

```lua
Config.DeliveryBonus = {
    perTshirt = 100,    -- Bonus per t-shirt delivered
    perSweater = 150,   -- Bonus per sweater delivered
}
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,                    -- Enable reconnection
    gracePeriodSeconds = 0,            -- 0 = unlimited until lobby closes
    maxReconnectAttempts = 3,          -- Max reconnection attempts
    resetAttemptsAfterSeconds = 300,   -- Reset after 5 minutes stable
    autoCleanupExpired = true,         -- Auto-remove expired players

    ownerTransfer = {
        enabled = true,                -- Transfer ownership if owner disconnects
        allowRejoinAsMember = true,    -- Owner can rejoin as member
        prioritizeByScore = true,      -- Highest score becomes owner
        minimumLobbyTime = 60,         -- Min time to be eligible for transfer
    },
}
```

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Fashion & Print Job.

***

## Current Version: 1.11

{% hint style="success" %}
You are using the latest version of Multiplayer Fashion & Print Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-fashion**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.11

**Changes:**

* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global + per-region missioncompletedItems config with dropMode + chance system to all 4 regions
* Switched vehicle interaction from AddModelInteraction to AddEntityInteraction (netId-based) — fixes coop sync issues
* Improved interaction entity caching with netId validation and deterministic sort

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `server/server.lua`, `client/main.lua`, `client/interaction/interactions.lua`, `client/interaction/interacts.lua`


# v1.10 Alpha

Initial documented release.


# Multiplayer Electrician Job

## Overview

**TW Electrician Job** is an immersive multiplayer electrical repair system where players work as professional electricians. Repair transformers, fix circuit boards, maintain street lamps, repair traffic lights, and fix phone poles across the city.

{% hint style="success" %}
**Multiplayer Support:** Up to 4 players can work together in a lobby, sharing tasks and rewards!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with up to 4 players in cooperative gameplay
* **Utility Truck System** - Use utility trucks with controllable lift platforms
* **Transformer Repair** - Fix electrical transformers
* **Circuit Board Repair** - Repair house circuit boards
* **Street Lamp Repair** - Maintain city street lamps
* **Traffic Light Repair** - Fix broken traffic lights
* **Phone Pole Repair** - Repair telephone poles

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **6 Work Regions** - Progressive difficulty with more tasks
* **Vehicle Lift System** - Control lift platform up/down
* **Vehicle Extras System** - 6 configurable vehicle parts
* **Reconnection System** - Players can reconnect to lobbies after disconnection
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the electrician job NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Get a Utility Truck

Rent a utility truck with a controllable lift platform for accessing high electrical equipment.

### Step 3: Complete Tasks

Travel to marked locations and complete various repair tasks:

1. **Transformer Repair** - Fix transformers (1-4 tasks per region)
2. **House Circuit Board** - Repair residential circuit boards (2-5 tasks)
3. **Street Lamp Repair** - Fix street lights (1-4 tasks)
4. **Traffic Light Repair** - Repair traffic signals (1-2 tasks)
5. **Phone Pole Repair** - Fix telephone poles (1-4 tasks)

### Step 4: Collect Rewards

Complete all tasks in a region to earn money, XP, and unlock higher-level regions.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command                    | Description             |
| -------------------------- | ----------------------- |
| `/jobresetelectrician`     | Reset your current job  |
| `/jobleaveelectrician`     | Leave the current lobby |
| `/openTutorialelectrician` | Open the tutorial menu  |

***

## Work Regions

| Region   | Level | Tasks                 |
| -------- | ----- | --------------------- |
| Region 1 | 0     | Basic repairs         |
| Region 2 | 2     | More transformers     |
| Region 3 | 4     | Added circuit boards  |
| Region 4 | 6     | Street lamps included |
| Region 5 | 8     | Traffic light repairs |
| Region 6 | 10    | Full electrical work  |

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/nL53yUBWm5RubRXNvUnh">/pages/nL53yUBWm5RubRXNvUnh</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/PeF2vIXs6NaB4hbDirLc">/pages/PeF2vIXs6NaB4hbDirLc</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/GxJ9ljfV4I8dblUl7aUm">/pages/GxJ9ljfV4I8dblUl7aUm</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Electrician Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Electrician Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-electrician** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-electrician` - Main script
   * `tw_electrician_stream` - Stream assets (utility truck, props)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-electrician/            ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── tw_electrician_stream/     ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains the utility truck with lift platform and electrical equipment props. Without it, the job vehicles won't function correctly!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/electrician-job/configuration) page for all available options.

***

## Step 5: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-electrician)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_electrician_stream
ensure tw-electrician
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_electrician_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 6: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-electrician

### In-Game Test

1. Go to the electrician job location
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Rent a utility truck and test the lift controls
5. Start a job and complete tasks

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Utility Truck Not Working

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-electrician
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Electrician Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'
```

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

***

## Job Settings

### Lobby & Players

```lua
-- Maximum Players in Lobby
Config.MaxPlayersInLobby = 4  -- 1-4 players per lobby

-- Job Cooldown (hours between jobs)
Config.jobCoolDownHours = 0  -- 0 = no cooldown
```

### Commands

```lua
Config.Command = {
    jobReset = "jobresetelectrician",      -- Reset current job
    jobLeave = "jobleaveelectrician",      -- Leave lobby
    openTutorial = "openTutorialelectrician", -- Open tutorial menu
}
```

***

## Vehicle Settings

```lua
-- Utility Trucks (with lift platforms)
Config.Vehicles = {
    "utilitytruc2",
    "utilitytruc3",
}

-- Vehicle Extra Parts (6 configurable parts)
Config.VehicleExtras = {
    [1] = true,
    [2] = true,
    [3] = true,
    [4] = true,
    [5] = true,
    [6] = true,
}

-- Vehicle Key System
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

### Lift Controls

The utility truck lift can be controlled using configurable keys:

* **Lift Up** - Raise the platform
* **Lift Down** - Lower the platform

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Traffic Light Models

Supported traffic light models for repair tasks:

```lua
Config.TrafficLightModels = {
    "prop_traffic_03a",
    "prop_traffic_02a",
    "prop_traffic_01a",
    "prop_traffic_01d",
    "prop_traffic_lightset_01",
    "prop_traffic_01b",
    "prop_traffic_03b",
}
```

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Region 1",
            regionMinimumLevel = 0
        },
        regionAwards = {
            money = 5000,
            xp = 1000,
            onlineJobExtraAwards = 1,
            bonusExtraMoney = 500,
            bonusExtraXP = 200,
        },
    },
    -- Regions 2-6 with increasing rewards
}
```

***

## Task Configuration

Configure tasks per region:

```lua
['transformerRepair'] = {
    taskCount = 2,  -- Number of transformers to repair
},
['circuitBoardRepair'] = {
    taskCount = 3,  -- Number of circuit boards to fix
},
['streetLampRepair'] = {
    taskCount = 2,  -- Number of street lamps to repair
},
['trafficLightRepair'] = {
    taskCount = 1,  -- Number of traffic lights to fix
},
['phonePoleRepair'] = {
    taskCount = 2,  -- Number of phone poles to repair
},
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,
    gracePeriodSeconds = 0,
    maxReconnectAttempts = 3,
    resetAttemptsAfterSeconds = 300,
    autoCleanupExpired = true,

    ownerTransfer = {
        enabled = true,
        allowRejoinAsMember = true,
        prioritizeByScore = true,
        minimumLobbyTime = 60,
    },
}
```

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Electrician Job.

***

## Current Version: 2.07

{% hint style="success" %}
You are using the latest version of Multiplayer Electrician Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-electrician**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v2.07

## New

* **DrawText UI support** — `Config.DrawTextUI = "3dtext" | "qb" | "esx" | "ox_lib" | "custom"`

## Changed Files

* **client/** → `drawtextui.lua` (new), `editable.lua`, `main.lua`, `utility.lua`
* `config/config.lua` • `fxmanifest.lua`


# v2.06

**Changes:**

* Fixed vehicle extras not applying — added SetVehicleModKit before extra toggle
* Added SetEntityAlwaysPrerender for consistent vehicle rendering
* Added NetworkRequestControlOfEntity with timeout for coop extra sync

**Changed Files:**

`client/main.lua` • `fxmanifest.lua`


# v2.04

**Changes:**

* Added configurable invite keybinds (Config.Keys) — accept/decline keys now editable from config
* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global missioncompletedItems config with dropMode + chance system
* Added per-region missioncompletedItems to all 6 regions
* Improved vehicle parking feedback — now shows dynamic distance messages (too close / too far / ok) instead of single generic message
* Added "lift already exists" warning when another lift/ladder is within 20m
* DrawText3D now shows on pole position instead of player position
* Extended vehicle detection range from 9m to 12m, added too-far feedback for 9m+
* Simplified ladder build logic — cleaner canBuildLadder check
* Replaced parkVehicle locale key with 4 new keys (parkVehicleTooClose, parkVehicleTooFar, parkVehicleOk, liftAlreadyExists) in all 7 languages
* Removed SetBlipCategory from blip creation

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `server/server.lua`, `client/main.lua`, `client/editable.lua`, `client/utility.lua`, `locales/en.lua`, `locales/tr.lua`, `locales/de.lua`, `locales/fr.lua`, `locales/ar.lua`, `locales/pt.lua`, `locales/ru.lua`


# v2.03

Initial documented release.


# Multiplayer Plumber Job

## Overview

**TW Plumber Job** is an immersive multiplayer plumbing repair system where players work as professional plumbers. Repair pipes, unclog toilets, fix valves, and maintain plumbing systems across residential and commercial properties.

{% hint style="success" %}
**Multiplayer Support:** Work together with other players in cooperative gameplay to complete plumbing tasks!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with other players in cooperative gameplay
* **Plumbing Van System** - Use a fully equipped plumbing van
* **Pipe Repair** - Fix broken pipes (bonus task)
* **Pipe Installation** - Insert new pipes
* **Toilet Unclogging** - Unclog blocked toilets
* **Valve Operations** - Open and fix valves
* **Switch Fixing** - Repair plumbing switches (bonus task)

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **6 Work Regions** - Progressive difficulty with more complex tasks
* **Pipe & Valve Mechanics** - Complex puzzle-based plumbing systems
* **Prop Attachment System** - Realistic pipe and valve placement
* **Reconnection System** - Players can reconnect to lobbies after disconnection
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the plumber job NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Get a Plumbing Van

Rent a plumbing van equipped with all necessary tools and equipment.

### Step 3: Complete Tasks

Travel to marked locations and complete various plumbing tasks:

1. **Pipe Repair** - Fix broken pipes (bonus task)
2. **Pipe Installation** - Install new pipes
3. **Toilet Unclogging** - Clear blocked toilets (1-2 tasks)
4. **Valve Opening** - Operate and fix valves (1-2 tasks)
5. **Switch Fixing** - Repair switches (bonus task)

### Step 4: Collect Rewards

Complete all tasks in a region to earn money, XP, and unlock higher-level regions.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command                | Description             |
| ---------------------- | ----------------------- |
| `/jobresetplumber`     | Reset your current job  |
| `/jobleaveplumber`     | Leave the current lobby |
| `/openTutorialplumber` | Open the tutorial menu  |

***

## Rewards by Region

| Region   | Level | Money   | XP    |
| -------- | ----- | ------- | ----- |
| Region 1 | 0     | $5,000  | 1,000 |
| Region 2 | 2     | $7,500  | 1,500 |
| Region 3 | 4     | $10,000 | 2,000 |
| Region 4 | 6     | $12,500 | 2,500 |
| Region 5 | 8     | $12,500 | 2,500 |
| Region 6 | 10    | $12,500 | 2,500 |

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/4CTbZ0wCIUP4iqlOsRi1">/pages/4CTbZ0wCIUP4iqlOsRi1</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/FBzd8Om3od3zV7Iyv5GT">/pages/FBzd8Om3od3zV7Iyv5GT</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/k6Sfzazgd0hBlilAXCrl">/pages/k6Sfzazgd0hBlilAXCrl</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Plumber Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Plumber Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-plumber** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-plumber` - Main script
   * `tw_plumber_stream` - Stream assets (plumbing van, pipe props)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-plumber/                ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── tw_plumber_stream/         ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains the plumbing van, pipe models, valve props, and plumbing equipment. Without it, the job won't function correctly!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/plumber-job/configuration) page for all available options.

***

## Step 5: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-plumber)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_plumber_stream
ensure tw-plumber
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_plumber_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 6: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-plumber

### In-Game Test

1. Go to the plumber job location
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Rent a plumbing van
5. Start a job and complete tasks

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Van Not Spawning

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-plumber
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Plumber Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'
```

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

***

## Job Settings

### Commands

```lua
Config.Command = {
    jobReset = "jobresetplumber",      -- Reset current job
    jobLeave = "jobleaveplumber",      -- Leave lobby
    openTutorial = "openTutorialplumber", -- Open tutorial menu
}
```

***

## Entity Optimization

```lua
-- Entity Optimization Settings
Config.EntityOptimization = {
    enabled = true,
    scanInterval = 5,     -- Scan interval in seconds
    scanDistance = 75.0,  -- Scan distance in meters
}
```

***

## Vehicle Settings

```lua
-- Plumbing Van
Config.Vehicle = "tolboru"

-- Vehicle Key System
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

The script **auto-detects** your vehicle key system:

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Region 1",
            regionMinimumLevel = 0
        },
        regionAwards = {
            money = 5000,
            xp = 1000,
        },
    },
    {
        regionID = 2,
        regionInfo = {
            regionName = "Region 2",
            regionMinimumLevel = 2
        },
        regionAwards = {
            money = 7500,
            xp = 1500,
        },
    },
    -- Regions 3-6 with increasing rewards
}
```

***

## Task Configuration

Configure tasks per region:

```lua
['pipeRepair'] = {
    taskCount = 1,       -- Number of pipes to repair (bonus)
},
['pipeInsert'] = {
    taskCount = 1,       -- Number of pipes to install
},
['toiletUnclog'] = {
    taskCount = 2,       -- Number of toilets to unclog
},
['valveOpen'] = {
    taskCount = 2,       -- Number of valves to operate
},
['switchFix'] = {
    taskCount = 1,       -- Number of switches to fix (bonus)
},
```

***

## Prop Attachment System

The script uses a prop attachment system for pipes and valves:

```lua
Config.PropAttachment = {
    pipeModel = "prop_pipe_01",
    valveModel = "prop_valve_01",
    attachOffset = vector3(0.0, 0.0, 0.0),
    attachRotation = vector3(0.0, 0.0, 0.0),
}
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,
    gracePeriodSeconds = 0,
    maxReconnectAttempts = 3,
    resetAttemptsAfterSeconds = 300,
    autoCleanupExpired = true,

    ownerTransfer = {
        enabled = true,
        allowRejoinAsMember = true,
        prioritizeByScore = true,
        minimumLobbyTime = 60,
    },
}
```

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Plumber Job.

***

## Current Version: 1.1.1

{% hint style="success" %}
You are using the latest version of Multiplayer Plumber Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-plumber**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.1.1

## Fixes & Improvements

* **Insert Pipe / Repair Pipe blip not appearing bug fixed** — at remotely configured mission coordinates (200m+), blips weren't visible until the player approached; now they appear on the map instantly when the mission starts
* **Blip registration decoupled from prop spawn distance gate** — blip = server-authoritative instant lobby-wide broadcast; prop spawn = 200m gate preserved (memory optimization)
* **Critical fix for users with custom coordinate configs** — especially in setups that moved insert/repair pipe locations to other regions, the mission was practically unplayable
* **Other missions** (`openValve`, `toiletChoked`, `fixSwitch`) **were not affected** — they were already working correctly, no regression

## Changed Files

* **Client:** `client/insertPipe.lua`, `client/repairPipe.lua`
* **Manifest:** `fxmanifest.lua` (1.1.0 → 1.1.1)


# v1.10

Bug fixes for ox\_target compatibility and locale corrections reported by community.

**Changes:**

* Fixed: ox\_target stops working after T-Pipe placement — next-in-sequence pipe (hologram) now gets collision enabled while it's the active target so ox\_target raycast can hit it; collision restored to off when no longer the target
* Fixed: progress bar always showing "Putting Back Materials" — every "take pipe" trunk action was calling the put-back animation by mistake (`pedtoVehicle` instead of `vehicletoPed`); 13 call sites corrected across legacy menu and target event handlers
* Fixed: Turkish locale — `receivingMaterials` and `putBackMaterials` strings were swapped, so Turkish servers showed the wrong message in both directions
* Fixed: German locale — `shortbend` / `longbend` were translated identically to `shortpipe` / `longpipe` (both "Rohr"); now use "Bogen" so bends and straight pipes are distinguishable
* Bumped version 1.09 → 1.10

**Changed Files:**

`client/main.lua` • `client/insertPipe.lua` • `locales/tr.lua` • `locales/de.lua` • `fxmanifest.lua`


# v1.09

Added full ox\_target support alongside the existing DrawText system. Switch between modes via config; coop-safe across all 5 missions.

**Changes:**

* Added `ox_target` support — toggle via `Config.InteractionHandler = 'drawtext' | 'ox_target'` (defaults to `drawtext`)
* Added: `Config.InteractionHandler = 'drawtext' | 'ox_target'` (defaults to `drawtext`)
* Added: ox\_target adapter + mission target helper, with safe fallback if ox\_target isn't running
* `insertPipe`: only the next-in-sequence pipe shows a target at any time
* `repairPipe`: targets only on valves and broken pipes (intact ones skipped); empty-hand / correct-pipe checks
* Vehicle trunk and delivery point stay on DrawText regardless of mode
* Cleanup: all ox\_target zones/entities removed on resource stop / mission abort
* Bumped version 1.08 → 1.09

**Changed Files:**

`client/interaction/adapters/*` (new) • `client/interaction/*.lua` • `client/main.lua` • mission scripts (`insertPipe`, `repairPipe`, `openValve`, `toiletChoked`, `fixSwitch`) • `client/utility.lua` • `config/config.lua` • `fxmanifest.lua`


# v1.08

**Changes:**

* Added configurable invite keybinds (Config.Keys) — accept/decline keys now editable from config
* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global + per-region missioncompletedItems config with dropMode + chance system to all 6 regions
* Added complete standalone framework support (no database, no framework required)
* Added tgiann-inventory and codem-inventory support
* Added MrNewbVehicleKeys support for vehicle key management
* Added rcore\_clothing support in RefreshSkin function
* Added Config.MaxPlayersInLobby setting (previously hardcoded to 4)
* Added Config.startJobFunction callback for custom job eligibility validation
* Added start job cooldown to prevent rapid restart abuse
* Switched vehicle interactions from model-based to entity-based (netId) — fixes coop sync issues
* Added pipe type names in insert UI — shows required pipe type on error
* Added distance-based 3D text scaling (3.0-7.0m range)
* Added new pipe objects to region 1 coordinate data (16 pipe segments)
* Increased toiletchoked and bonus mission maxAmount from 1 to 2
* Improved entity streaming resilience with NetworkID-based recovery (GetValidPlayerHandObject)
* Fixed global variable pollution (switchData, toiletData — local)
* Fixed valve close/fix events with proper nil checks and state reset
* Removed ox\_lib dependency (commented out)
* Added 'required' locale key in all 7 languages

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `config/coordinate.lua`, `config/GetCore.lua`, `server/server.lua`, `server/utility.lua`, `client/main.lua`, `client/utility.lua`, `client/fixSwitch.lua`, `client/insertPipe.lua`, `client/openValve.lua`, `client/repairPipe.lua`, `client/toiletChoked.lua`, `client/interaction/entities.lua`, `client/interaction/interactions.lua`, `client/interaction/interacts.lua`, `client/interaction/textures.lua`, `client/interaction/utils.lua`, `locales/en.lua`, `locales/tr.lua`, `locales/de.lua`, `locales/fr.lua`, `locales/ar.lua`, `locales/pt.lua`, `locales/ru.lua`


# v1.07

Initial documented release.


# Multiplayer Diving Job

## Overview

**TW Diving Job** is an immersive multiplayer underwater diving system where players explore the ocean depths. Collect corals, clean the sea, loot treasure suitcases, and discover valuable items beneath the waves.

{% hint style="success" %}
**Multiplayer Support:** Work together with other players in cooperative underwater exploration!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with other players in cooperative gameplay
* **Scuba Equipment System** - Purchase and use scuba gear, masks, and oxygen tanks
* **Coral Collection** - Harvest various coral species
* **Sea Cleaning** - Remove debris from the ocean
* **Treasure Hunting** - Loot suitcases with valuable items
* **Box Looting** - Discover treasure boxes with rare items
* **Boat & Anchor System** - Use boats with anchor mechanics

### Additional Features

* **Level & XP System** - Progress through levels with increasing rewards
* **4 Diving Missions** - Progressive difficulty in different ocean zones
* **Oxygen Tank System** - 3 tank levels with different capacities
* **Lift Bag Mechanic** - Raise heavy treasure boxes from the depths
* **Random Treasure System** - Probability-based valuable item drops
* **Knife Mechanic** - Cut open suitcases to access contents
* **Tutorial System** - In-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the diving job NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Get Equipment

Purchase diving equipment from the shop:

* **Scuba Gear/Mask** - $700
* **Oxygen Tanks** - Level 1: $500, Level 2: $1,000, Level 3: $1,500
* **Lift Bag** - $200
* **Knife** - $500

### Step 3: Dive & Complete Tasks

Take a boat to the dive site and complete missions:

1. **Coral Collection** - Harvest corals (15-50 per mission)
2. **Sea Cleaning** - Remove debris (15-50 per mission)
3. **Suitcase Looting** - Find and open suitcases (10-20 per mission)
4. **Box Looting** - Raise treasure boxes with lift bags

### Step 4: Collect Rewards

Sell collected items and complete missions for money and XP.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Commands

| Command           | Description              |
| ----------------- | ------------------------ |
| `/anchor`         | Drop/pick up boat anchor |
| `/jobresetdiving` | Reset your current job   |
| `/deletegear`     | Remove diving equipment  |

***

## Equipment & Prices

### Scuba Equipment

| Item            | Price |
| --------------- | ----- |
| Scuba Gear/Mask | $700  |
| Lift Bag        | $200  |
| Knife           | $500  |

### Oxygen Tanks

| Level   | Capacity  | Price  |
| ------- | --------- | ------ |
| Level 1 | 3 seconds | $500   |
| Level 2 | 5 seconds | $1,000 |
| Level 3 | 7 seconds | $1,500 |

***

## Harvestable Items

| Item               | Drop Rate | Value       |
| ------------------ | --------- | ----------- |
| Dendrogyra Coral   | 70%       | $1,500      |
| Antipatharia Coral | 20%       | $1,500      |
| Rolex Watch        | Variable  | $750-$2,500 |
| Diamond Ring       | 20%       | $2,000      |
| Gold Bar           | 10-20%    | $2,500      |

***

## Missions & Rewards

| Mission   | Level | Location      | Money   | XP    |
| --------- | ----- | ------------- | ------- | ----- |
| Mission 1 | 0     | Tworst Island | $10,000 | 1,000 |
| Mission 2 | 2     | Tworst Island | $20,000 | 2,000 |
| Mission 3 | 3     | Deep Ocean    | $30,000 | 3,000 |
| Mission 4 | 4     | Deep Trench   | $40,000 | 4,000 |

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/REqyeqYqlMwOvDu3i0Td">/pages/REqyeqYqlMwOvDu3i0Td</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/iSCm3yvQTfnE2VkrwGZN">/pages/iSCm3yvQTfnE2VkrwGZN</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/YXg5L6JtMORZlE6Ee7vn">/pages/YXg5L6JtMORZlE6Ee7vn</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Diving Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Diving Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-diving** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-diving` - Main script
   * `Liftbag-model` - Stream assets (diving island, underwater props, boat)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-diving/                 ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── Liftbag-model/          ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains the diving island map, underwater coral props, treasure boxes, and boat models. Without it, the job location and underwater elements won't appear!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/diving-job/configuration) page for all available options.

***

## Step 5: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-diving)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure Liftbag-model
ensure tw-diving
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`Liftbag-model`) must be started **before or with** the main script
  {% endhint %}

***

## Step 6: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-diving

### In-Game Test

1. Go to the diving job location
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Purchase diving equipment
5. Take a boat and test diving mechanics

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Island Not Loading

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors
4. The diving island should be visible when you approach the area

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-diving
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

{% hint style="info" %}
Configuration guide will be added soon.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Diving Job.

***

## Current Version: 1.6.8

{% hint style="success" %}
You are using the latest version of Multiplayer Diving Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-diving**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.6.8

**Changes:**

* Switched to ox\_inventory with multi-framework support
* Added coral items (Antipatharia & Dendrogyra) with images
* Fixed gear cleanup on job restart — entities now properly detach & delete
* Updated vehicle key system priority (qbx-vehiclekeys first)
* Improved usable item registration for qs-inventory
* Code formatting & consistency improvements

**Changed Files:**

`client/main.lua` • `server/editable.lua` • `config/config.lua` • `fxmanifest.lua`

**New Files:**

`ITEM-IMG/antipatharia_coral.png` • `ITEM-IMG/dendrogyra_coral.png` • `ox-item.txt` • `qb-item.txt`


# v1.6.7

**Changes:**

* Fixed `/deletegear` command not properly removing scuba tank and mask from world — replaced with force detach implementation
* Added entity existence checks (DoesEntityExist) before deletion to prevent null reference errors
* Enhanced scuba gear cleanup with sequential deletion and wait intervals for reliable entity removal across all players
* Fixed number formatting displaying incorrect values for large amounts by adding Math.round() rounding
* Improved oxygen system stability with proper tank cleanup on oxygen depletion
* Added success notification when scuba gear is removed
* Fixed UI responsive issues across different screen resolutions

**Changed Files:**

`client/main.lua` • `html/js/app.js` • `html/main.css`


# v1.6.6

Initial documented release.


# Multiplayer Transport Job

## Overview

**TW Transport Job** is a comprehensive multiplayer logistics and transport system where players work as delivery drivers. Load cargo with forklifts, transport goods with trucks and trailers, and deliver to various locations across the city. Includes legal and illegal delivery missions with police integration.

{% hint style="success" %}
**Multiplayer Support:** Up to 4 players can work together in a lobby, sharing tasks and rewards!
{% endhint %}

***

## Features

### Core Features

* **Multiplayer Lobby System** - Work with up to 4 players in cooperative gameplay
* **Truck & Trailer System** - Drive transport trucks with attachable trailers
* **Forklift Operations** - Load and unload cargo using forklifts
* **Box Loading** - Load boxes onto trailers at warehouses
* **Delivery System** - Transport and deliver goods to destinations
* **Furniture Delivery** - Unpack and deliver furniture items

### Additional Features

* **Level & XP System** - Progress through 70 levels with increasing rewards
* **4 Work Regions** - Progressive difficulty including illegal missions
* **Police Alert System** - Risk of police encounters on illegal missions
* **Police Search Mechanic** - Officers can search your cargo
* **Forklift Attachment** - Attach forklifts to trucks for transport
* **Tutorial System** - 6 in-game video tutorials for new players
* **Multi-language Support** - 7 languages included (EN, TR, DE, FR, PT, RU, AR)

***

## How It Works

### Step 1: Start a Lobby

Go to the transport job NPC and open the job menu. Create a lobby and invite other players (optional).

### Step 2: Get Your Vehicles

Rent a transport truck with trailer and a forklift for loading operations.

### Step 3: Complete Tasks

Travel to marked locations and complete various transport tasks:

1. **Box Loading** - Use forklift to load boxes onto trailer (2-8 boxes)
2. **Truck Delivery** - Drive truck to delivery location
3. **Box Opening** - Open boxes at destination
4. **Furniture Delivery** - Deliver items to final locations

### Step 4: Watch for Police (Illegal Missions)

On Region 4 illegal missions, police may be alerted:

* 75% chance of police alert
* Officers may search your cargo
* 65% chance of finding illegal items

### Step 5: Collect Rewards

Complete all tasks in a region to earn money, XP, and unlock higher-level regions.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |
| PolyZone  | Yes      | Required for all Tworst Scripts                     |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |
| Clothing Script        | Job uniform system                |
| Police Dispatch        | Alert system integration          |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

### Police Dispatch Systems

* ps-dispatch
* ls-dispatch
* fl-dispatch
* bixbi\_dispatch
* cd\_dispatch
* linden\_outlawalert

***

## Commands

| Command                  | Description             |
| ------------------------ | ----------------------- |
| `/jobresettransport`     | Reset your current job  |
| `/jobleavetransport`     | Leave the current lobby |
| `/openTutorialtransport` | Open the tutorial menu  |

***

## Rewards by Region

| Region   | Level | Type    | Money   | XP     |
| -------- | ----- | ------- | ------- | ------ |
| Region 1 | 0     | Legal   | $5,000  | 1,000  |
| Region 2 | 2     | Legal   | $10,000 | 3,000  |
| Region 3 | 4     | Legal   | $15,000 | 5,000  |
| Region 4 | 6     | Illegal | $25,000 | 10,000 |

***

## Daily Missions

| Task   | Requirement                       | XP    | Money  |
| ------ | --------------------------------- | ----- | ------ |
| Task 1 | Complete 50 transport tasks       | 2,500 | $1,000 |
| Task 2 | Complete 10 missions              | 1,000 | $3,000 |
| Task 3 | Earn $10,000                      | 2,000 | $3,000 |
| Task 4 | Complete 20 missions with friends | 2,000 | $3,000 |

***

## Police System

### Alert Settings

* **Alert Chance:** 75% on illegal missions
* **Cooldown:** 2 minutes between alerts

### Alert Types

| Type                | Code  | Priority |
| ------------------- | ----- | -------- |
| Suspicious Activity | 10-66 | 2        |
| Illegal Transport   | 10-71 | 3        |
| Speeding Vehicle    | 10-11 | 1        |

### Search Mechanic

* Search time: 8 seconds
* Illegal items chance: 65%
* Search distance: 4.0 units

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/SCTRjP3559tY1vYXXKPm">/pages/SCTRjP3559tY1vYXXKPm</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/Py2wkt6eXUvrm3EdTVaq">/pages/Py2wkt6eXUvrm3EdTVaq</a></td></tr><tr><td><strong>Changelog</strong></td><td>Version history and updates</td><td><a href="/pages/BAgN01E9ImOxjKEp9L2s">/pages/BAgN01E9ImOxjKEp9L2s</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Multiplayer Transport Job from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Multiplayer Transport Job on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **PolyZone**          | Required for all Tworst Scripts                     |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-transportv2** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **two folders**:
   * `tw-transportv2` - Main script
   * `tw_transport_stream` - Stream assets (truck, trailer, forklift, warehouse props)
3. Place **both folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-transportv2/            ← Main script
│   ├── config/
│   │   ├── config.lua
│   │   ├── coordinate.lua
│   │   └── GetCore.lua
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   └── fxmanifest.lua
└── tw_transport_stream/       ← Stream assets (REQUIRED)
    ├── stream/
    │   ├── *.ydr
    │   ├── *.yft
    │   ├── *.ytd
    │   └── ...
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** The stream folder contains the transport truck, trailer, forklift, and warehouse props. Without it, vehicles won't spawn and job locations will be incomplete!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

***

## Step 4: Configure the Script

Open `config/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = 'qb'  -- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Interaction System
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/transport-job/configuration) page for all available options.

***

## Step 5: Configure Police Dispatch (Optional)

If you want police alerts on illegal missions, configure your dispatch system:

```lua
Config.PoliceAlert = {
    enabled = true,
    dispatchSystem = "ps-dispatch",  -- Your dispatch resource
    alertChance = 75,                -- Chance of alert (%)
}
```

Supported dispatch systems:

* ps-dispatch
* ls-dispatch
* fl-dispatch
* bixbi\_dispatch
* cd\_dispatch
* linden\_outlawalert

***

## Step 6: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-transportv2)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
ensure PolyZone

# Tworst Scripts - Stream files must be loaded!
ensure tw_transport_stream
ensure tw-transportv2
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Stream resource (`tw_transport_stream`) must be started **before or with** the main script
  {% endhint %}

***

## Step 7: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-transportv2

### In-Game Test

1. Go to the transport job location (El Burro Heights)
2. Look for the job blip on the map
3. Interact with the NPC to open the job menu
4. Rent a truck and forklift
5. Test loading boxes with the forklift

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Vehicles Not Spawning

1. Make sure the stream folder is in your resources folder
2. Verify it's started in your `server.cfg`
3. Check the server console for streaming errors

### Forklift Not Attaching

1. Ensure the forklift model is loaded from stream
2. Check that attachment coordinates are correct in config
3. Try restarting both stream and main script

### Police Alerts Not Working

1. Verify your dispatch system is installed and running
2. Check `Config.PoliceAlert.enabled` is `true`
3. Ensure dispatch system name matches exactly

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-transportv2
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Multiplayer Transport Job.

***

## Configuration Files

The script uses multiple configuration files located in the `config/` folder:

| File             | Purpose                                           |
| ---------------- | ------------------------------------------------- |
| `config.lua`     | Main configuration (framework, settings, rewards) |
| `coordinate.lua` | Location coordinates for all job areas            |
| `GetCore.lua`    | Framework detection (usually don't modify)        |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'oldqb', 'esx', 'oldesx', 'vrp', 'vrp2', 'standalone'
Config.Framework = 'qb'

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'ar')
Config.Locale = 'en'

-- Currency Display
Config.CurrencyUnit = '$'  -- Options: '$', '€', '₺'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Inventory Settings

```lua
-- Inventory System (ignored in standalone mode)
Config.Inventory = "qb_inventory"
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory', 'tgiann-inventory'
```

***

## Interaction Settings

```lua
-- Interaction Handler
Config.InteractionHandler = 'drawtext'  -- Options: 'drawtext', 'ox-target', 'qb-target'
```

***

## Job Settings

### Lobby & Players

```lua
-- Maximum Players in Lobby
Config.MaxPlayersInLobby = 4  -- 1-4 players per lobby

-- Job Cooldown (hours between jobs)
Config.jobCoolDownHours = 0  -- 0 = no cooldown

-- Level Requirement Check
Config.jobLevelCheck = false  -- true = check player levels before starting
```

### Commands

```lua
Config.Command = {
    jobReset = "jobresettransport",      -- Reset current job
    jobLeave = "jobleavetransport",      -- Leave lobby
    openTutorial = "openTutorialtransport", -- Open tutorial menu
}
```

***

## Vehicle Settings

```lua
-- Transport Vehicles
Config.Vehicles = {
    truck = "tolpounder",   -- Main transport truck
    forklift = "forklift",  -- Forklift for loading
}

-- Vehicle Key System
Config.Vehiclekey = true

-- Remove Keys on Job End
Config.Removekeys = true
```

The script **auto-detects** your vehicle key system:

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

***

## Forklift Attachment System

Configure forklift attachment to trucks:

```lua
Config.ForkliftAttachment = {
    attachBoneId = 72,
    positions = {
        -- 8 default trailer positions
        -- 1 forklift position with front/back markers
    },
}
```

***

## Police Alert System

```lua
Config.PoliceAlert = {
    enabled = true,           -- Enable police alerts
    alertChance = 75,         -- Chance of alert on illegal missions (%)
    cooldown = 120,           -- Cooldown between alerts (seconds)

    -- Dispatch System
    dispatchSystem = "ps-dispatch",
    -- Options: 'ps-dispatch', 'ls-dispatch', 'fl-dispatch',
    --          'bixbi_dispatch', 'cd_dispatch', 'linden_outlawalert', 'custom'
}
```

### Alert Types

```lua
Config.AlertTypes = {
    suspicious = {
        code = "10-66",
        priority = 2,
        label = "Suspicious Activity",
    },
    illegalTransport = {
        code = "10-71",
        priority = 3,
        label = "Illegal Transport",
    },
    speeding = {
        code = "10-11",
        priority = 1,
        label = "Speeding Vehicle",
    },
}
```

***

## Police Search System

```lua
Config.PoliceSearch = {
    enabled = true,
    searchTime = 8,           -- Time to search (seconds)
    illegalItemsChance = 65,  -- Chance of finding illegal items (%)
    searchDistance = 4.0,     -- Interaction distance

    -- Police job names that can search
    policeJobs = {
        "police", "sheriff", "state",
        "lspd", "bcso", "sahp",
        "park", "pd", "policia"
    },
}
```

***

## Clothing System

```lua
-- Enable Job Clothing
Config.ChangeClothesSystem = false  -- true/false

-- Clothing Script
Config.ClothingScript = "qb-clothing"
-- Options: 'qb-clothing', 'illenium-appearance', 'fivem-appearance', 'esx_skin', 'rcore_clothing'
```

### Job Uniforms

```lua
Config.JobClothes = {
    male = {
        { jacket = 97,   texture = 0 },
        { shirt = 59,    texture = 0 },
        { legs = 9,      texture = 6 },
        { shoes = 12,    texture = 3 },
    },
    female = {
        { jacket = 239,  texture = 8 },
        { shirt = 15,    texture = 0 },
        { legs = 35,     texture = 0 },
        { shoes = 26,    texture = 0 },
    }
}
```

***

## Debug Settings

```lua
-- Debug Mode (shows console messages)
Config.Debug = false

-- Debug Commands (enables testing commands)
Config.DebugCommands = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.Debug = false` and `Config.DebugCommands = false` for better performance!
{% endhint %}

***

## Entity Optimization

```lua
Config.EntityOptimization = {
    enabled = true,
    updateInterval = 5,       -- Update interval in seconds
    scanDistance = 75,        -- Scan distance in meters
    movementThreshold = 50,   -- Movement threshold in meters
}
```

***

## Region & Rewards

Configure work regions and their rewards:

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Region 1",
            regionMinimumLevel = 0,
            illegal = false,
        },
        regionAwards = {
            money = 5000,
            xp = 1000,
            onlineJobExtraAwards = 2,
            bonusExtraMoney = 500,
            bonusExtraXP = 200,
        },
        tasks = {
            boxLoading = { min = 2, max = 4 },
        },
    },
    {
        regionID = 4,
        regionInfo = {
            regionName = "Region 4 - Illegal",
            regionMinimumLevel = 6,
            illegal = true,  -- Police alerts enabled
        },
        regionAwards = {
            money = 25000,
            xp = 10000,
        },
    },
}
```

***

## Task Configuration

Configure tasks per region:

```lua
['transport_trailer_loading'] = {
    taskCount = { min = 2, max = 8 },  -- Boxes to load
},
['transport_delivery_truck'] = {
    taskCount = 1,  -- Truck deliveries
},
['transport_open_box'] = {
    taskCount = 1,  -- Boxes to open
},
['transport_delivery_furniture'] = {
    taskCount = 1,  -- Furniture deliveries
},
```

***

## Daily Missions

Configure daily missions for extra rewards:

```lua
Config.Job['dailyMission'] = {
    {
        name = 'jobtask_one',
        header = "Task 1",
        label = "Complete 50 transport tasks",
        count = 50,
        xp = 2500,
        money = 1000,
    },
    {
        name = 'jobtask_two',
        header = "Task 2",
        label = "Complete 10 missions",
        count = 10,
        xp = 1000,
        money = 3000,
    },
    {
        name = 'jobtask_three',
        header = "Task 3",
        label = "Earn $10,000",
        count = 10000,
        xp = 2000,
        money = 3000,
    },
    {
        name = 'jobtask_four',
        header = "Task 4",
        label = "Complete 20 missions with friends",
        count = 20,
        xp = 2000,
        money = 3000,
    },
}
```

***

## Level System

Configure XP required for each level (up to level 70):

```lua
Config.RequiredXP = {
    [1] = 1000,
    [2] = 1500,
    [3] = 2000,
    [4] = 2500,
    [5] = 3000,
    -- ... up to level 70
    [70] = 45500,
}
```

***

## Reconnection System

Configure player reconnection settings:

```lua
Config.Reconnection = {
    enabled = true,
    gracePeriodSeconds = 0,
    maxReconnectAttempts = 3,
    resetAttemptsAfterSeconds = 300,
    autoCleanupExpired = true,

    ownerTransfer = {
        enabled = true,
        allowRejoinAsMember = true,
        prioritizeByScore = true,
        minimumLobbyTime = 60,
    },
}
```

***

## Tutorial Videos

The script includes 6 tutorial videos:

| # | Tutorial                          |
| - | --------------------------------- |
| 1 | How to Load Boxes with Forklift   |
| 2 | How to Attach Forklift to Vehicle |
| 3 | How to Park Truck at Delivery     |
| 4 | How to Unload Boxes               |
| 5 | How to Open & Deliver Boxes       |
| 6 | How to Deliver Truck              |

***

## UI Positions

Customize UI element positions:

```lua
Config.DefaultUIPositions = {
    teamList = { top = '77.22vh', left = '85.94vw' },
    scoreList = { top = '2.64vh', left = '1.61vw' },
    inviteSide = { top = '2.85vh', left = '73.07vw' },
    notificationDiv = { top = '40.48vh', left = '81.54vw' },
    keyInfoSide = { top = '50%', right = '2.0833vw' },
}
```

{% hint style="info" %}
Players can also adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Changelog

Version history and updates for the Multiplayer Transport Job.

***

## Current Version: 1.1

{% hint style="success" %}
You are using the latest version of Multiplayer Transport Job.
{% endhint %}

***

## Update Instructions

### Automatic Updates

Scripts purchased through Cfx.re automatically receive updates:

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-transportv2**
4. Click **Download** to get the latest version

### Manual Update Process

1. **Backup your current files**
   * Save your `config/config.lua`
   * Save your `config/coordinate.lua` (if modified)
2. **Download the new version**
3. **Extract and replace files**
   * Replace all files except your config files
   * Or compare and merge changes carefully
4. **Check for new config options**
   * Compare your config with the new default
   * Add any new settings that were added
5. **Restart your server**

{% hint style="warning" %}
**Important:** Always backup your configuration files before updating! New versions may add new config options that need to be added to your existing config.
{% endhint %}

***

## Reporting Issues

Found a bug or have a suggestion?

{% hint style="info" %}
Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Current script version
* Detailed description of the issue
* Steps to reproduce
* Server console errors (if any)
* Screenshots or videos (if applicable)
  {% endhint %}


# v1.1

## Fixed

* **Job NPC** — "Open Job Menu" target now shows on fresh join (ox\_target / qb-target / drawtext); no longer requires a script restart.

## Changed Files

* `client/main.lua` • `server/server.lua`


# v1.09

## Fixed

* Co-op boxes past \~6 not syncing (owner saw but couldn't grab, teammate saw nothing) → spawns now wait for a valid net ID.
* Unreliable forklift→truck attach → fork height now measured by raycast.

## Changed Files

* `transport_trailer_loading.lua`
* `transport_delivery_truck.lua`


# v1.08

## Security & Fixes

* Server-side lobby validation on all server events
* `FinishJob` event blocked from client-side trigger
* `LeaveVehicle` payout requires 25m delivery point proximity
* Cross-lobby event manipulation prevented
* Mission table writes restricted to whitelisted keys
* Vehicle spawn failure now rolls back `activeArea` + spawned entities

## Performance

* Server resmon optimized — embedded interaction system removed
* State bag replication + broadcast loop eliminated
* Boot-time `SELECT *` replaced with per-player lazy load
* Discord avatar negative cache + `bot_Token` guard
* `playerJobData` memory leak fixed on `playerDropped`
* `GetNetworkObject` warning spam fixed

## Interaction System

* Refactored to **TargetSystem component** (`ox_target` / `qb-target` / `drawtext`)
* New NUI-based DrawText UI with multi-card support
* Label deduplication on nearby entities
* Slide-in/out animation with anti-flicker debounce

## Changed Files

* `client/main.lua`
* `client/utility.lua`
* `client/components/target_system.lua`
* `client/interaction/interactions.lua`
* `client/interaction/interacts.lua`
* `client/interaction/raycast.lua`
* `client/interaction/textures.lua`
* `client/interaction/entities.lua`
* `client/interaction/utils.lua`
* `server/server.lua`
* `server/mission.lua`
* `server/editable.lua`
* `config/config.lua`
* `fxmanifest.lua`
* `html/index.html`
* `html/js/app.js`
* `html/main.css`


# v1.04

**Changes:**

* Added configurable invite keybinds (Config.Keys) — accept/decline keys now editable from config
* Added CalculateTeamMoney system — team rewards now scale properly with player count (bonus/penalty/equal split)
* Added resolveCompletionItems system — mission completion item drops with weightedPool and perItem modes
* Added global missioncompletedItems config with dropMode + chance system
* Added per-region missioncompletedItems to all 4 regions
* Switched vehicle interaction from AddModelInteraction to AddEntityInteraction (netId-based) — fixes coop sync issues
* Improved entity caching for interaction system with netId validation
* Added deterministic sort with 0.3 threshold for interaction distance ties
* Added roomSetting guard to entity scan thread — prevents unnecessary scanning when not in job
* Removed unused truck tracking thread (dead code cleanup)
* Fixed playerCache thread — now only runs while UI is open instead of infinite loop
* Added sleep optimization to carry object thread, invisible thread, and vehicle entry prevention thread
* Removed SetBlipCategory from blip creation
* Added NetworkDoesNetworkIdExist check before vehicle delivery validation
* Added roomSetting guard to police alert auto-notification thread
* Fixed police impound thread — now exits when job ends instead of running forever

**Changed Files:**

`fxmanifest.lua`, `config/config.lua`, `server/server.lua`, `client/main.lua`, `client/utility.lua`, `client/interaction/entities.lua`, `client/interaction/interactions.lua`, `client/interaction/interacts.lua`


# v1.03

Initial documented release.


# Lite Jobs Pack

<figure><img src="/files/AHu5DhOuVLcIIqfMSGPt" alt=""><figcaption></figcaption></figure>

## Overview

**TW Lite Jobs Pack** is an all-in-one multiplayer job system containing **23 unique jobs** for your FiveM server. From mining and fishing to delivery and treasure hunting, this comprehensive pack covers a wide variety of blue-collar and service jobs — all with built-in multiplayer support, XP progression, dynamic economy, and a modern UI.

{% hint style="success" %}
**Multiplayer Support:** Up to 3 players can work together in a lobby, sharing tasks and rewards with coop bonuses!
{% endhint %}

***

## Included Jobs (23)

<table><thead><tr><th width="60">#</th><th width="200">Job</th><th>Description</th></tr></thead><tbody><tr><td>1</td><td><strong>Miner</strong></td><td>Extract valuable ores (coal, iron, gold, emerald, diamond) from underground mines</td></tr><tr><td>2</td><td><strong>Lumberjack</strong></td><td>Cut down trees across forests and deliver logs for processing</td></tr><tr><td>3</td><td><strong>Farmer</strong></td><td>Harvest vegetables (lettuce, pumpkin, melon, watermelon) and deliver crates</td></tr><tr><td>4</td><td><strong>Fruit Picker</strong></td><td>Pick oranges and apples from fruit trees</td></tr><tr><td>5</td><td><strong>Cleaner</strong></td><td>Clean dirt stains across city streets with multiple routes</td></tr><tr><td>6</td><td><strong>Power Washer</strong></td><td>Pressure wash dirty surfaces around the city</td></tr><tr><td>7</td><td><strong>Window Cleaner</strong></td><td>Clean windows on buildings across different city routes</td></tr><tr><td>8</td><td><strong>Car Detailer</strong></td><td>Wash and polish customer vehicles with a multi-step detailing process</td></tr><tr><td>9</td><td><strong>Scrapyard</strong></td><td>Dismantle junk vehicles and collect scrap metal for recycling</td></tr><tr><td>10</td><td><strong>Hunting</strong></td><td>Hunt animals with tiered weapons, load carcasses, weigh and sell at the processing station</td></tr><tr><td>11</td><td><strong>Newspaper Delivery</strong></td><td>Deliver newspapers by bicycle across multiple city routes</td></tr><tr><td>12</td><td><strong>Cleanup Collector</strong></td><td>Collect garbage bags from bins and dumpsters, load onto sanitation truck</td></tr><tr><td>13</td><td><strong>Truck Driver</strong></td><td>Long-haul trucking with trailer pickups, distance-based pay, and illegal route chances</td></tr><tr><td>14</td><td><strong>Treasure Hunter</strong></td><td>Board a boat and hunt for underwater treasure chests with your team</td></tr><tr><td>15</td><td><strong>Dog Walker</strong></td><td>Walk dogs for clients with leash mechanics and distance-based pay</td></tr><tr><td>16</td><td><strong>Powerlines</strong></td><td>Repair electrical panels and phone pole wiring with minigame-based repairs</td></tr><tr><td>17</td><td><strong>Delivery</strong></td><td>Load packages from depot and deliver to customers across the city</td></tr><tr><td>18</td><td><strong>Warehouse</strong></td><td>Load boxes and pallets onto trucks using forklift or by hand</td></tr><tr><td>19</td><td><strong>Landscaping</strong></td><td>Trim overgrown bushes and dig up weeds with gardening equipment</td></tr><tr><td>20</td><td><strong>Fishing</strong></td><td>Cast lines and catch fish with 3 rod tiers, 9 fish types, and a fishing minigame</td></tr><tr><td>21</td><td><strong>Diving</strong></td><td>Board a boat and dive underwater for treasures and corals</td></tr><tr><td>22</td><td><strong>Forklift Operator</strong></td><td>Operate a forklift to transport and sort crates in an underground depot</td></tr><tr><td>23</td><td><strong>Tire Technician</strong></td><td>Change flat tires on stranded vehicles with realistic multi-step repairs</td></tr></tbody></table>

***

## Features

### Core Features

* **23 Unique Jobs** - Massive variety of gameplay from mining to treasure hunting
* **Multiplayer Lobby System** - Work with up to 3 players in cooperative gameplay
* **Level & XP System** - Per-job progression with increasing rewards
* **Modern UI** - Beautiful job menu, progress panels, and leaderboard with drag-and-drop positioning
* **Tutorial System** - In-game video tutorials for each job
* **Reconnection System** - Players can reconnect to lobbies after disconnection
* **8 Language Support** - EN, TR, DE, FR, PT, RU, ES, NL

### Advanced Systems

* **Admin Panel** - Full dashboard with economy management, player management, job editor, and market control
* **Quality System** - Tiered loot quality (Common, Uncommon, Rare, Legendary) with level-based bonuses
* **Dynamic Economy** - Supply and demand pricing that adjusts automatically
* **Weather Impact** - Job payment multipliers based on in-game weather conditions
* **Shift System** - Time-based payment multipliers (Morning, Afternoon, Evening, Night)
* **Achievement System** - Track milestones with optional Discord webhook notifications
* **Daily Bonus** - Random daily bonus jobs with increased pay
* **Coop Leaderboard** - Team-based rankings and competition
* **Referral Bonus** - Reward players for inviting others to work together
* **Global Events** - Server-wide special events with collective goals
* **Illegal Routes** - High-risk, high-reward illegal pickup/delivery options (Truck Driver)
* **Discord Integration** - Webhook logging for job completions, admin actions, and achievements
* **Runtime Job Editor** - Edit NPC locations, vehicle settings, spawn points, and blips without restart

***

## How It Works

### Step 1: Visit the Job NPC

Go to any job NPC location on the map and interact to open the job menu. Browse available jobs and select one.

### Step 2: Create or Join a Lobby

Start a solo session or create a multiplayer lobby and invite nearby players to work together.

### Step 3: Complete Tasks

Follow the job-specific objectives — gather resources, make deliveries, repair equipment, or provide services. Each job has unique mechanics and routes.

### Step 4: Earn Rewards

Collect money, XP, and achievements as you complete tasks. Level up to unlock better routes, tools, and higher-paying opportunities.

***

## Requirements

| Resource  | Required | Notes                                               |
| --------- | -------- | --------------------------------------------------- |
| Framework | Yes      | QBCore, QBox, ESX, vRP, or Standalone               |
| Database  | Yes      | oxmysql (recommended), mysql-async, or ghmattimysql |

### Optional Dependencies

| Resource               | Purpose                           |
| ---------------------- | --------------------------------- |
| ox\_lib                | Enhanced UI and utility functions |
| qb-target / ox\_target | Target interaction system         |
| Vehicle Keys Script    | Automatic vehicle key integration |

***

## Supported Systems

### Frameworks

| Framework  | Config Value       |
| ---------- | ------------------ |
| QBCore     | `'qb'`             |
| QBox       | `'qb'`             |
| ESX Legacy | `'esx'`            |
| vRP / vRP2 | `'vrp'` / `'vrp2'` |
| Standalone | `'standalone'`     |

### Inventory Systems

| System           | Config Value      |
| ---------------- | ----------------- |
| QBCore Inventory | `'qb_inventory'`  |
| ESX Inventory    | `'esx_inventory'` |
| ox\_inventory    | `'ox_inventory'`  |
| qs-inventory     | `'qs_inventory'`  |

### Vehicle Key Systems (Auto-detected)

* qb-vehiclekeys
* qbx-vehiclekeys
* qs-vehiclekeys
* wasabi-carlock
* cd\_garage
* Renewed-Vehiclekeys

### Fuel Systems (Auto-detected)

* LegacyFuel
* ox\_fuel
* cdn-fuel
* ps-fuel
* x-fuel

***

## Quick Links

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Installation</strong></td><td>Step-by-step installation guide</td><td><a href="/pages/6B84rFphu1Lorasejc2W">/pages/6B84rFphu1Lorasejc2W</a></td></tr><tr><td><strong>Configuration</strong></td><td>Complete configuration reference</td><td><a href="/pages/pFiV6DvnHh6Aerd1rYqW">/pages/pFiV6DvnHh6Aerd1rYqW</a></td></tr><tr><td><strong>Jobs Guide</strong></td><td>Detailed guide for all 23 jobs</td><td><a href="/pages/Z0mbM061aVvpvnOtrPSl">/pages/Z0mbM061aVvpvnOtrPSl</a></td></tr></tbody></table>

***

## Purchase

{% hint style="info" %}
Purchase Lite Jobs Pack from our [Tebex Store](https://tworst.tebex.io) or [CFX Store](https://tworst.com).
{% endhint %}


# Installation

Step-by-step guide to install the Lite Jobs Pack on your FiveM server.

***

## Prerequisites

Before installing, make sure you have:

| Requirement           | Description                                         |
| --------------------- | --------------------------------------------------- |
| **Framework**         | QBCore, QBox, ESX, vRP, or Standalone               |
| **Database Resource** | oxmysql (recommended), mysql-async, or ghmattimysql |
| **FiveM Server**      | Build 2802 or higher recommended                    |

***

## Step 1: Download the Script

### From Cfx.re Portal (Recommended)

1. Go to [portal.cfx.re](https://portal.cfx.re)
2. Navigate to **Granted Assets**
3. Find **tw-litejobpack** in your purchased scripts
4. Click **Download** to get the latest version

### From Tebex

1. Log in to your Tebex account
2. Go to your purchases
3. Download the script package

***

## Step 2: Extract Files

1. Extract the downloaded archive
2. You will find **three folders**:
   * `tw-litejobpack` - Main script (23 jobs, UI, configs)
   * `tw-litejobpack-stream` - Stream assets (custom props, tools, weapons, vehicles)
   * `tw-litejobpack-map` - Map assets (warehouse interior and crate models)
3. Place **all three folders** in your server's `resources` directory

```
resources/
├── [standalone]/
├── [qb]/
├── tw-litejobpack/                ← Main script
│   ├── shared/
│   │   ├── config.lua             ← Main configuration
│   │   └── jobs/                  ← 23 job definition files
│   ├── client/
│   ├── server/
│   ├── locales/
│   ├── html/
│   ├── img/
│   └── fxmanifest.lua
├── tw-litejobpack-stream/         ← Stream assets (REQUIRED)
│   ├── metas/
│   │   ├── powerwash/             ← Pressure washer weapon meta
│   │   └── utillitruck/           ← Utility truck vehicle meta
│   ├── stream/
│   │   ├── baskul/                ← Processing scale props
│   │   ├── cuttree/               ← Tree cutting props
│   │   ├── plumber/               ← Plumber pipes & toilet props
│   │   ├── powerwash/             ← Pressure washer weapon model
│   │   ├── tool/                  ← Pickaxes, axes, ores, crops (29 props)
│   │   └── utillitruck/           ← Utility truck model
│   └── fxmanifest.lua
└── tw-litejobpack-map/            ← Map assets (REQUIRED)
    ├── stream/
    │   ├── yusufwarehouse.ymap    ← Warehouse interior map
    │   └── *.ydr, *.yft, *.ytd   ← Warehouse & crate models
    └── fxmanifest.lua
```

{% hint style="danger" %}
**Important:** Both asset folders are required! The **stream** folder contains custom props (ores, tools, crops, vehicles, weapons) and the **map** folder contains the warehouse interior used by the Warehouse and Forklift jobs. Without them, many jobs will not function correctly!
{% endhint %}

***

## Step 3: Database Setup

{% hint style="success" %}
**Automatic Setup:** The script automatically creates the required database tables when it starts for the first time. No manual SQL import needed!
{% endhint %}

The following tables are created automatically:

* Player job progress & XP/levels
* Statistics & leaderboard data
* Achievement tracking
* Session management

***

## Step 4: Configure the Script

Open `shared/config.lua` and set your framework:

```lua
-- Framework Selection
Config.Framework = "qb"  -- Options: 'qb', 'esx', 'vrp', 'vrp2', 'standalone'

-- Database Resource
Config.SQL = "oxmysql"  -- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'

-- Inventory System
Config.Inventory = "qb_inventory"  -- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'

-- Language
Config.Locale = "en"  -- Options: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'es', 'nl'
```

{% hint style="info" %}
**QBox Users:** Set `Config.Framework = 'qb'` - QBox is fully compatible with the 'qb' setting.
{% endhint %}

See the [Configuration](/scripts/lite-jobs-pack/configuration) page for all available options.

***

## Step 5: Add Items & Weapons

Several jobs require inventory items or weapon definitions to be added to your framework.

### Newspaper Job — WEAPON\_ACIDPACKAGE (Required)

{% hint style="danger" %}
**Critical:** The Newspaper Delivery job uses `WEAPON_ACIDPACKAGE` to throw newspapers. This weapon is **not** included in GTA V by default. You **must** define it in your framework, or the Newspaper job will not work!
{% endhint %}

**QB-Core** — Add to `qb-core/shared/weapons.lua`:

```lua
['weapon_acidpackage'] = {
    ['name'] = 'weapon_acidpackage',
    ['label'] = 'News Paper',
    ['weight'] = 1000,
    ['type'] = 'weapon',
    ['ammotype'] = 'ammo-acid',
    ['image'] = 'weapon_acidpackage.png',
    ['unique'] = true,
    ['useable'] = true,
    ['description'] = 'News paper'
},
```

**ox\_inventory** — Add to `ox_inventory/data/weapons.lua`:

```lua
['WEAPON_ACIDPACKAGE'] = {
    label = 'Newspaper',
    weight = 0,
    throwable = true
},
```

**ESX** — Add the weapon definition to your ESX weapons configuration.

{% hint style="info" %}
This weapon is given via native `GiveWeaponToPed`, not through inventory. However, your framework still needs to recognize it.
{% endhint %}

### Pressure Washer & Car Detailer — WEAPON\_PRESSURE1 (ox\_inventory Users)

If you are using **ox\_inventory**, the Pressure Washer and Car Detailer jobs use `WEAPON_PRESSURE1` as a work tool. This weapon is given natively (not through inventory), but ox\_inventory's weapon mismatch system will detect it as unauthorized and remove it from the player.

To prevent this, you need to add `WEAPON_PRESSURE1` to the ignore list.

**Step 1** — Add to `ox_inventory/data/weapons.lua`:

```lua
['WEAPON_PRESSURE1'] = {
    label = 'Pressure Washer',
    weight = 0,
},
```

**Step 2** — Add to ignoreweapons in `ox.cfg`:

File: Your server's `ox.cfg` (usually located in your server root or txData base folder)

Find the line:

```
setr inventory:ignoreweapons []
```

Change it to:

```
setr inventory:ignoreweapons ["WEAPON_PRESSURE1"]
```

If you already have other weapons in the list, add it with a comma:

```
setr inventory:ignoreweapons ["WEAPON_HANDCUFFS", "WEAPON_PRESSURE1"]
```

{% hint style="info" %}
This setting tells ox\_inventory to skip the weapon mismatch check for `WEAPON_PRESSURE1`. Without this, ox\_inventory will repeatedly strip the pressure washer from the player's hands during the job.
{% endhint %}

{% hint style="info" %}
**Why is this different from the Newspaper job?**

The Newspaper job (`WEAPON_ACIDPACKAGE`) is a throwable weapon — each throw consumes one item from inventory, so it must be managed through ox\_inventory's item system with `throwable = true`.

The Pressure Washer (`WEAPON_PRESSURE1`) is a held tool — it stays in the player's hands during work and is removed when the tool is returned to the trunk. It does not need to exist in the inventory, only to be ignored by the mismatch system.
{% endhint %}

### Fishing Items (18 items)

**Fish (9 types):**

| Item Name        | Label     |
| ---------------- | --------- |
| `fish_anchovy`   | Anchovy   |
| `fish_trout`     | Trout     |
| `fish_mackerel`  | Mackerel  |
| `fish_salmon`    | Salmon    |
| `fish_snapper`   | Snapper   |
| `fish_tuna`      | Tuna      |
| `fish_grouper`   | Grouper   |
| `fish_swordfish` | Swordfish |
| `fish_shark`     | Shark     |

**Fishing Rods (3 types):**

| Item Name     | Label        |
| ------------- | ------------ |
| `standartrod` | Standard Rod |
| `carbonrod`   | Carbon Rod   |
| `prorod`      | Pro Rod      |

**Baits (6 types):**

| Item Name    | Label            |
| ------------ | ---------------- |
| `basicbait`  | Basic Bait       |
| `spoonlure`  | Spoon Lure       |
| `threesided` | Three-Sided Lure |
| `tailfish`   | Tail Fish Lure   |
| `doublehook` | Double Hook      |
| `triplehook` | Triple Hook      |

### Diving Items (2 items)

| Item Name            | Label        |
| -------------------- | ------------ |
| `dendrogyra_coral`   | Pillar Coral |
| `antipatharia_coral` | Black Coral  |

{% hint style="warning" %}
**Note:** Refer to the `ITEMS.md` file included with the script for ready-to-copy item definitions for your framework.
{% endhint %}

***

## Step 6: Add to server.cfg

Add the following to your `server.cfg`:

```cfg
# Dependencies (must start before tw-litejobpack)
ensure oxmysql          # or mysql-async
ensure es_extended      # or qb-core (your framework)
# ensure ox_lib           # optional

# Tworst Scripts - Asset files must be loaded first!
ensure tw-litejobpack-map
ensure tw-litejobpack-stream
ensure tw-litejobpack
```

{% hint style="warning" %}
**Load Order:**

* Dependencies must start **before** the script
* Map resource (`tw-litejobpack-map`) and stream resource (`tw-litejobpack-stream`) must be started **before** the main script
  {% endhint %}

***

## Step 7: Restart Server

1. Save all configuration changes
2. Restart your server completely
3. Check the server console for any errors

***

## Verification

After starting the server, verify the installation:

### Check Console

Look for these messages in your server console:

* Database tables created successfully (first run only)
* No error messages related to tw-litejobpack

### In-Game Test

1. Open the map and look for job blips
2. Go to any job NPC location
3. Interact with the NPC to open the job menu
4. Select a job, create a lobby, and test the gameplay
5. Verify XP and payment are working correctly

***

## Troubleshooting

### Script Won't Start

1. Check resource name matches exactly (case-sensitive on Linux)
2. Verify all dependencies are started before the script
3. Check for syntax errors in config files

### Missing Props / Custom Models Not Loading

1. Make sure both `tw-litejobpack-stream` and `tw-litejobpack-map` are in your resources folder
2. Verify they are started in your `server.cfg` before the main script
3. Check the server console for streaming errors

### Warehouse / Forklift Jobs Not Working

1. Make sure `tw-litejobpack-map` resource is started — it contains the warehouse interior
2. Verify the map resource loads without errors in the server console
3. The warehouse map includes custom crate models required for the Forklift and Warehouse jobs

### Items Not Found (Fishing/Diving)

1. Ensure you've added all required items to your framework
2. Check item names match exactly (case-sensitive)
3. Refer to the `ITEMS.md` file for correct item definitions

### Database Errors

1. Verify database connection string in `server.cfg`
2. Check that your database resource is starting properly
3. Ensure `Config.SQL` matches your database resource

### Changing Station Door Not Visible

If the door at the changing station is invisible, add the following to your `server.cfg`:

```
setr game_enableDynamicDoorCreation true
```

This enables dynamic door creation in FiveM, which is required for the changing station door to render properly.

### Framework Not Detected

1. Make sure `Config.Framework` matches your framework
2. Verify framework resource is starting before tw-litejobpack
3. Check framework resource name matches expected names

***

## Need Help?

{% hint style="info" %}
Having installation issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket with:

* Server console errors
* Your `Config.Framework` and `Config.SQL` settings
* Screenshots of any issues
  {% endhint %}


# Configuration

Complete configuration reference for the Lite Jobs Pack.

***

## Configuration Files

The script uses configuration files located in the `shared/` folder:

| File                  | Purpose                                            |
| --------------------- | -------------------------------------------------- |
| `shared/config.lua`   | Main configuration (framework, features, systems)  |
| `shared/jobs/*.lua`   | Individual job settings (NPC, payment, XP, routes) |
| `server/editable.lua` | Discord webhook settings                           |

***

## Basic Settings

### Framework & Core

```lua
-- Framework Selection
-- Options: 'qb', 'esx', 'vrp', 'vrp2', 'standalone'
Config.Framework = "qb"

-- Database Resource
-- Options: 'oxmysql', 'mysql-async', 'ghmattimysql'
Config.SQL = "oxmysql"

-- Inventory System
-- Options: 'qb_inventory', 'esx_inventory', 'ox_inventory', 'qs_inventory'
Config.Inventory = "qb_inventory"

-- Language (Available: 'en', 'tr', 'de', 'fr', 'pt', 'ru', 'es', 'nl')
Config.Locale = "en"

-- Currency Display Symbol
Config.CurrencySymbol = "$"

-- Event Prefix (used for internal events)
Config.EventPrefix = "tw-litejobpack"
```

{% hint style="info" %}
**QBox Users:** QBox is fully compatible. Set `Config.Framework = 'qb'` for QBox servers.
{% endhint %}

***

## Debug Settings

```lua
-- Development Mode (enables extra logging)
Config.DevMode = false

-- Debug Mode (shows console messages)
Config.Debug = false

-- Test Mode (enables test commands)
Config.Test = false
```

{% hint style="warning" %}
**Production Servers:** Always set `Config.DevMode`, `Config.Debug`, and `Config.Test` to `false` for better performance!
{% endhint %}

***

## Lobby Settings

```lua
Config.Lobby = {
    maxPlayers = 3,          -- Maximum players per lobby (1-3)
    inviteRadius = 8.0,      -- Radius to detect nearby players for invite
    inviteTimeout = 30,      -- Seconds before invite expires
    kickCooldown = 5,        -- Cooldown between kicks (seconds)
    inviteCooldown = 10,     -- Cooldown between invites (seconds)
}
```

***

## Target System

```lua
Config.TargetSystem = {
    enabled = false,                -- Enable/disable target interaction
    resource = "auto",              -- "auto", "ox_target", "qb-target"
    icon = "fas fa-briefcase",      -- Icon for job interactions
    jobCenterIcon = "fas fa-building",  -- Icon for job center NPC
}
```

***

## NPC Camera

```lua
Config.NPCCamera = {
    enabled = true,          -- Enable camera zoom on NPC interaction
    hidePlayer = true,       -- Hide player model during camera
    distance = 2.3,          -- Camera distance from NPC
    sideOffset = 0.0,        -- Horizontal offset
    height = 0.3,            -- Camera height offset
    fov = 25.0,              -- Field of view
    pitch = 5.0,             -- Camera pitch angle
    transitionMs = 500,      -- Transition duration in milliseconds
}
```

***

## Feature Toggles

### Quality System

Adds tiered loot quality with level-based bonuses.

```lua
Config.QualitySystem = {
    enabled = false,
    levelChanceBonus = 0.5,     -- Bonus chance per level
    levelPayBonus = 0.02,       -- Bonus pay multiplier per level

    defaultTiers = {
        { name = "Common",    chance = 55, multiplier = 1.0 },
        { name = "Uncommon",  chance = 25, multiplier = 1.3 },
        { name = "Rare",      chance = 13, multiplier = 1.8 },
        { name = "Legendary", chance = 7,  multiplier = 2.5 },
    },
}
```

### Dynamic Economy

Supply and demand system that adjusts item prices automatically.

```lua
Config.Economy = {
    enabled = false,
    recoveryInterval = 10,       -- Stock recovery interval (minutes)
    MinMultiplier = 0.5,         -- Minimum price multiplier
    MaxMultiplier = 2.0,         -- Maximum price multiplier

    BaseStocks = {
        ['coal_ore'] = 2000,
        ['iron_ore'] = 1000,
        ['gold_ore'] = 500,
        ['emerald_ore'] = 300,
        ['diamond_ore'] = 200,
        ['wood_log'] = 1500,
        ['metal_scrap'] = 2000,
        ['meat'] = 3000,
        -- ... more items
    }
}
```

### Global Events

Server-wide special events with collective goals and rewards.

```lua
Config.GlobalEvents = {
    enabled = false,
    events = {
        {
            id = "clean_city",
            jobId = "cleanup",
            title = "City Cleanup Initiative",
            description = "The mayor has ordered a city-wide cleanup!",
            target = 500,
            reward = { money = 5000, xp = 1000 }
        },
    }
}
```

### Job Cooldown

Prevents players from spamming jobs.

```lua
Config.JobCooldown = {
    enabled = false,
    mode = "perJob",         -- "perJob" or "global"
    duration = 120,          -- Cooldown in seconds
}
```

### Coop Payment

Configure team payment bonuses.

```lua
Config.CoopPayment = {
    enabled = false,
    mode = "full",           -- "full" (everyone gets full pay) or "split"
    bonus = 1.2,             -- 1.2x bonus for coop play
}
```

### Daily Bonus

Random daily bonus jobs with increased pay.

```lua
Config.DailyBonus = {
    enabled = false,
    bonusJobCount = { min = 1, max = 3 },     -- Number of bonus jobs per day
    bonusRange = { min = 1.25, max = 1.50 },   -- Pay multiplier range
    excludeJobs = {},                           -- Job IDs to exclude
}
```

### Coop Leaderboard

Team-based rankings visible in the UI.

```lua
Config.CoopLeaderboard = {
    enabled = true,
    broadcastInterval = 5000,    -- Update interval in milliseconds
}
```

### Weather Impact

Adjust job payments based on in-game weather.

```lua
Config.WeatherImpact = {
    enabled = false,
    reportInterval = 60000,      -- Weather check interval (ms)
    rules = {
        RAIN    = { default = 1.0, cleaner = 0.85, farmer = 1.20, landscaping = 1.20 },
        THUNDER = { default = 1.0, miner = 1.15, lumberjack = 1.15, scrapyard = 1.15 },
        FOGGY   = { default = 1.0, delivery = 1.15, trucker = 1.15, newspaper = 1.15 },
        SNOW    = { default = 1.0, powerlines = 1.20, fishing = 0.80, diving = 0.80 },
        CLEAR   = {},
        EXTRASUNNY = { default = 1.0, farmer = 1.10, fruitpicker = 1.10 },
    },
}
```

### Shift System

Time-based payment multipliers.

```lua
Config.ShiftSystem = {
    enabled = false,
    shifts = {
        morning   = { label = "Morning Shift",   hours = { 6, 12 },  rules = { default = 0.90 } },
        afternoon = { label = "Afternoon Shift",  hours = { 12, 18 }, rules = { default = 1.00 } },
        evening   = { label = "Evening Shift",    hours = { 18, 24 }, rules = { default = 1.15 } },
        night     = { label = "Night Shift",      hours = { 0, 6 },   rules = { default = 1.30, diving = 0.80 } },
    },
}
```

### Referral Bonus

Reward players for inviting others to jobs.

```lua
Config.ReferralBonus = {
    enabled = false,
    xpReward = 150,              -- XP reward for referral
    maxBonusesPerDay = 5,        -- Daily limit
}
```

### Achievements

Track player milestones with Discord webhook support.

```lua
Config.Achievements = {
    enabled = true,
    discordWebhook = true,
    list = {
        { id = "miner_lv5",      label = "Master Miner",      jobId = "miner",      type = "level", target = 5,  xpReward = 500 },
        { id = "miner_lv10",     label = "Mining Legend",      jobId = "miner",      type = "level", target = 10, xpReward = 2000 },
        { id = "fishing_lv5",    label = "Expert Angler",      jobId = "fishing",    type = "level", target = 5,  xpReward = 500 },
        { id = "trucker_lv5",    label = "Road King",          jobId = "trucker",    type = "level", target = 5,  xpReward = 500 },
        -- ... more achievements for each job
    }
}
```

***

## UI Positioning

Customize UI element positions. Players can also drag panels in-game.

```lua
Config.DefaultUIPositionsVersion = 2
Config.DefaultUIPositions = {
    jobProgressPanel        = { bottom = '12.00vh', right = '1.00vw', locked = false },
    coopLeaderboardPanel    = { top = '12.00vh', right = '1.00vw', locked = false },
    drawTextContainer       = { top = '47.65vh', right = '1.80vw', locked = false },
    actionProgressContainer = { bottom = '18.00vh', left = '48.54vw', locked = false },
    finishJobModal          = { top = '35.00vh', right = '8.00vw', locked = false },
}
```

* `locked = true` — Panel stays at the configured position, player cannot move it
* `locked = false` — Player can drag and save a custom position
* Increment `DefaultUIPositionsVersion` when changing positions to reset player overrides

{% hint style="info" %}
Players can adjust UI positions in-game through the settings menu!
{% endhint %}

***

## Disabling / Enabling Individual Jobs

Each job can be toggled on or off in its own config file (`shared/jobs/<jobname>.lua`):

```lua
enabled = true,   -- Set to false to disable this job completely
```

When disabled:

* The job NPC will **not** spawn
* The job blip will **not** appear on the map
* Players **cannot** start the job

{% hint style="info" %}
You can also disable/enable jobs at runtime through the Admin Panel's Job Editor without restarting the server.
{% endhint %}

***

## Miscellaneous Settings

```lua
-- Prevent entering vehicles while holding a job tool
Config.PreventVehicleWithTool = true

-- Force first-person view during break sessions
Config.BreakSessionFirstPerson = false

-- Require a specific job to access the pack
Config.RequireSelectedJob = false
Config.RealJob = 'none'
```

***

## Admin Panel

The Lite Jobs Pack includes a powerful admin panel for managing jobs, players, and the economy at runtime.

### Access Configuration

```lua
Config.AdminPanel = {
    acePermission = "admin",                -- ACE permission required
    identifierWhitelist = {                 -- Or whitelist specific identifiers
        -- "steam:xxxxxxxxxxxxx",
    },
}
```

Access the admin panel with the `/jobadmin` command (configurable).

### Dashboard

The admin dashboard provides real-time statistics:

* **Economy Overview** — Total money and XP earned (today, this week, all-time)
* **Job Breakdown** — Revenue and unique player counts per job
* **Active Lobbies** — Current coop sessions with player lists
* **Market Prices** — Live supply/demand multipliers for all items
* **Online Players** — Current player count

### Player Management

* **Search Players** — Find by name or identifier (online and offline)
* **Player Statistics** — View job levels, total XP, recent job history (last 20 jobs)
* **Set Player Level** — Manually adjust a player's job level (1 to max)
* **Set Perk Points** — Adjust a player's perk point balance

### Economy Management

* **View Pay Rates** — See payment modes, item prices, quality tiers for every job
* **Set Market Multipliers** — Adjust supply/demand pricing per item
* **Reset Market** — Reset individual items or all market prices to base values
* **Save Economy Config** — Persist changes directly to job config files

{% hint style="info" %}
Economy changes are validated before saving — values must be within 0-100,000 range and quality tier chances must sum to 100%.
{% endhint %}

### Job Editor (Runtime)

Admins can edit job configurations at runtime without server restart:

* **NPC Settings** — Model, scenario, coordinates, interaction distance, blip label
* **Vehicle Settings** — Model, plate, colors, spawn locations
* **Location Coordinates** — Processing station, work clothes, finish area
* **Spawn Points** — Rock spawns, tree spawns, area spots
* **Job State** — Enable/disable individual jobs

{% hint style="warning" %}
The Job Editor requires `Config.DevMode = true` or admin permission. Changes are saved directly to the job config files.
{% endhint %}

### Discord Logging

Configure Discord webhooks for admin action logging in `server/editable.lua`:

```lua
DiscordLogConfig = {
    enabled = true,
    botName = "tw-litejobpack",
    botToken = "",                   -- Your Discord bot token
    webhooks = {
        jobFinish = "",              -- Webhook for job completions
        jobLog = "",                 -- Webhook for admin actions
        achievement = "",            -- Webhook for achievements
    },
}
```

***

## Individual Job Configuration

Each job has its own configuration file in `shared/jobs/`. Every job file follows a consistent structure:

### Job Metadata

```lua
{
    id = "miner",
    name = "Miner",
    subtitle = "Underground Mining Operations",
    enabled = true,                          -- Toggle job on/off
    icon = "./img/jobs/miner_icon.svg",
    image = "./img/jobs/miner_bg.png",
    video = "https://...",                   -- Promotional video URL
}
```

### NPC Configuration

```lua
npc = {
    enabled = true,
    coords = vector4(2944.13, 2743.39, 43.3, 349.75),
    model = "s_m_y_construct_02",
    scenario = "WORLD_HUMAN_CLIPBOARD",
    interaction = {
        distance = 2.0,
        key = 38,
        keyLabel = "[E]",
        text = "Start Mining Job",
    },
    blip = {
        enabled = true,
        sprite = 618,
        color = 28,
        scale = 0.8,
        label = "Mining Job",
    },
}
```

### Payment Modes

Jobs use one of four payment modes:

| Mode         | Description                                    | Example Jobs              |
| ------------ | ---------------------------------------------- | ------------------------- |
| `"onJobEnd"` | Pay on job completion based on items collected | Miner, Farmer, Scrapyard  |
| `"distance"` | Pay based on distance traveled                 | Trucker, Taxi, Dog Walker |
| `"custom"`   | Custom payment logic per action                | Fishing, Powerlines       |
| Per-item     | Pay per individual task completed              | Cleaner, Delivery         |

```lua
-- Example: On Job End (Miner)
payment = {
    mode = "onJobEnd",
    completionBonus = 0,
    coopMode = "full",
}

-- Example: Distance-based (Trucker)
payment = {
    mode = "distance",
    perHundredMeters = 10,
    illegalMultiplier = 2.0,
    maxDamageDeduction = 0.5,
    coopMode = "full",
}

-- Example: Custom (Fishing)
payment = {
    mode = "custom",
    deliveryBonus = 150,
    completionBonus = 0,
    coopMode = "full",
}
```

### XP Rewards

```lua
xprewards = {
    oreExtracted = 25,        -- XP per ore extracted
    jobCompleted = 500,       -- XP on job completion
}
```

### Vehicle Configuration

```lua
runtime = {
    vehicle = {
        model = "bison",
        plate = "MINER",
        fuelOnSpawn = 100.0,
        color = { primary = 6, secondary = 0 },
        spawnLocations = {
            vector4(2952.47, 2748.95, 43.50, 278.43),
            vector4(2953.36, 2743.02, 43.50, 278.43),
        },
        trunkDoors = { 5 },
        toolPositions = { ... },
        cargoPositions = { ... },
    },
}
```

### Quality Tiers (Per-Job Override)

Individual jobs can override the global quality system:

```lua
qualityTiers = {
    { name = "Common",    chance = 55, multiplier = 1.0 },
    { name = "Uncommon",  chance = 25, multiplier = 1.3 },
    { name = "Rare",      chance = 13, multiplier = 1.8 },
    { name = "Legendary", chance = 7,  multiplier = 2.5 },
},
levelPayBonus = 0.02,         -- +2% pay per level
levelChanceBonus = 0.5,       -- Better tier chance per level
```

### Clothes (Work Uniform)

```lua
clothes = {
    male = {
        tshirt_1 = 59, tshirt_2 = 1,
        torso_1 = 38, torso_2 = 0,
        pants_1 = 40, pants_2 = 0,
        shoes_1 = 24, shoes_2 = 0,
        -- ... more components
    },
    female = { ... },
}
```

### Preview System

Each job has a multi-step preview with camera angles:

```lua
preview = {
    playerPosition = vector3(x, y, z),
    steps = {
        {
            title = "Welcome to Mining",
            description = { "Step description line 1", "Line 2" },
            camCoord = vector3(x, y, z),
            camTarget = vector3(x, y, z),
            entities = { ... },
        },
        -- ... more steps
    },
}
```

***

## Need Help?

{% hint style="info" %}
Having configuration issues? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}


# Jobs Guide

Detailed guide for all 23 jobs included in the Lite Jobs Pack. Each job has unique mechanics, payment systems, and progression.

***

## Disabling / Enabling Jobs

You can enable or disable any individual job by editing its config file in `shared/jobs/<jobname>.lua`:

```lua
enabled = true,   -- Set to false to disable this job
```

When a job is disabled, its NPC and blip will not appear on the map and players cannot start it.

***

## Reward Items (All Jobs)

Every job can optionally give bonus items upon mission completion. This feature is configurable per-job in the `missioncompletedItems` section:

```lua
missioncompletedItems = {
    giveItemPlayer = false,          -- Set to true to enable reward items
    dropMode = "weightedPool",
    itemList = {
        { item = "sandwich",     count = 1, chance = 50 },
        { item = "water_bottle", count = 1, chance = 30 },
    },
}
```

| Item           | Default Chance |
| -------------- | -------------- |
| `sandwich`     | 50%            |
| `water_bottle` | 30%            |
| No item        | 20%            |

{% hint style="info" %}
Reward items are **disabled by default** (`giveItemPlayer = false`). To enable, set it to `true` and make sure the items are defined in your framework's inventory.
{% endhint %}

***

## 1. Miner

**Extract valuable ores from underground mines.**

### How It Works

1. Talk to the mining NPC and start the job
2. Travel to the mine entrance (Alamo Sea area or K4MB1 Cave)
3. Use your pickaxe to extract ores from rock formations
4. Collect the ores and deliver them to the processing station

### Ore Types

| Ore     | Rarity    |
| ------- | --------- |
| Coal    | Common    |
| Iron    | Uncommon  |
| Gold    | Rare      |
| Emerald | Very Rare |
| Diamond | Legendary |

### Payment & XP

| Action         | XP     | Payment                       |
| -------------- | ------ | ----------------------------- |
| Extract ore    | 25 XP  | Per item (varies by ore type) |
| Job completion | 500 XP | Completion bonus              |

### Special Features

* 5 custom ore rock props (requires stream resource)
* 2 pickaxe tiers (Rusty Pickaxe, Carbon Pickaxe)
* Processing scale with DUI display
* Full coop support

***

## 2. Lumberjack

**Cut down trees across forests and deliver logs.**

### How It Works

1. Start the lumberjack job from the NPC
2. Travel to the forest area
3. Cut down trees with your hatchet/axe
4. Collect logs and deliver to the lumber yard

### Tree Tiers

| Tier | Tree  | Level Required | Health | XP per Tree | Respawn Time |
| ---- | ----- | -------------- | ------ | ----------- | ------------ |
| 1    | Pine  | 0              | 100    | 30 XP       | 30 seconds   |
| 2    | Oak   | 3              | 200    | 50 XP       | 45 seconds   |
| 3    | Maple | 7              | 300    | 75 XP       | 60 seconds   |

### Payment & XP

| Action         | XP                    | Payment           |
| -------------- | --------------------- | ----------------- |
| Cut tree       | 30-75 XP (tier-based) | Per log delivered |
| Job completion | 500 XP                | Completion bonus  |

### Special Features

* 30 spawn locations across the map
* 3 tree tiers with increasing health and XP rewards
* Tree respawn: 30-60 seconds (tier-dependent)
* Level-based drop quality

***

## 3. Farmer

**Harvest vegetables and deliver crates.**

### How It Works

1. Start the farmer job from the NPC
2. Go to the farm area with planted crops
3. Harvest vegetables from the fields
4. Load crates and deliver to the buyer

### Crop Types

| Crop       | Weight |
| ---------- | ------ |
| Lettuce    | Light  |
| Pumpkin    | Medium |
| Melon      | Heavy  |
| Watermelon | Heavy  |

### Payment & XP

| Action         | XP     | Payment             |
| -------------- | ------ | ------------------- |
| Harvest plant  | 20 XP  | Per crate delivered |
| Job completion | 500 XP | Completion bonus    |

### Special Features

* 4 custom crop props
* Crate system with weight/slot requirements
* Full coop support

***

## 4. Fruit Picker

**Pick fruits from trees.**

### How It Works

1. Start the fruit picker job
2. Travel to the orchard area
3. Pick oranges and apples from trees
4. Deliver harvested fruits

### Produce Types

| Fruit  | XP    |
| ------ | ----- |
| Orange | 25 XP |
| Apple  | 25 XP |

### Payment & XP

| Action         | XP     | Payment                 |
| -------------- | ------ | ----------------------- |
| Pick fruit     | 25 XP  | Per item (weight-based) |
| Job completion | 500 XP | Completion bonus        |

### Special Features

* 20+ tree locations mapped
* Tree-based harvesting animations

***

## 5. Cleaner

**Clean dirt stains across city streets.**

### How It Works

1. Start the cleaner job from the NPC
2. Select a route from the available options
3. Travel to marked stain locations
4. Clean each stain to earn payment

### Routes

| Route   | Area           | Level Required |
| ------- | -------------- | -------------- |
| Route 1 | Pillbox Hill   | 0              |
| Route 2 | La Mesa        | Varies         |
| Route 3 | Textile City   | Varies         |
| Route 4 | Vinewood Hills | Varies         |

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Clean stain    | 30 XP  | $75 per stain    |
| Job completion | 500 XP | Completion bonus |

### Special Features

* 4 different routes with level-locked progression
* Marker-based stain detection system

***

## 6. Power Washer

**Pressure wash dirty surfaces around the city.**

### How It Works

1. Start the power washer job
2. Get your pressure washer equipment
3. Travel to marked dirty surfaces
4. Spray each surface (8 hits required per stain)

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Clean stain    | 35 XP  | $100 per stain   |
| Job completion | 600 XP | Completion bonus |

### Special Features

* Raycast-based surface detection
* Route system similar to cleaner job
* 8 spray hits per stain for realistic feel

***

## 7. Window Cleaner

**Clean windows on city buildings.**

### How It Works

1. Start the window cleaner job
2. Select your route
3. Travel to buildings with dirty windows
4. Clean each window (8 hits per window)

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Clean window   | 30 XP  | $80 per window   |
| Job completion | 500 XP | Completion bonus |

### Special Features

* Multiple routes with different buildings
* Break session minigame system
* Full coop support

***

## 8. Car Detailer

**Wash and polish customer vehicles.**

### How It Works

1. Start the car detailer job
2. Find a customer vehicle at the marked location
3. **Phase 1: Spray Wash** — Spray the vehicle (6 hits)
4. **Phase 2: Polish** — Polish 3 points on the vehicle

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Spray wash     | 40 XP  | $80 per wash     |
| Polish         | 25 XP  | $50 per polish   |
| Job completion | 500 XP | Completion bonus |

### Special Features

* Two-phase detailing process
* Decal stain system on vehicles
* Customer location detection

***

## 9. Scrapyard

**Dismantle junk vehicles and collect scrap metal.**

### How It Works

1. Start the scrapyard job
2. Go to the scrapyard area
3. Use a crowbar to dismantle vehicles
4. Collect metal components
5. Weigh and sell the scrap

### Payment & XP

| Action         | XP     | Payment                   |
| -------------- | ------ | ------------------------- |
| Collect scrap  | 20 XP  | $15 per kg (weight-based) |
| Job completion | 400 XP | Completion bonus          |

### Special Features

* 17 custom spawn locations
* Multiple junk vehicle models
* Weight-based payment system

***

## 10. Hunting

**Hunt animals in the wilderness.**

### How It Works

1. Start the hunting job from the NPC
2. Get your weapon from the available tiers
3. Hunt animals (boar, rabbits, coyotes, etc.)
4. Load carcasses into your vehicle
5. Deliver to the processing station for weighing and selling

### Weapon Tiers

| Tier | Weapon                                   | Level Required | Ammo | Damage Multiplier |
| ---- | ---------------------------------------- | -------------- | ---- | ----------------- |
| 1    | Hunting Rifle (`weapon_musket`)          | 0              | 30   | 1.0x              |
| 2    | Bolt-Action Rifle (`weapon_sniperrifle`) | 3              | 40   | 1.3x              |
| 3    | Heavy Sniper (`weapon_heavysniper`)      | 7              | 50   | 1.6x              |

### Payment & XP

| Action          | XP     | Payment          |
| --------------- | ------ | ---------------- |
| Kill animal     | 15 XP  | —                |
| Deliver carcass | 50 XP  | $15 per kg       |
| Job completion  | 500 XP | Completion bonus |

### Special Features

* 3 weapon tiers unlocked by level with increasing damage multipliers
* Disabled friendly fire during hunting
* Weighing system at processing station

***

## 11. Newspaper Delivery

**Deliver newspapers by bicycle.**

{% hint style="danger" %}
**Required:** This job uses `WEAPON_ACIDPACKAGE` for throwing newspapers. You must define this weapon in your framework or the job will not work. See the [Installation](/scripts/lite-jobs-pack/installation) page for setup instructions.
{% endhint %}

### How It Works

1. Start the newspaper delivery job
2. Get on your bicycle
3. Pick up newspapers from the depot
4. Ride to marked houses and throw newspapers using the newspaper bundle weapon

### Routes

| Route      | Difficulty | Payment |
| ---------- | ---------- | ------- |
| Restaurant | Easy       | $200    |
| Easy Route | Easy       | $300    |
| Hard Route | Hard       | $700    |

### Payment & XP

| Action            | XP     | Payment                |
| ----------------- | ------ | ---------------------- |
| Deliver newspaper | 50 XP  | Route-based ($200-700) |
| Job completion    | 300 XP | —                      |

### Special Features

* Bicycle-based delivery mechanics
* Newspaper throwing physics
* Multiple routes with varying difficulty

***

## 12. Cleanup Collector

**Collect garbage from bins and dumpsters.**

### How It Works

1. Start the cleanup collector job
2. Drive the sanitation truck to marked areas
3. Collect garbage bags from bins/dumpsters (27+ bin model types detected)
4. Load bags onto the truck
5. Deliver to the dump when full

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Collect bag    | 10 XP  | $50 per bag      |
| Truck delivery | 100 XP | $200 bonus       |
| Job completion | 500 XP | Completion bonus |

### Special Features

* 27+ dumpster/bin model detection
* Truck capacity system
* Full coop support

***

## 13. Truck Driver

**Long-haul trucking with trailers.**

### How It Works

1. Start the truck driver job
2. Pick up your truck and attach a trailer
3. Drive to the delivery destination
4. Payment is calculated based on distance driven

### Payment & XP

| Action                     | XP    | Payment           |
| -------------------------- | ----- | ----------------- |
| Per 100m driven            | 10 XP | $10 per 100m      |
| Illegal route (20% chance) | Same  | 2x pay multiplier |

### Special Features

* Distance-based payment system
* 20% chance of high-paying illegal routes
* Police alert mechanics on illegal deliveries
* Trailer attach/detach system
* Queue management for truck assignments

{% hint style="warning" %}
**Illegal Routes:** There is a 20% chance of receiving an illegal delivery with double pay. Police may be alerted — higher levels reduce alert chance!
{% endhint %}

***

## 14. Treasure Hunter

**Underwater treasure hunting (multiplayer encouraged).**

### How It Works

1. Start the treasure hunter job
2. Board a boat with your team
3. Use the tracker/beacon to locate underwater treasures
4. Dive to the treasure location and collect chests
5. Return to the surface and sell your finds

### Payment & XP

| Action         | XP     | Payment             |
| -------------- | ------ | ------------------- |
| Find treasure  | 50 XP  | Custom per treasure |
| Job completion | 500 XP | 1.2x coop bonus     |

### Special Features

* 25 underwater treasure locations
* Shared treasure system for teams
* Tracker/beacon mechanics
* Multiplayer cooperation encouraged — coop bonus for team play

***

## 15. Dog Walker

**Walk dogs for wealthy clients.**

### How It Works

1. Start the dog walker job
2. Pick up the dog from the client
3. Walk the dog along the route (leash mechanics)
4. Handle poop cleanup when needed
5. Return the dog to the client

### Payment & XP

| Action          | XP     | Payment          |
| --------------- | ------ | ---------------- |
| Per 100m walked | 15 XP  | $10 per 100m     |
| Poop cleanup    | 10 XP  | $5 bonus         |
| Job completion  | 100 XP | Completion bonus |

### Special Features

* Leash mechanics with movement restrictions
* Poop management system (random intervals)
* Walking animation sequences

***

## 16. Powerlines

**Repair electrical panels and phone pole wiring.**

### How It Works

1. Start the powerlines job
2. Select a route
3. **Panel Repairs** — Go to houses and fix electrical panels (grid matching minigame)
4. **Pole Repairs** — Use a bucket truck to reach phone poles (welding minigame)

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Repair panel   | 50 XP  | $525 per panel   |
| Repair pole    | 100 XP | $525 per pole    |
| Job completion | 300 XP | Completion bonus |

### Special Features

* Two different repair types with unique minigames
* Bucket truck mechanics for pole access
* Route system with varying panel/pole counts

***

## 17. Delivery

**Package delivery service.**

### How It Works

1. Start the delivery job
2. Go to the depot and load packages into your van
3. Drive to delivery locations (60+ location pool)
4. Hand packages to customer NPCs

### Payment & XP

| Action                          | XP    | Payment           |
| ------------------------------- | ----- | ----------------- |
| Deliver package                 | 50 XP | $225 per delivery |
| Multi-box delivery (30% chance) | 50 XP | $225 per box      |

### Special Features

* 60+ delivery location pool
* 30% chance of multi-box deliveries
* Vehicle trunk/cargo system
* Customer NPC interaction

***

## 18. Warehouse

**Freight and logistics operations.**

### How It Works

1. Start the warehouse job
2. Go to the warehouse facility
3. Load boxes by hand or use a forklift for pallets
4. Place cargo onto the delivery truck
5. NPC truck driver takes the loaded truck

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Load box       | 15 XP  | $50 per box      |
| Load pallet    | 50 XP  | $200 per pallet  |
| Job completion | 100 XP | Completion bonus |

### Special Features

* Forklift or hand-carry mechanics
* NPC truck driver system
* Multiple truck orders to fulfill
* Truck capacity limits

***

## 19. Landscaping

**Garden maintenance and landscaping.**

### How It Works

1. Start the landscaping job
2. Pick up equipment from your work truck (trimmer + shovel)
3. Travel to the route locations
4. Trim overgrown bushes with the trimmer
5. Dig up weeds with the shovel

### Payment & XP

| Action         | XP     | Payment          |
| -------------- | ------ | ---------------- |
| Trim bush      | 30 XP  | $50 per bush     |
| Dig lawn/weed  | 20 XP  | $30 per lawn     |
| Job completion | 500 XP | Completion bonus |

### Special Features

* Two types of tasks (trimming + digging)
* Equipment pickup from work truck
* Multiple routes with different task counts
* Tool management system

***

## 20. Fishing

**Professional fishing with rod tiers and minigame.**

### How It Works

1. Start the fishing job
2. Select your fishing rod and bait
3. Cast your line into the water
4. Complete the fishing minigame to catch fish
5. Deliver your catch for payment

### Fishing Rods

| Rod          | Level Required |
| ------------ | -------------- |
| Standard Rod | 0              |
| Carbon Rod   | Mid-level      |
| Pro Rod      | High-level     |

### Fish Types (9)

| Fish      | Difficulty |
| --------- | ---------- |
| Anchovy   | Easy       |
| Trout     | Easy       |
| Mackerel  | Easy       |
| Salmon    | Medium     |
| Snapper   | Medium     |
| Tuna      | Medium     |
| Grouper   | Hard       |
| Swordfish | Hard       |
| Shark     | Hard       |

### Payment & XP

| Action         | XP     | Payment              |
| -------------- | ------ | -------------------- |
| Catch fish     | 20 XP  | Custom per fish type |
| Deliver catch  | 40 XP  | $150 delivery bonus  |
| Job completion | 400 XP | Completion bonus     |

### Special Features

* 3 fishing rod tiers with level unlocks
* 6 bait types affecting catch rates
* Fishing minigame with difficulty levels
* Free mode option (fish without starting a job)

{% hint style="warning" %}
**Required Items:** Fishing requires 18 inventory items (fish, rods, baits). See the [Installation](/scripts/lite-jobs-pack/installation) page for item setup.
{% endhint %}

***

## 21. Diving

**Underwater diving for treasures and corals.**

### How It Works

1. Start the diving job
2. Board the dive boat
3. Sail to the dive location and drop anchor
4. Dive underwater and complete tasks
5. Collect corals and treasures
6. Surface and sell your finds

### Collectibles

| Item                       | Payment |
| -------------------------- | ------- |
| Dendrogyra Coral (Pillar)  | $1,500  |
| Antipatharia Coral (Black) | $1,500  |

### Payment & XP

| Action                   | XP     | Payment          |
| ------------------------ | ------ | ---------------- |
| Complete underwater task | 25 XP  | —                |
| Sell item                | 50 XP  | $1,500 per coral |
| Job completion           | 500 XP | Completion bonus |

### Special Features

* Boat mechanics with anchor system
* Underwater task system
* 2 coral types to collect

{% hint style="warning" %}
**Required Items:** Diving requires 2 inventory items (corals). See the [Installation](/scripts/lite-jobs-pack/installation) page for item setup.
{% endhint %}

***

## 22. Forklift Operator

**Underground logistics and crate sorting.**

### How It Works

1. Start the forklift operator job
2. Enter the underground depot
3. Get on the forklift
4. Pick up crates and transport to the conveyor belt
5. Sort crates by category

### Crate Categories

| Category  | Value |
| --------- | ----- |
| Jewellery | $200  |
| Antiques  | $150  |
| Tobacco   | $100  |
| Hazard    | $75   |
| Fake      | $50   |

### Payment & XP

| Action         | XP       | Payment               |
| -------------- | -------- | --------------------- |
| Sort crate     | Variable | Per crate value       |
| Job completion | —        | $600 completion bonus |

### Special Features

* 5 crate categories with 3 variants each (15 total crate props)
* Forklift mechanics (raise/lower forks)
* Categorization and sorting system
* Conveyor belt delivery

***

## 23. Tire Technician

**Roadside tire repair service.**

### How It Works

1. Start the tire technician job
2. Get your tools (jack, wrench)
3. Drive to the stranded vehicle location
4. Jack up the vehicle
5. Remove the flat tire
6. Install the new tire
7. Lower the vehicle

### Payment & XP

| Action          | XP     | Payment          |
| --------------- | ------ | ---------------- |
| Complete repair | 70 XP  | $115 per repair  |
| Job completion  | 350 XP | Completion bonus |

### Special Features

* Multi-step realistic repair process
* Jack and tool mechanics
* 6 repair locations across the map
* Multiple vehicle models for service

***

## Need Help?

{% hint style="info" %}
Having questions about a specific job? Join our [Discord server](https://discord.gg/tworst) and open a support ticket.
{% endhint %}




---

[Next Page](/llms-full.txt/1)

