> 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/placement.md).

# Placement

The placement editor, its keys, the server-side validation rules and no-build zones.

When a player uses a bench item, a placement preview appears. The final spot is always checked again on the server: collisions, slopes, water, vehicles and no-build zones. Settings are in `config/config.lua`.

## Modes

```lua
Config.Placement = {
    mode            = 'ghost',
    allowModeSwitch = true,
    -- ...
}
```

| Mode                | What it is                                                                                |
| ------------------- | ----------------------------------------------------------------------------------------- |
| `'ghost'` (default) | A see-through preview in front of the player, driven by the keyboard. No extra resources. |
| `'object_gizmo'`    | Drag-and-drop with the **object\_gizmo** resource (must be running).                      |

With `allowModeSwitch = true`, players can switch between the two with **TAB** during placement.

## Keys

```lua
keybinds = {
    rotateLeft   = 'LEFT',
    rotateRight  = 'RIGHT',
    moveAway     = 'UP',
    moveCloser   = 'DOWN',
    moveUp       = 'PAGEUP',
    moveDown     = 'PAGEDOWN',
    snapToGround = 'LMENU',
    confirm      = 'RETURN',
    cancel       = 'X',
    switchMode   = 'TAB',
},
```

| Key                 | Action                                    |
| ------------------- | ----------------------------------------- |
| ← / →               | Rotate                                    |
| ↑ / ↓               | Move away / closer                        |
| Page Up / Page Down | Raise / lower                             |
| Left Alt            | Snap to the ground                        |
| **Enter**           | Place                                     |
| X                   | Cancel (the item stays in your inventory) |
| TAB                 | Switch placement mode                     |

### Ghost movement

```lua
ghost = {
    rotateSpeed   = 60.0, -- degrees / second
    distanceSpeed = 1.2,  -- metres / second
    heightSpeed   = 0.6,  -- metres / second
    minDistance   = 0.8,
    maxHeight     = 1.5,
    minHeight     = -1.5,
},
```

## Validation rules

```lua
maxDistance              = 6.0,
requireGround            = true,
groundTolerance          = 0.05,
maximumFloatDistance     = 0.08,
maximumGroundPenetration = 0.03,
maxSlope                 = 12.0,

allowWater    = false,
allowVehicles = false,

preventObjectOverlap   = true,
preventBenchOverlap    = true,
benchClearance         = 0.15,
validatePlayerPosition = true,

lockPitch = true,
lockRoll  = true,
allowYaw  = true,
allowXYZ  = true,

spawnDistance  = 1.8,
scanInterval   = 80,
sessionTimeout = 180,
```

| Option                                         | Default | What it does                                                                |
| ---------------------------------------------- | ------- | --------------------------------------------------------------------------- |
| `maxDistance`                                  | `6.0`   | Max distance from the player to the bench.                                  |
| `requireGround`                                | `true`  | The bench must sit on the ground (with the float / penetration tolerances). |
| `maxSlope`                                     | `12.0`  | Steepest ground allowed, in degrees.                                        |
| `allowWater` / `allowVehicles`                 | `false` | Allow placing in water / on vehicles.                                       |
| `preventObjectOverlap` / `preventBenchOverlap` | `true`  | Refuse spots that collide with objects / other benches.                     |
| `benchClearance`                               | `0.15`  | Gap kept between benches, in metres.                                        |
| `validatePlayerPosition`                       | `true`  | Check there's room to stand at the bench.                                   |
| `lockPitch` / `lockRoll`                       | `true`  | Keep the bench level.                                                       |
| `spawnDistance`                                | `1.8`   | How far in front of the player the preview appears.                         |
| `sessionTimeout`                               | `180`   | Seconds before an abandoned placement expires.                              |

## No-build zones

Spheres where benches can't be placed:

```lua
Config.RestrictedZones = {
    { coords = vec3(441.0, -982.0, 30.7), radius = 60.0, label = 'Mission Row PD' },
    { coords = vec3(298.0, -584.0, 43.3), radius = 60.0, label = 'Pillbox Hospital' },
}
```

(Both examples ship commented out.)

## Your own placement rule

For anything more specific (for example: only inside owned properties), edit this function in `config/config.lua`. Return `false` plus an optional locale key to refuse:

```lua
Config.CanPlaceBench = function(src, benchType, coords, bucket)
    return true
end
```

See [Bridges and config hooks](/visionstore-docs/scripts/crafting/developers/bridges.md#config-hooks) for an example.

## Housing and instances

Benches only exist in the "instance" they were placed in. By default that's the player's `instance` state bag, then their routing bucket, which covers housing scripts that give each interior its own bucket. rtx\_housing is supported out of the box. See [Bridges](/visionstore-docs/scripts/crafting/developers/bridges.md#housing).


---

# 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/placement.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.
