> 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/scripts/gardener-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, interaction style. 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-gardenerv2`: tw-lib notices your edit and stores it.                                                                                       |
| **Server console: `twlib set`**                            | Quick changes without opening a file: `twlib set tw-gardenerv2 Config.MaxPlayersInLobby 3`, then `restart tw-gardenerv2`. Undo with `twlib unset tw-gardenerv2 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, truck paint, flower planting rules, levels |
| `defaults/coordinate.lua` | Lawns, bushes, trees and flower beds of every region                                                                                                       |
| `defaults/locales/*.lua`  | Texts in 7 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, ar
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-gardenerv2 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

Gardener uses one setting for every interaction, the job NPC as well as the mowers, branches and flowers:

```lua
Config.InteractionHandler = 'default'
Config.TargetSystem = {
    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-briefcase', -- FontAwesome icon on ox_target / qb-target options
}
```

| `resource`                    | Meaning                                                                                                                                                                              |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `'default'`                   | Follow `Config.InteractionHandler`, which by default is the choice made once for **all** Tworst jobs in `/twlib` → Settings → All jobs (or `twlib set tw-lib interaction ox-target`) |
| `'drawtext'`                  | Tworst prompt with **E**; no target resource needed                                                                                                                                  |
| `'ox_target'` / `'qb-target'` | Target eye (the resource must be started)                                                                                                                                            |
| `'auto'`                      | ox\_target, then qb-target, then the fallback                                                                                                                                        |

### How the prompt looks

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

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

| `Config.DrawTextUI` | Prompt                                                                                      |
| ------------------- | ------------------------------------------------------------------------------------------- |
| `'twlib'`           | The shared Tworst prompt from tw-lib (default, same look in every Tworst job)               |
| `'default'`         | Same as `'twlib'`                                                                           |
| `'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)) |

***

## 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)
Config.jobLevelCheck        = false -- true: everyone in the lobby needs the region's level
Config.onlyOneGroup         = false -- true: only one crew can work a region at a time
Config.ChangeClothesSystem  = true  -- Job uniform on start; the player's own clothes come back at the end
Config.Vehiclekey           = true  -- Give keys for the truck
Config.Removekeys           = true  -- Take them back at the end
Config.Debug                = false
```

### Who Can Take the Job

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

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     = "jobresetgardenerv2",
    jobLeave     = "jobleavegardenerv2",
    openTutorial = "openTutorialgardenerv2",
}
```

### Truck Paint

```lua
Config.VehicleColour = false -- false = the truck keeps its own colours; { primary, secondary } forces a paint (GTA colour ids)
```

***

## Job Menu Look

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

```lua
Config.UI = {
    primary     = '#77ff7c',                 -- Accent: buttons, titles, bars; lighter and darker shades follow from it
    background  = 'rgba(27, 35, 27, 0.94)',
    titleBg     = 'rgba(35, 44, 35, 1)',
    titleFont   = 'Nature',
    logo        = 'img/newLogo.png',         -- Path inside html/ or an https:// link
    scoreIcon   = 'img/teamScoreImg.png',
    regionImage = 'img/region.png',
    scriptName  = 'Gardener',
}
```

`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.Gardenerv2 = {
    ['coords'] = {
        ['intreactionCoords'] = vector3(-670.43, -888.99, 24.5),
        ['ped'] = true,
        ['pedCoords'] = vector3(-670.43, -888.99, 24.5),
        ['pedHeading'] = 186.29,
        ['pedHash'] = 0x49EA5685,
    },
    ['blip'] = { show = true, ... },
    ...
}
```

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

***

## Regions & Rewards

```lua
['regionData'] = {
    {
        regionID = 1,
        regionInfo = {
            regionName = "Vespucci Beach",
            regionImage = "region.png",
            regionMinimumLevel = 0,
        },
        regionAwards = {
            money = 5000,             -- Base money for one player
            xp = 1000,
            onlineJobExtraAwards = 2, -- How the pay changes with crew size (see below)
            bonusExtraMoney = 0,      -- Bonus task pay
            bonusExtraXP = 0,
        },
        missioncompletedItems = { giveItemPlayer = false, dropMode = "weightedPool", itemList = { ... } },
        regionJobVehicle = { vehicle = "tolsadler", mower = "mower", ExtraVehicle = true },
        vehicleSpawnCoords = { ... },
        mowerSpawnCoords = { ... },
        jobDeliverCoords = vector3(-685.23, -885.77, 24.57),
        flowerArea = { { coords = vector3(-1315.52, -1463.46, 4.31), area = 15.0 } },
        regionJobTask = {
            { jobName = "lawnmowing",  missionCount = { minAmount = 20, maxAmount = 30 } },
            { jobName = "prunegrass",  missionCount = { minAmount = 8,  maxAmount = 12 } },
            { jobName = "branch",      missionCount = { minAmount = 1,  maxAmount = 2 } },
            { jobName = "plantflower", missionCount = { minAmount = 4,  maxAmount = 10 } },
            { jobName = "wateringcan", bonusJob = true },
            { jobName = "takeBranch",  bonusJob = true },
        },
    },
},
```

| Region | Name           | Money   | XP    |
| ------ | -------------- | ------- | ----- |
| 1      | Vespucci Beach | $5,000  | 1,000 |
| 2      | Pillbox Hill   | $7,500  | 1,000 |
| 3      | Rockford Hills | $10,000 | 1,000 |
| 4      | Richman        | $12,500 | 1,000 |
| 5      | Vinewood Hills | $12,500 | 1,000 |

`missionCount` sets how many of each task a region can roll. The spots themselves are in `defaults/coordinate.lua`.

### Crew Size and Pay

`onlineJobExtraAwards` decides how the pay changes with more players:

| Value               | Effect (example: $5,000, 2 players)              |
| ------------------- | ------------------------------------------------ |
| Positive, e.g. `2`  | Team bonus: 5000 × 2 = $10,000 per person        |
| Negative, e.g. `-2` | Team penalty: 5000 / (2 × 2) = $1,250 per person |
| `0`                 | Split equally: 5000 / 2 = $2,500 per person      |

{% 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.

***

## 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 %}

***

## Flower Planting

Flowers can only be planted on suitable ground. Two methods are available:

```lua
Config.UseZBasedGroundValidation = false -- false = ground type list, true = height check
```

**Ground type list** (`false`, default): only the ground types in `Config.MaterialHashes` (dirt, sand, mud, grass) are allowed. `Config.AllowUnknownSurfaces = true` also allows ground types the game does not report.

**Height check** (`true`): compares the player's height with the planting spot.

```lua
Config.GroundValidation = {
    maxHeightDifference = 1.5,  -- Metres above the player
    minHeightDifference = -0.5, -- Metres below the player
    checkSlope = true,
    maxSlope = 0.5,             -- 0.0 = flat, 1.0 = wall
    checkWater = true,          -- No planting under water
}
```

***

## Tutorial

`Config.TutorialList` holds the tutorial videos. Players open them with `/openTutorialgardenerv2`. 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, identifier)
    local job = exports['tw-lib']:GetPlayerJob(source) -- { name, label, grade }; nil on standalone / vRP / TMC
    return job ~= nil and job.name == 'mechanic'
end

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

-- Your own notification system instead of the built-in one.
Config.sendNotification = function(message, messageType)
    exports['my-notify']:Send(message, messageType)
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 %}
