Skip to main content
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.
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

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

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:
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)

Config.DebugAlwaysAdmin = false
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.

Command

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.

Locale

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

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

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

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

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.
The menu does not expose these settings — edit them here and restart the resource for changes to apply.

Control groups

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.
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.
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 SettingsIntegrationsWebhooksNew WebhookCopy 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.