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

# Configuration

> Everything lives in shared/config.lua, plus server-only Discord settings in shared/sv_config.lua. Edit, then restart nex_peacetime.

Everything lives in `shared/config.lua`, plus server-only Discord settings in `shared/sv_config.lua`. Edit, then `restart nex_peacetime`.

## Admin access

A player is treated as an admin if **any one** of the following paths matches. Pick whichever fits your server — you don't need to configure all of them.

### 1. ACE permission (recommended)

```lua theme={null}
Config.AcePermission = { 'group.admin', 'simple.pt' }
```

A single string or a list of ACE permissions. The player passes the check if they have any of them. Grant in `server.cfg`:

```
add_ace group.admin simple.pt allow
add_principal identifier.fivem:1234567 group.admin
```

### 2. Identifier whitelist

```lua theme={null}
Config.Admins = {
    -- 'license:0000000000000000000000000000000000000',
    -- 'discord:000000000000000000',
    -- 'fivem:1234567',
}
```

Empty by default. Each entry is matched against **all** of the player's identifiers (license, steam, discord, fivem, ip), prefix included. When a player runs `/ptmenu` and is denied, the server console prints their full identifier list — copy one straight in.

### 3. Framework auto-detection

No configuration needed. If QBCore / QBox or ESX is running, the script asks the framework directly: QBCore players pass with the `admin` or `god` permission, or a player group of `admin`, `superadmin`, `mod`, or `god`; ESX players pass when `getGroup()` returns one of those groups. On servers without a framework this check is a silent no-op.

### 4. Custom framework hook

```lua theme={null}
Config.CustomAdminCheck = function(src)
    return false
end
```

Runs server-side. Return `true` to grant admin. Use this if your admin system isn't ACE-based, for example:

```lua theme={null}
Config.CustomAdminCheck = function(src)
    -- ESX:
    local x = ESX.GetPlayerFromId(src)
    return x and x.getGroup() == 'admin'
    -- QBCore:
    -- return exports['qb-core']:GetCoreObject().Functions.HasPermission(src, 'admin')
end
```

### 5. Panic override (testing only)

```lua theme={null}
Config.DebugAlwaysAdmin = false
```

<Danger>
  When `true`, **every** connected player is an admin and can toggle peacetime or wipe restrictions. Use it only during initial setup, then flip it back before going live.
</Danger>

## Command

```lua theme={null}
Config.Command = 'ptmenu'
```

The only command. Rename it if it clashes with another resource. Permission is checked server-side, so there's no ACE `command.*` entry to maintain — see [Commands](/nex_peacetime/commands).

## Locale

```lua theme={null}
Config.Locale = 'en'
```

Every visible string — menu labels, the HUD indicator, toast notifications, and the denial message — lives in `locales/en.json`. To translate, copy it to e.g. `locales/de.json`, translate the values (keep the keys), and set `Config.Locale = 'de'`. Unknown or invalid locales fall back to English.

## Default restrictions

```lua theme={null}
Config.DefaultRestrictions = {
    firing         = true,
    aiming         = true,
    weaponSwap     = true,
    melee          = true,
    vehicleWeapons = true,
    throwables     = true,
    explosives     = true,
}
```

Written to GlobalState on first start only — this table is the initial seed. Admins change restrictions live from the menu afterwards.

## Duration presets

```lua theme={null}
Config.DurationPresets = {
    { label = '15m', seconds = 15 * 60 },
    { label = '30m', seconds = 30 * 60 },
    { label = '1h',  seconds = 60 * 60 },
    { label = '2h',  seconds = 2 * 60 * 60 },
    { label = '∞',   seconds = nil },
}
```

The chips shown in the enable flow. `seconds = nil` means indefinite. Admins can always enter a custom duration from the menu regardless of what you list here.

## Restriction presets

```lua theme={null}
Config.RestrictionPresets = {
    {
        label = 'Full',
        restrictions = {
            firing = true, aiming = true, weaponSwap = true, melee = true,
            vehicleWeapons = true, throwables = true, explosives = true,
        },
    },
    {
        label = 'Light',
        restrictions = {
            firing = true, aiming = true, weaponSwap = false, melee = false,
            vehicleWeapons = true, throwables = true, explosives = true,
        },
    },
    {
        label = 'Off',
        restrictions = {
            firing = false, aiming = false, weaponSwap = false, melee = false,
            vehicleWeapons = false, throwables = false, explosives = false,
        },
    },
}
```

One-click presets in the restrictions block of the menu. Tweak the included sets or add your own.

## UI styling

```lua theme={null}
Config.UI = {
    accent = '#4888e9',

    indicator = {
        position         = 'top-center',   -- top-left | top-center | top-right | bottom-left | bottom-center | bottom-right
        showWhenDisabled = false,
        animation        = 'slide',        -- slide | fade | none
    },

    toast = {
        position = 'top-right',            -- top-right | top-left | bottom-right | bottom-left
        duration = 4500,                   -- ms before auto-dismiss
    },
}
```

* `accent` is the only color you set. It highlights primary buttons, selected chips, active toggles, the indicator dot and countdown, and info toasts. Buttons are outlined and tinted rather than solid-filled, so any brightness stays readable.
* `indicator` controls the HUD banner shown on every player's screen while peacetime is active. Its text lives in the locale file.
* `toast` controls the custom in-game notifications.

<Info>
  The menu does not expose these settings — edit them here and restart the resource for changes to apply.
</Info>

## Control groups

```lua theme={null}
Config.ControlGroups = {
    firing         = { { 0, 24 }, { 0, 257 } },
    aiming         = { { 0, 25 }, { 0, 68 } },
    weaponSwap     = { { 1, 37 }, { 0, 12 }, { 0, 13 }, { 0, 14 }, { 0, 15 }, { 0, 16 }, { 0, 17 } },
    melee          = { { 0, 140 }, { 0, 141 }, { 0, 142 }, { 0, 143 }, { 0, 263 }, { 0, 264 } },
    vehicleWeapons = { { 0, 69 }, { 0, 70 }, { 0, 92 }, { 0, 114 }, { 0, 331 } },
    throwables     = { { 0, 58 } },
    explosives     = { { 0, 47 } },
}
```

The exact game controls each restriction category disables, as `{ controlGroup, controlId }` pairs. Edit to extend or trim the lockdown — for example, add more control IDs under `melee` if a custom keybind slips through. The `firing` category additionally calls `DisablePlayerFiring` every frame.

## Discord logging

Server-only settings in `shared/sv_config.lua`. The file is loaded via `server_scripts`, so it is never downloaded to clients and your webhook URLs stay private.

<Warning>
  Keep `shared/sv_config.lua` out of the `shared_scripts` block in `fxmanifest.lua`. Anything loaded there is sent to every player, and your webhooks would leak.
</Warning>

```lua theme={null}
Config.Discord = {
    enabled = false,   -- master switch; while false, nothing is ever sent
    webhook = '',      -- default webhook URL

    -- Optional per-event webhooks; nil or '' falls back to the default above.
    webhooks = {
        enabled      = nil, -- peacetime turned ON
        disabled     = nil, -- peacetime turned OFF by an admin
        expired      = nil, -- peacetime auto-ended (timer elapsed)
        restrictions = nil, -- restriction toggles changed
        denied       = nil, -- a non-admin tried to open the menu
    },

    -- Which events to log.
    log = {
        enabled      = true,
        disabled     = true,
        expired      = true,
        restrictions = true,
        denied       = false, -- can be noisy; off by default
    },

    botName   = 'Peacetime',
    avatarUrl = '',

    -- Left border colour of each embed (hex 0xRRGGBB).
    colors = {
        enabled      = 0x2ECC71,
        disabled     = 0xE74C3C,
        expired      = 0x95A5A6,
        restrictions = 0x3498DB,
        denied       = 0xF1C40F,
    },

    includeIdentifiers = true,
}
```

To enable logging: set `enabled = true` and paste a webhook URL (Discord → **Server Settings** → **Integrations** → **Webhooks** → **New Webhook** → **Copy URL**) into `webhook`. Use the `webhooks` table to split events across channels. With `includeIdentifiers = true`, embeds for player-triggered events include the acting player's full identifier list for accountability.
