> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elementlabs.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom settings

> Add your server's own settings to the settings screen, next to the game's.

A custom settings category is a tab on the settings screen, after the game's own: Display,
Graphics, Audio and the rest. Its rows look and behave like the game's: the arrow keys and a pad
move through them, left and right change a value, and the column beside them shows each row's
description.

The map keeps nothing. It shows the values you give it, tells you when the player changes one, and
leaves saving and applying them to you.

## Calls

```lua theme={null}
exports.element_3d_pausemenu:RegisterSettings(category)
```

| Export | Signature |
| - | - |
| `RegisterSettings` | `(category: table) => boolean` |
| `UpdateSettings` | `(id: string, patch: table) => boolean` |
| `RemoveSettings` | `(id: string) => boolean` |
| `SetSettingValue` | `(id: string, setting: string, value: any) => boolean` |
| `GetSettingValue` | `(id: string, setting: string) => any` |

A category belongs to the resource that registered it. Only that resource can update it, remove it
or set its values, and it is removed when that resource stops. Registering an id another resource
owns is refused.

## Fields

### The category

| Field | Type | Default | Meaning |
| - | - | - | - |
| `id` | `string` | required | No spaces. |
| `label` | `string` | required | The text on the tab. |
| `order` | `number` | `0` | Where the tab sits among the other custom ones. They all come after the game's. |
| `sections` | list | required | Groups of rows, each `{ title?, settings }`. `title` is drawn above the group. |
| `onChange` | function | required | Called when the player changes a value or presses an action. See [What happens](#what-happens). |

### A setting

| Field | Type | Meaning |
| - | - | - |
| `id` | `string` | Required, no spaces, unique within the category. |
| `label` | `string` | Required. The row's name. |
| `type` | `string` | Required. `toggle`, `list`, `slider` or `action`. |
| `value` | see below | Required except for `action`. The value the row shows now. |
| `description` | `string` | What the row is for, shown beside the list while the row is selected. |
| `locked` | `boolean` | Shown but not editable: the server has decided it. |

| Type | `value` | Extra fields |
| - | - | - |
| `toggle` | `boolean` | None. Drawn with the game's own Off and On. |
| `list` | `string` | `options`: a list of at least two `{ value = string, label = string }`. `value` is one of them. |
| `slider` | `number` | `min` and `max`, and `step` (default `1`). `value` is put on the nearest step. At most 1000 steps. |
| `action` | none | None. A row that only fires, such as "Reset tutorial". |

## What happens

`onChange(id, value, previous)` is called on the client when the player changes a row, with the
setting's id, its new value and the one it had. An action calls it with the action's id and no
values. Return `false` to refuse a change: the row goes back to the value it had and the player is
told it was not accepted. Anything else keeps the new value. An `onChange` that throws refuses the
change too, and the error is written to the console.

Save the value, apply it and send it to your server from `onChange`. When the value changes on your
side (loaded from a database, or forced by the server) call `SetSettingValue`. It does not call
`onChange`, and an open settings screen shows the new value at once.

## Errors

`RegisterSettings` answers `false` and writes the reason to the console when the category or any
setting does not read: a missing id or label, an unknown type, a `value` that does not fit its type
or is not one of its options, a slider whose `min` is not below its `max`. Nothing is registered.

`SetSettingValue` answers `false` for a value the setting cannot hold, for an action, and for a
category of another resource. A category registered or removed while the settings screen is open
appears or disappears the next time it opens; a change to one already shown is drawn at once.

## Example

```lua theme={null}
local saved = json.decode(GetResourceKvpString('hud') or '{}')

local function settings()
  return {
    id = 'hud',
    label = 'HUD',
    sections = {
      { title = 'Speedometer', settings = {
        { id = 'speedo', label = 'Speedometer', type = 'toggle', value = saved.speedo ~= false,
          description = 'Shows your speed while driving.' },
        { id = 'units', label = 'Units', type = 'list', value = saved.units or 'kmh',
          options = { { value = 'kmh', label = 'km/h' }, { value = 'mph', label = 'mph' } } },
        { id = 'opacity', label = 'Opacity', type = 'slider', min = 0, max = 100, step = 5,
          value = saved.opacity or 80 },
      } },
      { settings = {
        { id = 'firstPerson', label = 'First person in vehicles', type = 'toggle', value = true,
          locked = true, description = 'Set by the server.' },
        { id = 'resetTutorial', label = 'Reset tutorial', type = 'action' },
      } },
    },
    onChange = function(id, value)
      if id == 'resetTutorial' then
        TriggerServerEvent('hud:resetTutorial')
        return
      end
      saved[id] = value
      SetResourceKvp('hud', json.encode(saved))
    end,
  }
end

AddEventHandler('el:pausemenu:ready', function()
  exports.element_3d_pausemenu:RegisterSettings(settings())
end)
```

## Related

* [Exports](https://docs.elementlabs.net/products/3d-pause-menu/reference/exports.md)
* [Pages](https://docs.elementlabs.net/products/3d-pause-menu/reference/pages.md)
* [Settings](https://docs.elementlabs.net/products/3d-pause-menu/configuration/settings.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.