> For the complete documentation index, see [llms.txt](https://docs.tworst.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tworst.com/getting-started-installation/scripts/transport-job/configuration.md).

# Configuration

{% hint style="success" %}
**Your settings survive updates.** In 3.0 every value you change is saved by tw-lib in the database (`tw_lib_settings`). When you install an update, tw-lib writes your values back into the new config file. You never have to back up or merge a config again.
{% endhint %}

***

## Three Ways to Change a Setting

| Way                                                        | Best for                                                                                                                                                                                     |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **In game: `/twlib` → Settings**                           | Pay, XP, bonus, cooldown, crew size, level rules, reward split. Saved values apply when the job restarts: use the **Restart** button in the menu.                                            |
| **Edit `defaults/config.lua` / `defaults/coordinate.lua`** | Everything else. Save the file and restart `tw-transportv2`: tw-lib notices your edit and stores it.                                                                                         |
| **Server console: `twlib set`**                            | Quick changes without opening a file: `twlib set tw-transportv2 Config.MaxPlayersInLobby 3`, then `restart tw-transportv2`. Undo with `twlib unset tw-transportv2 Config.MaxPlayersInLobby`. |

{% hint style="info" %}
After tw-lib stores a value, the line in the config file shows the shipped default next to it, for example `Config.MaxPlayersInLobby = 3 --[[twlib:4]]`. That marker is how tw-lib tells your value from ours. Leave it there.
{% endhint %}

***

## Configuration Files

| File                      | What is inside                                                                                                                       |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `defaults/config.lua`     | General settings, interaction, lobby, commands, UI colours, regions & rewards, daily missions, tutorial videos, police alert, levels |
| `defaults/coordinate.lua` | Pallets, destinations and furniture spots of every region                                                                            |
| `defaults/locales/*.lua`  | Texts in 6 languages                                                                                                                 |
| `hooks/*.lua`             | Your own functions (start/end hooks, notifications, prompts)                                                                         |

{% hint style="info" %}
There is no `Config.Framework`, `Config.Inventory` or `Config.SQL` anymore: tw-lib detects them. The old key, fuel and skin functions are gone too; `Config.Vehiclekey`, `Config.Removekeys` and `Config.ChangeClothesSystem` still switch those features off.
{% endhint %}

***

## General

```lua
Config.Locale             = TwLibLocale or 'en' -- Language: en, tr, de, fr, pt, ru
Config.CurrencyUnit       = '$'
Config.ServerName         = "TWORST"            -- Max 10 characters
Config.MoneyType2         = "bank"              -- Reward account: 'bank' or 'cash'
```

### Language

Default is English. To change it, run `twlib set tw-transportv2 Config.Locale tr` in the server console and restart the job, or change `'en'` in the `Config.Locale` line and restart the job. Both are kept across updates.

***

## Interaction

Transport routes every interaction (the job NPC, the forklift, pallets, boxes and furniture) through one system:

```lua
Config.InteractionHandler = 'scriptbase' -- Keep this: every interaction goes through Config.TargetSystem
Config.TargetSystem = {
    enabled  = true,
    resource = 'default',  -- 'default' | 'drawtext' | 'ox_target' | 'qb-target' | 'auto'
    fallback = 'drawtext', -- 'drawtext' | 'none': used when the chosen target resource is not running
    icon     = 'fas fa-truck',
}
```

| `resource`                    | Meaning                                                                                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'default'`                   | The choice made once for **all** Tworst jobs in `/twlib` → Settings → All jobs (or `twlib set tw-lib interaction ox-target`); the prompt if none is set |
| `'drawtext'`                  | The job's own prompts                                                                                                                                   |
| `'ox_target'` / `'qb-target'` | Target eye (the resource must be started)                                                                                                               |
| `'auto'`                      | ox\_target, then qb-target, then the fallback                                                                                                           |

{% hint style="info" %}
`Config.InteractionHandler` also accepts `'ox-target'`, `'qb-target'` or `'drawtext'` to force a choice for this job only, but `'scriptbase'` is the value to keep: it lets `Config.TargetSystem` decide.
{% endhint %}

### How the prompt looks

In prompt mode, `Config.DrawTextUI` decides what draws it:

```lua
Config.DrawTextUI          = 'default' -- 'default' | 'twlib' | 'ox_lib' | 'qb' | 'esx' | 'custom'
Config.InteractionKeyColor = "~g~"
```

| `Config.DrawTextUI`     | Prompt                                                                                      |
| ----------------------- | ------------------------------------------------------------------------------------------- |
| `'default'` / `'twlib'` | The shared Tworst prompt from tw-lib                                                        |
| `'ox_lib'`              | ox\_lib TextUI (ox\_lib must be started)                                                    |
| `'qb'`                  | qb-core DrawText                                                                            |
| `'esx'`                 | GTA help notification                                                                       |
| `'custom'`              | Your own functions: `Config.CustomDrawText` / `Config.CustomHideText` (see [Hooks](#hooks)) |

### Interaction Limits

`Config.Disable` turns interactions off while the player is dead, in a menu, in a vehicle or handcuffed.

***

## Lobby & Job

```lua
Config.MaxPlayersInLobby    = 4     -- Crew size
Config.LetOwnerSplitRewards = true  -- The owner sets each member's share of the money reward
Config.jobCoolDownHours     = 0     -- Hours before the same player can work again (0 = none); every crew member counts
Config.jobLevelCheck        = false -- true: everyone in the lobby needs the region's level
Config.ChangeClothesSystem  = true  -- Job uniform on start; the player's own clothes come back at the end
Config.Vehiclekey           = true  -- Give keys for the job vehicles
Config.Removekeys           = true  -- Take them back at the end
Config.Debug                = false
```

### Who Can Take the Job

```lua
Config.Job = {
    ['job'] = 'all', -- 'all', a job name ('trucker') or a list ({ 'trucker', 'mechanic' })
    ...
}
```

The job rule is checked on the server when a lobby is opened **and** when an invite is accepted. On frameworks without jobs (standalone, vRP, TMC) everyone can join.

### Commands

```lua
Config.Command = {
    jobReset     = "jobresettransport",
    jobLeave     = "jobleavetransport",
    openTutorial = "openTutorialtransport",
}
```

***

## Job Menu Look

The job menu is the shared Tworst job UI inside tw-lib. The transport's colours and pictures:

```lua
Config.UI = {
    primary            = 'rgb(255, 227, 167)',       -- Accent: buttons, titles, bars
    primaryHover       = 'rgb(152, 132, 89)',
    primaryTransparent = 'rgba(142, 124, 79, 0.1)',
    background         = 'rgba(43, 37, 29, 0.94)',
    titleBg            = 'rgba(53, 46, 37, 1)',
    titleFont          = 'Nature',
    logo               = 'img/newLogo.png',          -- Path inside html/ or an https:// link
    scoreIcon          = 'img/teamScoreImg.png',
    regionImage        = 'img/region.png',
    scriptName         = 'Transport',
}
```

`Config.DefaultUIPositions` sets where the crew list, score, invite and notification boxes sit on screen. Players can also move them in game.

***

## Job Location & Blips

```lua
Config.Job = {
    ['coords'] = {
        ['intreactionCoords'] = vector3(-424.27, -2789.87, 6.53),
        ['ped'] = true,
        ['pedCoords'] = vector3(-424.27, -2789.87, 6.53),
        ['pedHeading'] = 312.55,
        ...
    },
    ['blip'] = { show = true, ... },
    ...
}
```

`['missionBlips']` holds the blips of each task step, the vehicles and the delivery point.

***

## Regions & Rewards

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Rockford Hills",
            regionImage = "region.png",
            regionMinimumLevel = 0,
        },
        regionAwards = {
            money = 5000,             -- Paid to the crew at the end
            xp = 1000,
            onlineJobExtraAwards = 2, -- Multiplier per extra crew member
            bonusExtraMoney = 500,    -- Bonus task pay
            bonusExtraXP = 200,
        },
        missioncompletedItems = { giveItemPlayer = false, dropMode = "weightedPool", itemList = { ... } },
        regionJobVehicle = { truckVehicle = "tolpounder", forkliftVehicle = "forklift" },
        vehicleSpawnCoords = { truckCoords = ..., forkliftCoords = ..., ... },
        regionJobTask = {
            { jobName = "transport_trailer_loading",    missionCount = { minAmount = 2, maxAmount = 4 } },
            { jobName = "transport_delivery_truck",     missionCount = { minAmount = 1, maxAmount = 1 } },
            { jobName = "transport_open_box",           missionCount = { minAmount = 1, maxAmount = 1 } },
            { jobName = "transport_delivery_furniture", missionCount = { minAmount = 1, maxAmount = 1 } },
        },
    },
},
```

| Region | Name                | Min. level | Money   | XP     |
| ------ | ------------------- | ---------- | ------- | ------ |
| 1      | Rockford Hills      | 0          | $5,000  | 1,000  |
| 2      | Cypress Flats       | 2          | $10,000 | 3,000  |
| 3      | Paleto Bay          | 4          | $15,000 | 5,000  |
| 4      | Grapeseed (illegal) | 6          | $25,000 | 10,000 |

`missionCount` sets how many pallets and deliveries a region can roll. Region 4 has `illegalMission = true`, which turns on the police alert (see below).

{% hint style="info" %}
Your changes to a region are saved against its `regionID`. If a later update adds, moves or reorders regions, your money and XP stay with the right region. Keep `regionID` values unique and do not reuse them.
{% endhint %}

### Reward Split

With `Config.LetOwnerSplitRewards = true` the lobby owner sets each member's share in the lobby menu: the crew's total (the reward per player × the members online at the payout) is shared by those percentages. With `false` every member gets the same reward.

### Mission Completion Items

`missioncompletedItems` gives extra items at the end of a region. `dropMode = "perItem"` rolls each item on its own; `"weightedPool"` gives one item from the pool. A `chance` of 100 is always given. If a region has no `missioncompletedItems` block, the global one in `Config.Job` is used.

***

## Daily Missions

```lua
['dailyMission'] = {
    { name = 'jobtask_one',   xp = 2500, money = 1000, ... },
    { name = 'jobtask_two',   xp = 1000, money = 3000, ... },
    { name = 'jobtask_three', xp = 2000, money = 3000, ... },
    { name = 'jobtask_four',  xp = 2000, money = 3000, ... },
},
```

{% hint style="info" %}
Changes to a daily mission are saved against its `name`. Keep the names unique.
{% endhint %}

***

## Police Alert

Only on regions with `illegalMission = true`.

```lua
Config.PoliceAlert = {
    enabled  = true,
    testMode = false,             -- true = always send the alert (for testing)
    settings = {
        alertChance          = 75, -- Chance of an alert (%)
        cooldownMinutes      = 2,  -- Time between two alerts
        minPlayersForAlert   = 0,  -- Police needed online
        alertIntervalMinutes = 10, -- How often an alert can come during the illegal run
    },
    dispatchSystem = "ps-dispatch", -- ps-dispatch, ls-dispatch, fl-dispatch, bixbi_dispatch, cd_dispatch, linden_outlawalert, custom
    ...
}
```

`vehicleDetails` chooses what the alert includes (speed, plate, colour, model, doors, heading, driver's gender). For another dispatch script, set `dispatchSystem = "custom"` and write your call in `dispatchExports["custom"]`.

### Police Search

```lua
policeSearch = {
    enabled = true,
    searchSettings = {
        searchTime      = 8000, -- ms
        illegalChance   = 65,   -- Chance of finding illegal cargo (%)
        searchDistance  = 4.0,
        impoundDistance = 4.0,
    },
    policeJobs = { 'police', 'sheriff', 'state', 'lspd', 'bcso', 'sahp', 'park', 'pd', 'policia' },
},
```

A player with one of the `policeJobs` gets a **Search Vehicle** option next to a job truck. If illegal cargo is found, the truck can be impounded.

***

## Tutorial

`Config.TutorialList` holds the tutorial videos. Players open them with `/openTutorialtransport`. Replace a video's `name` with your own link to show your own tutorial.

***

## Levels

`Config.RequiredXP` holds the XP needed for each of the 70 levels. XP above the requirement carries over to the next level.

***

## Texts

All texts are in `defaults/locales/<language>.lua`. Edit the file and restart the job: tw-lib keeps your edited texts across updates like any other setting. A text missing in a language falls back to English.

***

## Hooks

Functions cannot be stored in the database, so they live in `hooks/`. Copy `hooks/hooks.example.lua` to `hooks/my-hooks.lua` and edit it there. An update replaces only the example; your file is never touched, and it is loaded after the settings, so it wins.

```lua
-- Runs for every player in the lobby before the job starts. Return false to stop that player.
Config.startJobFunction = function(source, owneridentifier)
    local job = exports['tw-lib']:GetPlayerJob(source) -- { name, label, grade }; nil on standalone / vRP / TMC
    return job ~= nil and job.name == 'trucker'
end

-- Runs for every player when the job is finished.
Config.endJobFunction = function(source, owneridentifier, scoreAmount)
end

-- Your own notification system. messageData is { text, type } or a text.
Config.sendNotification = function(messageData)
    local text = type(messageData) == 'table' and messageData.text or messageData
    exports['my-notify']:Send(text)
end

-- Your own prompt when Config.DrawTextUI = 'custom'.
-- cards is a list of { text, key }: one entry per prompt in range.
Config.CustomDrawText = function(cards, position)
    exports['my-textui']:Show(cards[1].text, cards[1].key)
end
Config.CustomHideText = function()
    exports['my-textui']:Hide()
end
```

***

## Need Help?

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