> For the complete documentation index, see [llms.txt](https://docs.rainmad.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rainmad.com/resources/map-editor-place-anything/configuration.md).

# Configuration

Everything is in `cfg.lua`, and it is short: what follows is every setting in it, in the order they appear.

## Locale

```lua
cfg.locale = 'en'
```

A file under `locales/`. See Translate the Strings.

## Commands

```lua
cfg.commands = {
    editor = 'map_editor',
    inspect = 'prop_inspect',
    details = 'prop_details',
    join = 'map_join',
    leave = 'map_leave',
}
```

Each one is the word it answers to, and `false` registers none at all, which is useful when a menu or an item opens the editor instead. See [Exports](/resources/map-editor-place-anything/exports.md).

| Command                                  | What                                                                    |
| ---------------------------------------- | ----------------------------------------------------------------------- |
| `/map_editor [playerId]`                 | opens the editor. With an id, on that player's screen instead of yours. |
| `/prop_inspect [model\|hash] [playerId]` | the viewer. `-` in the first slot to reach the second.                  |
| `prop_details <model\|hash>`             | server console only: everything known about one prop.                   |
| `/map_join [no]`                         | answers the last session invitation.                                    |
| `/map_leave`                             | stops watching somebody's session.                                      |

The first three need a permission below. `/map_join` and `/map_leave` answer an invitation, so they ask for none: whoever sent it has the permission.

## Permissions

```lua
cfg.editorPermission = 'command.map_editor'
cfg.adminPermission = 'rm_mapeditor.admin'
cfg.authorizedIdentifiers = {}
```

Two tiers, because opening the editor and running the map are different jobs.

**`editorPermission`** opens the editor. A builder with this sees their own layouts and nothing of anybody else's: they cannot read, rename, overwrite or delete somebody else's, and they cannot stand one up for the server.

**`adminPermission`** sees every layout and can activate one. The broad `command` ace counts as both, which is what an admin panel or a server recipe usually grants.

**`authorizedIdentifiers`** is the first tier without an ace, for one or two people:

```lua
cfg.authorizedIdentifiers = {
    ['license:110000112a4b6c8'] = true,
    ['discord:123456789012345678'] = true,
}
```

Either permission can be `false`, which switches that tier off entirely.

## The Editor

```lua
cfg.editor = { ... }
```

| Setting             | Default   | What                                                                                                                                                                                       |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `reach`             | `300.0`   | how far the placement ray reaches from the camera, in metres                                                                                                                               |
| `area`              | `250.0`   | how far from where a session opens it may place things. The host can widen it or switch it off in the session settings; a caller's own zone or shell overrides it. `false` for no boundary |
| `limit`             | `200`     | objects one session may place. `false` for no cap                                                                                                                                          |
| `gridStep`          | `0.25`    | where the grid button starts. It walks 0.1, 0.25, 0.5, 1 and back to off                                                                                                                   |
| `rotateStep`        | `1.5`     | degrees per rotate press                                                                                                                                                                   |
| `snapDistance`      | `0.25`    | how close a dragged prop's edge comes to a neighbour's before it snaps flush. `0` to never snap                                                                                            |
| `tiers`             | all three | what the standalone editor browses                                                                                                                                                         |
| `allowCustomModels` | `true`    | whether a player may type a model the catalogue does not carry                                                                                                                             |

### Keys

```lua
pickerKey = 'F6', testKey = 'F7', clearKey = 'BACK', bringKey = 'H',
deleteKey = 'DELETE', duplicateKey = 'C', undoKey = 'B',
```

Defaults only. Each is a key mapping, so a player can rebind it under **Settings → Key Bindings → FiveM**, and the on-screen guide reads their own binding back.

### Tiers

```lua
tiers = { 'prop', 'structure', 'element' },
```

| Tier        | What it holds                                                |
| ----------- | ------------------------------------------------------------ |
| `prop`      | standalone objects: furniture, clutter, gear                 |
| `structure` | walls, ceilings, floors, window frames, building shells      |
| `element`   | glass panes, light rigs, decals, emissive strips, vfx planes |

Narrowing this changes browsing only. Every row still ships, the server still answers about it by name or hash, and a resource calling `openEditor` still asks for what it wants.

## The Picker

```lua
cfg.nui = {
    primaryColor = '#f15d38',
    imageBaseUrl = '',
}
```

**`primaryColor`** is the accent of the picker, the panels and the gizmo.

**`imageBaseUrl`** empty ships the thumbnails with the resource: about 80 MB the first time a player opens the picker, cached by hash after. A URL serves them from a host you control instead. Mirror either layout. The picker asks for `atlas.json` and takes the answer:

| Layout | Files                                                           |
| ------ | --------------------------------------------------------------- |
| sheets | `atlas.json` + `atlas_000.webp` … (copy `assets/props/` across) |
| files  | `<model>.webp`, one per prop, no `atlas.json` present           |

## The Layout Library

```lua
cfg.layouts = true
```

On: the browser, the `rm_mapeditor_layouts` table, and the switch that stands a layout up for the whole server. See [Layouts](/resources/map-editor-place-anything/layouts.md).

Off: this resource writes nothing down. It becomes an editor other resources call, and none of the layout handlers are registered for a client to reach.

## Your Own Props

Props your own resources stream, added by hand, go in `data/custom.json`:

```json
[{ "model": "my_chair_01", "label": "Custom Chair", "category": "seating" }]
```

* `tier` defaults to `prop`; `structure` or `element` keeps it out of furnishing sessions
* `tags` are optional, and are what the picker's **Where** menu filters on
* thumbnail: `assets/custom/<model>.webp`, or none and the tile draws empty
* a model this server does not stream never appears, and says nothing

A whole prop pack goes in `data/custom/` instead, one file per pack. See [Adding Props](/resources/map-editor-place-anything/adding-props.md).

Both are yours: copy `cfg.lua`, `data/custom.json` and `data/custom/` forward when you replace the folder with a new version.
