> 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/scenes-draw-everywhere/configuration.md).

# Configuration

Everything lives in `rm_scenes/cfg.lua` (open file, comments included). The important knobs, in the order they appear:

## Locale & bridges

```lua
cfg.locale = 'en'            -- locales/<locale>.json
cfg.bridge = {
    framework = 'auto',      -- 'auto' | 'qb' | 'esx' | 'standalone'
    notification = 'builtin' -- any file name from bridge/notification/
}
```

`'auto'` tries qb, then esx, then falls back to standalone. Every notification adapter is an open file in `rm_scenes/bridge/notification/` and its file name is the value for `cfg.bridge.notification`; the annotation in `cfg.lua` lists the set bundled with your version. Copy an adapter to integrate a resource we don't cover.

## Entry points

```lua
cfg.commands = {
    create = 'create_scene', -- string | false
    list   = 'scenes',       -- string | false
}
```

Set either to `false` to remove the command; the [server exports](/resources/scenes-draw-everywhere/events-and-exports.md) keep working, so you can route entry through an item, a menu or another script instead.

## Interface

```lua
cfg.nui = {
    primaryColor = '#f15d38', -- accent color of the whole interface

    overlays = {              -- where the hint overlays dock on screen
        placement = 'bottom-right', -- key hints while selecting the surface area for a new scene
        depth     = 'bottom-right', -- key hints while adjusting depth / repositioning before saving
        saving    = 'bottom-right', -- spinner shown while a confirmed scene save uploads
        list      = 'top-left',     -- the scene list panel
    },

    fonts = {                 -- extra editor fonts on top of the built-in system list
        { label = 'Bangers', family = 'Bangers, cursive', url = 'https://fonts.googleapis.com/css2?family=Bangers&display=swap' },
    },
}
```

Fonts load at runtime when the editor opens; nothing ships in the resource. `url` accepts a CSS stylesheet (Google Fonts embed URL) or a direct font file, and `family` must match the font's real family name.

## Scenes

```lua
cfg.scenes = {
    renderDistance     = 250.0,
    occlusion          = true,  -- skip drawing scenes hidden behind walls
    limitPerPerson     = false, -- number | false; admins bypass
    deleteUnseenAfter  = 14,    -- days; delete scenes nobody rendered for this long; 0 disables
    allowHttpImageUrls = false, -- editor URL images: also accept plain http:// links
}
```

* `occlusion` runs light line-of-sight checks so scenes behind buildings cost nothing to draw. Disable it if you see scenes pop late around complex geometry.
* `deleteUnseenAfter` prunes at resource start. It's what removes drawings stuck on objects that no longer spawn; "seen" means any player actually rendered the scene.
* `allowHttpImageUrls` relaxes the editor's URL image rule from https-only to https+http, for hosts without TLS. The bytes travel unencrypted and the private-address guard still applies; keep it off unless you need it.

### Durations

```lua
cfg.scenes.durations = {
    { label = '1 day', value = 86400 },
    -- ...
    { label = 'Permanent', value = 31557600 },
}
```

The list the save dialog offers; the server only accepts values from it. Labels are free text. The stock `Permanent` entry is one year in seconds; raise the value if that's not permanent enough.

### Controls

```lua
cfg.scenes.controls = {
    save         = 201, -- ENTER
    createPoints = 24,  -- LEFT MOUSE BUTTON
    cancel       = 202, -- BACKSPACE (ESC always cancels too)
    backward     = 44,  -- Q
    forward      = 46,  -- E
    reposition   = 45,  -- R
    merge        = 47,  -- G
    showMerges   = 74,  -- H
    resizeGrow   = 241, -- SCROLLWHEEL UP
    resizeShrink = 242, -- SCROLLWHEEL DOWN
    resizeWidth  = 21,  -- LEFT SHIFT (hold: resize width only)
    resizeHeight = 36,  -- LEFT CTRL (hold: resize height only)
}
```

Values are [FiveM control ids](https://docs.fivem.net/docs/game-references/controls/). The `resize*` keys fine-tune a locked selection before the editor opens: scroll grows or shrinks it, and holding the width/height key limits the change to one dimension. The hint overlays always display the labels of whatever you bind here.

### Texture pool

```lua
cfg.scenes.texturePool = {
    max  = 32,   -- runtime textures kept in memory at once (~4 MB each at the size below)
    size = 1024, -- pixel dimensions (width = height) per pooled texture
}
```

The per-client texture memory cap. When more scenes are in range than the pool holds, the farthest ones give up their slot. If dense builds show blank scenes up close, raise `max` and budget the memory cost.

## Permissions

```lua
cfg.auth = {
    onlyAuthorized = false, -- false = everyone can create scenes

    persons = {
        -- ['license:...'] = true,
    },
    jobs = {
        -- ['police'] = {},   -- empty table = whole job, any grade, anywhere
        -- ['mechanic'] = { grades = { 2, 3 }, locations = { { coords = vec3(...), range = 50 } } },
    },
    gangs = {
        -- ['ballas'] = { locations = { { coords = vec3(...), range = 100 } } }, -- qb gangs; same shape as jobs
    },
    admins = {
        -- ['license:...'] = true, -- ace 'command' also counts
    },
}
```

With `onlyAuthorized = true`, creation is limited to listed identifiers, jobs and gangs. A job/gang entry can restrict `grades` and pin creation to `locations` (sphere areas); the location check is enforced **server-side** on every save, move and copy, not just in the preview.

Admins see and manage every scene, bypass `limitPerPerson` and the location restrictions, and get the extra list tools ([Scene list](/resources/scenes-draw-everywhere/scene-list.md)).

### Custom check

```lua
cfg.auth.customCheck = function(identifiers, playerId)
    return true -- or false, or { locations = { { coords = vec3(...), range = 50 } } }
end
```

When set, it replaces the built-in check entirely. Return `true`/`false`, or a table with `locations` to allow creation only inside those areas.

## Advanced

Three optional keys exist for tuning images; the defaults suit most servers, add them under `cfg.scenes` only if you need them:

```lua
cfg.scenes.imageBps         = 128 * 1024       -- per-client streaming rate for scene images
cfg.scenes.imageCacheMax    = 64               -- decoded images a client keeps cached (farthest evicted first)
cfg.scenes.maxImageUrlBytes = 15 * 1024 * 1024 -- size cap for images imported from a URL
cfg.scenes.editorImageBps   = 2 * 1024 * 1024  -- streaming rate for URL images returning to the editor
```

Changing `maxImageUrlBytes` also moves the save, edit and Discord webhook ceilings to match, so a large imported layer can still bake and save. Imported images travel back to the editor on their own lane at `editorImageBps`; saved scenes stay small regardless of import size, because the editor export is capped and re-encoded, and they stream to players at `imageBps`.
