RedM Reports Configuration
Everything is configured in config.lua — a shared script, one file for both client and server.
Restart after editing
config.lua is shared, so a client re-opening the menu is not enough. Run restart pc_report after any config change.
Core
| Key | Default | Description |
|---|---|---|
Config.Debug | false | Verbose console logs. Leave off on live servers. |
Config.MaxReportsPerPlayer | 3 | Max open tickets per player. 0 = unlimited. |
Framework
Config.Framework = {
auto = true, -- auto-detect the first started framework
force = nil, -- 'vorp' | 'rsg' | 'redp' | 'standalone' to pin one
resourceNames = { vorp = 'vorp_core', rsg = 'rsg-core', redp = 'redem_roleplay' },
}Detection order is vorp → rsg → redp, falling back to standalone. If your core's folder name differs from the defaults, set it in resourceNames.
Database
Config.Database = {
enabled = true, -- false = memory only (lost on restart)
tableChecker = true, -- auto create/migrate tables on boot
deleteClosedReportsAfterRestart = false, -- true = wipe closed tickets on boot
}Commands
Config.Commands = {
report = { command = 'report', description = 'Open the report menu' },
refresh_report_permissions = { command = 'refresh_report_permissions' },
}Reports
Categories
{ id = 'report', label = 'Report', icon = 'fa-bullhorn', form = 'report' }form links to a key in Config.Forms.
Priorities
{ id = 'low', label = 'Low', color = '#4caf50', weight = 1 }Config.PriorityPlayerMax = 'high'— the highest weight a reporter may select. Staff can set any.Config.DefaultPriority = 'low'
Forms
Per-category custom fields. Field type can be text, textarea, number, select or player.
report = {
{ id = 'reported', label = 'Who are you reporting?', type = 'player', mapsTo = 'reported_player', required = true },
{ id = 'evidence', label = 'Evidence', type = 'textarea' },
{ id = 'reproducible', type = 'select', options = { 'Always','Sometimes','Once' } },
}mapsTo = 'reported_player' turns a player field into the reported-player target. It is resolved server-side — the client's claim is never trusted.
Keep forms short
Every extra required field is a chance for a frustrated player to abandon the report. Two or three fields cover most of what staff need; the rest comes out in chat.
Anonymous reports
Config.AnonymousReports = { Enabled = true }Anonymous hides the reporter's name and server ID from staff, webhooks, chat and the typing indicator. The license is still retained server-side so tooling keeps working.
Cooldown
Config.Cooldown = { Seconds = 60 } -- anti-spam between creations, 0 = offCommunication
Config.QuickResponses = {
{ label = 'On my way', text = 'A staff member is now handling your report.' }
}
Config.StaffChat = { Enabled = true, History = 50 }Staff tools
Report actions
Built-ins: tp, bring, revive, freeze, heal, strip, jail, warn, kick, ban.
{
id = 'tp', label = 'Go To', icon = 'fa-person-running',
targets = { 'reporter', 'reported' }, -- which party it can act on
permission = 'adminActions', -- capability gate; warn/kick/ban use 'punish'
clientGrant = true, -- for client-side effects (revive/freeze/heal/disarm)
handler = function(staffSrc, targetSrc, ticket) ... end,
}Integrations
Wire kick and ban into your own admin system without touching the core:
Config.Integrations = {
Kick = function(targetSrc, reason, staffSrc) DropPlayer(targetSrc, reason) end,
Ban = function(targetSrc, reason, staffSrc) exports['your_bans']:Ban(targetSrc, reason) end,
}Spectate
Config.Spectate = { Enabled = true, Mode = 'freecam' } -- 'freecam' (any framework) | 'vorp_admin'vorp_admin mode requires that resource installed.
Jail, blocks, tags
Config.Jail = { coords = vector3(2411.0, -1300.0, 46.6) }
Config.Blocks = { Durations = {
{ label = '1 Hour', seconds = 3600 },
{ label = 'Permanent', seconds = 0 },
} }
Config.Tags = { 'cheating', 'griefing', 'rdm', 'vdm', 'bug', 'vip' }Duty & watch
Config.Duty = { Enabled = true, command = 'reportduty', startOnJoin = false }
Config.Watch = { Enabled = true }Only on-duty staff are auto-assigned and receive watch/escalation pings.
Resolution reasons
Config.ResolutionReasons = { 'Resolved', 'No action needed', 'Duplicate', 'Invalid / troll', 'Player offline' }Shown as a dropdown when staff close a report, and stored for statistics.
Media
Config.Media = {
Enabled = true,
Resource = 'screenshot-basic', -- soft dependency
Webhook = { url = '', botName = '...', botIcon = '' }, -- REQUIRED for uploads
Single = { encoding = 'jpg', quality = 0.85 },
Burst = { count = 5, intervalMs = 600, encoding = 'jpg', quality = 0.75 },
OnReportOpen = { enabled = true, subject = 'scene' }, -- auto-capture on create
Staff = { reporter = true, reported = true },
MaxPerReport = 20,
}There is no video on RedM
A "burst" is a rapid series of screenshots presented as a gallery. This is a platform limitation, not a missing feature.
Media auto-disables silently — no errors — if screenshot-basic is not started or the webhook URL is empty.
Report blips
Config.ReportBlips = { Enabled = true, sprite = 'blip_ambient_eagle', scale = 0.2 }Staff toggle open-report location blips from the Dashboard.
Analytics
SLA
Config.SLA = {
Enabled = true, ClaimMinutes = 10, CloseMinutes = 60,
Escalate = { Enabled = true, AfterMinutes = 15, Priorities = { high = true, urgent = true }, Role = '' },
CheckSeconds = 60,
}Escalate.Role takes a Discord role mention such as "<@&123456789>".
Auto-assign, reviews, dashboard
Config.AutoAssign = { Enabled = false, OnlyPriorities = nil } -- e.g. { urgent = true }
Config.Reviews = { Enabled = true, PromptOnClose = true, Min = 1, Max = 5 }
Config.Dashboard = { PageSize = 10, CacheSeconds = 15 }
Config.Performance = { RecentClosedLimit = 50, LazyMessages = true, LazyMedia = true }Localisation & webhooks
| Key | Covers |
|---|---|
Config.LocaleUI | NUI text. Elements with data-i18n in html/index.html pull from here |
Config.Locale.Notification | In-game toast text, icons and colours |
Config.Locale.Webhook | Discord embed titles and message builders |
Config.WebhookRouting | Optional per-category / per-priority webhook overrides for report creation |
Per-action webhook URLs and embed colours live in server/webhook.lua, separately from Config.Media.Webhook.url.
Treat webhook URLs as secrets
Anyone holding the URL can post to that channel. Keep them out of screenshots and out of any config you share when asking for support.