> For the complete documentation index, see [llms.txt](https://visionstore.gitbook.io/visionstore-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://visionstore.gitbook.io/visionstore-docs/scripts/crafting/configuration/benches.md).

# Bench types

Bench types, who may use them, portable bench items and permanent map benches.

A **bench type** is a kind of workstation: which prop it uses, which recipe tabs it shows and who may use it. Every physical bench of that type keeps its **own** level, XP, condition and stash. Bench types are in `config/benches.lua`.

## The included bench types

```lua
Config.Benches = {

    tools = {
        label      = 'Tools Bench',
        model      = 'workbench2',
        categories = { 'tools' },
    },

    medical = {
        label      = 'Medical Bench',
        model      = 'med_bench',
        categories = { 'medical' },
    },

    weapons = {
        label      = 'Weapons Bench',
        model      = 'default',
        categories = { 'weapons', 'attachments' },
        startingXP = 0,
    },
}
```

## Add a bench type

```lua
Config.Benches['kitchen'] = {
    label      = 'Kitchen Counter',
    model      = 'counter',          -- a key from config/models.lua
    categories = { 'food' },         -- tabs, in this order
}
```

Restart, then give one in game: `/crafting give <playerId> kitchen`. For its own item name and icon, add a `kitchen_crafting_bench` item to ox\_inventory (see [Bench items](#bench-items)).

## All fields

| Field        | Default     | What it does                                                                                                                                                                                           |
| ------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `label`      |             | Name shown on the bench.                                                                                                                                                                               |
| `model`      | `'default'` | Prop key from `config/models.lua`: `default`, `workbench2`, `tool_bench`, `lab_desk`, `med_bench`, `counter` or `none`. See [Bench props](/visionstore-docs/scripts/crafting/configuration/models.md). |
| `categories` |             | Category keys shown as tabs, in this order.                                                                                                                                                            |
| `recipes`    | all         | Optional allow-list per category, for example `recipes = { tools = { 'lockpick', 'radio' } }`. A category without an entry shows all its recipes.                                                      |
| `portable`   | `true`      | May exist as an inventory item.                                                                                                                                                                        |
| `startingXP` | `0`         | XP a brand new bench of this type starts with.                                                                                                                                                         |
| `access`     |             | Who may use it, see below.                                                                                                                                                                             |

## Who may use a bench

`access` rules only apply when `Config.Permissions.access = 'benchRules'`, **or** when the bench sets `enforce = true` (then they apply in every mode). See [Permissions](/visionstore-docs/scripts/crafting/configuration/general.md#permissions).

| Field         | Example                                           | Meaning                                                         |
| ------------- | ------------------------------------------------- | --------------------------------------------------------------- |
| `full`        | `true`                                            | Anyone.                                                         |
| `jobs`        | `{ police = true }` or `{ police = { 2, 3, 4 } }` | These jobs, optionally only these grades.                       |
| `gangs`       | `{ ballas = true }`                               | These gangs.                                                    |
| `ace`         | `{ 'crafting.weapons' }`                          | Players with this ACE.                                          |
| `identifiers` | `{ 'license:xxxx' }`                              | These players.                                                  |
| `enforce`     | `true`                                            | Apply these rules even in `'everyone'` mode.                    |
| `unlock`      |                                                   | A hidden NPC unlock id. Set automatically by `config/npcs.lua`. |

Example: a job-only police armory that can't be carried around (included, commented out, in the file):

```lua
police_armory = {
    label      = 'Police Armory',
    model      = 'workbench2',
    categories = { 'weapons', 'attachments' },
    portable   = false,
    access     = {
        jobs    = { police = { 2, 3, 4, 5 } },
        enforce = true,
    },
},
```

## Bench items

A bench in someone's pocket is an ox\_inventory item that carries the bench's permanent id. These settings are in `config/config.lua`:

```lua
Config.PortableBench = {
    item   = 'crafting_bench',
    format = '%s_crafting_bench',

    needsAccessToPlace          = false,
    blockPickupWithActiveCrafts = true,
    anyBenchPickup              = true,
}
```

| Option                        | Default               | What it does                                                                                                         |
| ----------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `item`                        | `'crafting_bench'`    | Generic bench item, used when no per-type item exists.                                                               |
| `format`                      | `'%s_crafting_bench'` | Per-type item name: bench type `tools` → `tools_crafting_bench`. If that item exists, it's used (own name and icon). |
| `needsAccessToPlace`          | `false`               | `false` = holding the item is enough to place it.                                                                    |
| `blockPickupWithActiveCrafts` | `true`                | Refuse pickup while the bench has running or unclaimed crafts.                                                       |
| `anyBenchPickup`              | `true`                | **G** picks up any deployed bench, by anyone allowed to use it.                                                      |

Bench items **must** have `stack = false`, `consume = 0` and `server = { export = 'Chapo_Crafting.usePortableBench' }` (see [Installation](/visionstore-docs/scripts/crafting/installation.md)).

{% hint style="info" %}
A per-type item like `tools_crafting_bench` also works when given with a plain `/giveitem`: it gets its own bench identity the first time it's used. Benches given with `/crafting give` or the `GivePortableBench` export already carry it.
{% endhint %}

## Static benches

Permanent map benches, created on every start. They keep their own level (keyed on `id`, so never change it) and **can never be picked up**. The file ships with this example commented out:

```lua
Config.StaticBenches = {
    {
        id        = 'sandy_tools_bench',   -- unique, never change it
        benchType = 'tools',
        coords    = vec3(1692.25, 3584.03, 34.62),
        heading   = 210.0,
        bucket    = nil,                   -- routing bucket, nil = open world
    },
}
```

* For a bench that's **part of an MLO**, give its bench type `model = 'none'`: no prop is spawned, only the screen.
* **Faster alternative:** stand where you want it and run `/crafting place <type> fixed`. It places a bench that can't be picked up, without editing this file or restarting.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://visionstore.gitbook.io/visionstore-docs/scripts/crafting/configuration/benches.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
