> 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/food-stand/configuration.md).

# Configuration

{% hint style="success" %}
**Your settings survive updates.** The job runs on tw-lib: values you change in `/twlib` or in `config_job.lua` are stored in the database and written back after an update.
{% endhint %}

***

## Configuration Files

These files are open (not escrowed):

| File                                                         | What is inside                                                                                                      |
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `config_job.lua`                                             | Language, interaction, lobby, XP, daily tasks, **economy**, notify, keys, tutorial, work outfit, blips, Discord log |
| `config_station.lua`                                         | Job start point, tow vehicles, trailer, stand types, stations, stock, supplies, orders, register, menu, eating      |
| `config.lua`                                                 | Hand feel at the counter and grill. Change only if you know what you tune                                           |
| `config_sound.lua`                                           | Sounds and stand music                                                                                              |
| `custom_tables.lua`, `trailer_layout.lua`, `steam_tuned.lua` | Trailer layout and props — leave as they are                                                                        |
| `locales/*.lua`                                              | Texts in 14 languages                                                                                               |
| `shared/npc_outfits.lua`                                     | Customer outfits                                                                                                    |
| `items/*.lua`                                                | Item definitions per inventory                                                                                      |
| `tw-foodstandjob_depot/config.lua`                           | Depot name                                                                                                          |
| `tw-foodstandjob_trailers/vehicle_names.lua`                 | Trailer names                                                                                                       |

***

## Changing Settings

| Way                                            | Best for                                                                                                                                                                       |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **In game: `/twlib` → Settings → Food Stands** | Crew size, cooldown, level rules, reward split, interaction, economy multipliers, teleport into the vehicle, keys, tutorial, work outfit. Use the **Restart** button to apply. |
| **Edit the config files**                      | Everything else. Save and restart `tw-foodstandjob`.                                                                                                                           |
| **Server console**                             | `twlib set tw-foodstandjob Config.MaxPlayersInLobby 4`, then `restart tw-foodstandjob`.                                                                                        |

See [tw-lib → Configuration](/tw-lib/tw-lib/configuration.md).

***

## General (`config_job.lua`)

```lua
Config.Locale = TwLibLocale or 'en'      -- en, tr, de, es, fr, hu, ja, nl, pt, ro, ru, sl, sv, zh
Config.InteractionHandler = 'interact'   -- 'interact' | 'ox-target' | 'qb-target' | 'drawtext' | 'auto' | 'default'
Config.UI = { primary = 'rgb(236, 64, 42)', scriptName = 'Food Stands' }
```

| `Config.InteractionHandler`   | Meaning                                                |
| ----------------------------- | ------------------------------------------------------ |
| `'interact'`                  | tw-lib 3D interaction: a dot + \[E] capsule (default)  |
| `'ox-target'` / `'qb-target'` | Target eye                                             |
| `'drawtext'`                  | Key prompt                                             |
| `'auto'`                      | ox\_target or qb-target, whichever runs, else drawtext |
| `'default'`                   | The tw-lib setting for all Tworst jobs                 |

***

## Lobby & Crew

```lua
Config.MaxPlayersInLobby = 3
Config.LetOwnerSplitRewards = false  -- true: the owner sets each member's % share; false: split by job points
Config.jobCoolDownHours = 0          -- 0 = no cooldown
Config.Leaderboard = { enabled = true, limit = 10 }
```

### Who Can Run a Stand

```lua
Config.Job.job = 'all'               -- 'all', a job name or a list ({ 'burgershot' })
Config.Job.typeJobs = {
    -- burger = { 'burgershot', 'police' },
}
```

`typeJobs` locks a single stand type to a job: a listed type can only be taken out by that job, the rest follow `Config.Job.job`. It checks the player who starts the shift.

***

## Economy

All money in one place. `1.0` = default, `0.5` = half, `2.0` = double. Changes apply after a restart.

```lua
Config.Economy = {
    supplyCost = 1.0,   -- ingredient / supply prices (lower = more profit)
    menuPrice  = 1.0,   -- food sale prices (the owner still picks 0.5-2x in the menu)
    tip        = 1.0,   -- customer tips
    refund     = 0.8,   -- share of unused stock paid back at shift end (0 = none, 1 = full)
    customers  = 1.0,   -- customer density (2.0 = twice as often)
    work = { burger = 1.25, sandwich = 1.05, taco = 1.0, hotdog = 1.0, pizza = 1.25,
             doner = 1.15, sushi = 1.0, bowl = 1.0, icecream = 1.0 },  -- difficulty bonus per type
}
```

{% hint style="info" %}
With the defaults, each type turns a profit after about 5–10 orders, and makes about 45–55% net after 30 orders. `work` pays harder types more per main dish.
{% endhint %}

The whole `Config.Economy` block can be changed in `/twlib`.

***

## Levels & Daily Tasks

```lua
Config.RequiredXP = { 1000, 1500, 2000, ... }     -- 30 levels
Config.Job.regionData = {
    { regionID = 1, regionInfo = { regionName = 'Food Stand', regionMinimumLevel = 0 },
      regionAwards = { xp = 20 } },               -- XP per delivered order, for everyone on the shift
}

Config.Job.dailyMission = {
    { name = 'jobtask_one',   kind = 'deliver', count = 25,   xp = 300, money = 500 },
    { name = 'jobtask_two',   kind = 'ontime',  count = 15,   xp = 300, money = 500 },
    { name = 'jobtask_three', kind = 'player',  count = 3,    xp = 400, money = 750 },
    { name = 'jobtask_four',  kind = 'earn',    count = 2000, xp = 500, money = 1000 },
}
```

| `kind`    | Counts                       |
| --------- | ---------------------------- |
| `deliver` | Delivered orders             |
| `ontime`  | On-time NPC deliveries       |
| `player`  | Orders from player customers |
| `earn`    | Money earned from sales      |

Tasks reset every 24 hours. `{}` = no daily tasks.

***

## Vehicles, Blips & Keys

```lua
Config.Job.vehiclePlate = 'BURG%03d'     -- %d = job number
Config.Job.teleportVehicle = true        -- shift start: owner in the driver seat, crew in passenger seats
Config.Job.vehicleBlips = {
    truck   = { enabled = true, sprite = 225, color = 0,  scale = 0.8, label = 'Work Vehicle' },
    trailer = { enabled = true, sprite = 225, color = 17, scale = 0.8 },
}
Config.Job.publicBlip = { enabled = true, sprite = 628, color = 2, scale = 0.75, shortRange = false }
Config.Vehiclekey = true                 -- keys for every lobby member
Config.Removekeys = true                 -- taken back when the shift ends
```

`publicBlip` shows every open stand on the map for **all** players and removes it when the stand closes. `false` = only the crew sees its own stand.

***

## Notifications

```lua
Config.Notify = 'own'
```

| Value      | Meaning                                                                                                                                                                                                                                                             |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'own'`    | The job's own notification (default)                                                                                                                                                                                                                                |
| `'auto'`   | Finds a running notify script (okokNotify, brutal\_notify, mythic\_notify, codem-notification, ox\_lib, ...), else the framework's, else the job's own                                                                                                              |
| a name     | `'okokNotify'`, `'ox_lib'`, `'qb'`, `'qbx'`, `'esx'`, `'brutal_notify'`, `'mythic_notify'`, `'codem-notification'`, `'codem-supreme-notification'`, `'g-notifications'`, `'is_ui'`, `'lation_ui'`, `'vms_notifyv2'`, `'wasabi_uikit'`, `'17mov_Hud'`, `'gs-notify'` |
| a function | Your own export                                                                                                                                                                                                                                                     |

```lua
Config.Notify = function(text, kind, ms)
    exports['my-notify']:Send(text, kind, ms)   -- kind = 'error' | 'success' | 'info' | 'primary'
end
```

If the chosen script fails, the job's own notification shows instead — never lost, never shown twice.

***

## Tutorial & Work Outfit

```lua
Config.Tutorial = true                -- step cards on the first shift + one card per station on first use
Config.ChangeClothesSystem = false    -- true: work outfit at shift start, own clothes back at the end
Config.JobClothes = { male = { ... }, female = { ... } }
```

***

## Discord Shift Log

```lua
Server = {
    discordWebhook = '',
    botToken = '',
    botName = 'Food Stands',
    botLogo = 'https://...',
}
```

{% hint style="info" %}
`Server` values are server-only: tw-lib never sends them to players and keeps them in the database, not in the file.
{% endhint %}

***

## Job Start Point (`config_station.lua`)

```lua
Config.Job = {
    locationMode = 'single',   -- 'single' | 'perType'
    npc = {
        model = 's_m_m_linecook',
        pos   = vector4(-1501.383, -902.673, 10.125, 230.0),
        blip  = { enabled = true, sprite = 628, color = 17, scale = 0.8, label = 'Food Stands' },
    },
    vehicle = {
        models = { 'sadler', 'rebel2' },   -- tow vehicles with a hitch; one is picked at random
        spawn  = vector4(-1474.753, -918.230, 9.067, 230.0),
        slots  = { ... },                  -- where vehicle and trailer spawn (a taken slot is skipped)
    },
    finish = vector4(-1467.859, -924.015, 9.090, 230.0),   -- shift finish marker
    noMap  = { resource = 'tw-foodstandjob_depot', npc = vector4(...), spawn = vector4(...) },
    typeLocations = {},
    ...
}
```

| Mode        | Meaning                                                                                   |
| ----------- | ----------------------------------------------------------------------------------------- |
| `'single'`  | One point for all stand types (default: the depot near Vespucci)                          |
| `'perType'` | Each type at its own point in `typeLocations`; types without a point use the single point |

```lua
typeLocations = {
    burger = { npc = vector4(...), spawn = vector4(...), blip = { ... } },
},
```

`noMap` is where the NPC and the spawn move when the depot is not running. `display` sets the showroom trailers outside the depot.

***

## Stand Types

```lua
types = {
    burger = { label = 'Burger Shot', trailer = 'burgertrailer', ... },
    pizza  = { label = 'Pizza',       trailer = 'pizzatrailer',  ... },
    ...
},
typeOrder   = { 'burger', 'sandwich', 'taco', 'hotdog', 'pizza', 'doner', 'sushi', 'bowl', 'icecream' },
defaultType = 'burger',
```

`label` is the name players see. `typeOrder` is the order in the lobby panel. Remove a type from `typeOrder` to hide it.

***

## Stock & Supplies

* `startStock` / `typeStock` — what a stand has when the shift starts.
* `supply` — the items in the **G** supply menu, each with its own amount and base price; `refundRate` for unused stock; `stockMax` per item.
* `delivery.courier` — the courier NPC that brings the boxes (`false` = the box appears at once).

Prices are base prices; scale them all with `Config.Economy.supplyCost`.

***

## Orders

```lua
Config.Orders = {
    interval = { min = 22, max = 40 },  -- s between customers at demand 1.0
    maxQueue = 4,
    group    = { chance = 0.15, min = 2, max = 3 },
    waitSec  = 120,                     -- delivered within this = on time
    leaveSec = 190,                     -- not delivered by then = money back, customer leaves
    wish     = { chance = 0.40, twoNo = 0.30, tipMul = 1.5, ... },
    demand   = { start = 1.0, min = 0.30, late = 0.12, fail = 0.25, onTime = 0.03, recoverPerMin = 0.04 },
    payAccount = 'cash',
    pay  = { ownerCut = 0.30, points = { grill = 1, prep = 1, wrap = 2, pack = 1, register = 1 } },
    area = { radius = 40.0, same = 0.75, other = 1.10, min = 0.5, max = 1.3 },
    rep  = { enabled = true, perStar = 0.10, min = 3, ... },
    ...
}
```

| Key                    | Meaning                                                                      |
| ---------------------- | ---------------------------------------------------------------------------- |
| `interval`             | Seconds between two customers at normal demand                               |
| `waitSec` / `leaveSec` | On-time limit / give-up limit                                                |
| `wish`                 | Special requests: chance, a second "No ..." chance, tip multiplier           |
| `demand`               | How late / failed / on-time orders move the demand, and how fast it recovers |
| `pay.ownerCut`         | Owner's share of each delivery before the job-point split                    |
| `pay.points`           | Job points per kind of work                                                  |
| `area`                 | Food area: radius, same-type and other-type multipliers                      |
| `rep`                  | Reputation: star effect on the customer rate                                 |

***

## Register

```lua
Config.Register = {
    enabled = true,
    npcOrders = 'auto',     -- 'auto' = NPC orders go to the kitchen by themselves; 'register' = the cashier enters them
    payAccount = 'bank',    -- player bills are paid from this account
    billSec = 30,           -- an unanswered bill expires
    maxWrong = 2,           -- wrong entries before an NPC leaves (register mode)
    taxRate = 0.10,         -- sales tax, shown to the customer
    orderRequest = true,    -- true: a player must press [E] Place Order before they can be billed
    ...
}
```

***

## Player Menu & Menu Board

```lua
Config.MenuPricing = { min = 0.5, max = 2.0, elastic = 1.2, tip = 0.6, tipMax = 1.5, ... }
Config.MenuBoard   = { enabled = true, near = 25.0, far = 30.0, ... }
```

`min` / `max` are the price limits as a multiple of the base price. `elastic` sets how much a higher price lowers demand for that item, `tip` / `tipMax` how much it lowers tips.

***

## Eating & Drinking

```lua
Config.Consume = {
    enabled = true,
    food  = { hunger = 30, thirst = 0,  ms = 5000, ... },
    drink = { hunger = 0,  thirst = 35, ms = 5000, ... },
    byItem = { tw_heartstopper = { hunger = 60 }, tw_doubleburger = { hunger = 45 }, ... },
}
```

Values are 0–100 (qb / qbx metadata or esx\_status). `byItem` overrides single items.

***

## Sound & Music (`config_sound.lua`)

```lua
Config.Sound = { enabled = true, volume = 0.6, ... }   -- master volume; each player scales it with /standsound 0-100
Config.Music = {
    enabled = true,
    volume = 0.22,      -- level when closest
    range = 20.0,       -- m: not heard beyond this
    maxList = 25,       -- songs per stand
    maxStreams = 3,     -- nearby stands playing at once
}
```

***

## Depot Name (`tw-foodstandjob_depot/config.lua`)

```lua
Config.DepotName = 'STREETWORTH'
```

The name on the outside sign and the lobby board. 3–16 characters: A–Z, 0–9, space and `& - ' .`. Lowercase becomes uppercase; an invalid name keeps STREETWORTH. A long name is shrunk to fit the sign.

***

## Usage Statistics

The job sends anonymous usage counts — no names, IDs or IPs. You can turn them off in `/twlib`. Details: [tworst.tr/privacy](https://tworst.tr/privacy).

***

## Event Protection

Every event a client sends to the job passes one gate on the server:

* **Rate limit** - each player may send each event a limited number of times per second (20 by default, more for the fast sync events). Extra calls are dropped.
* **Error guard** - a broken or forged event prints one red line in the console and does nothing; the job keeps running.
* **Server state only** - pay, stock, orders and XP are counted from the server's own state. A client cannot say "I delivered" or "give me money".

Type `foodstandrpc` in the server console to see how many events were dropped or failed since the start. Nothing to configure.

***

## Need Help?

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