Configuration
Configuration for Advanced AOP.
Configuration
Advanced AOP is configured through config.lua. Below is the current configuration file.
Config File
config.lua
Config = {}
--[[
Teedle AOP Resource
Functional AOP + Peacetime system for FiveM.
REQUIRED:
- PolyZone must be started before this resource.
PERMISSIONS:
- ACE permissions are recommended.
- Discord staff roles should be mapped to ACE groups through your Discord permissions resource.
]]
Config.Framework = 'qbcore' -- 'qbcore' or 'standalone'
Config.Command = 'aop'
Config.PeacetimeCommand = 'pt'
Config.UseAcePermissions = true
Config.AcePermission = 'teedle.aop'
-- Optional fallback identifiers. Leave empty if you only want ACE.
Config.AdminIdentifiers = {
-- 'license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-- 'discord:123456789012345678',
}
-- Optional QBCore job permission fallback.
-- Example: ['police'] = 8 means police grade 8+ can use AOP commands.
Config.AllowedJobs = {
-- ['police'] = 8,
}
Config.Permissions = {
-- true = staff with ACE/allowed job can ignore AOP enforcement.
-- false = staff are treated like normal players, useful for testing or stricter staff rules.
staffBypass = false,
}
Config.QBCoreSpawnProtection = {
-- Keeps AOP from teleporting/pushing players while qb-spawn/qb-apartments/qb-clothing
-- are doing new-character setup. This prevents new characters from being ripped out of
-- their selected apartment before they can create clothing and properly exit.
enabled = true,
-- Applied immediately when the AOP resource starts on a QBCore client.
-- This prevents AOP from grabbing a brand-new character before qb-spawn/apartments opens.
-- It is cleared early when the player leaves the apartment.
initialStartupSeconds = 0,
-- Applied when QBCore reports the player loaded. New-character flows can take a while.
-- It is cleared early when the player leaves the apartment.
onPlayerLoadedSeconds = 8,
-- Applied while the spawn selector/apartment selector is open.
whileSpawnUISeconds = 900,
-- Applied after the spawn UI closes or apartment spawn events fire.
-- Keep this short because apartment/clothing protection will cover first-character setup.
afterSpawnSeconds = 12,
-- Applied when clothing/character customization opens.
clothingSeconds = 900,
-- Applied when qb-apartments tells the server the player is inside an apartment.
-- This is cleared as soon as qb-apartments flips their inside metadata back to false.
apartmentInsideSeconds = 900,
-- Applied right after the player exits their apartment into the city.
-- After this short buffer, normal AOP enforcement resumes.
afterApartmentExitSeconds = 10,
-- If false, the resource will NOT auto-correct location directly after qb-spawn closes.
-- This should stay false for QBCore apartment/first-character flows.
correctAfterSpawn = true,
}
Config.Display = {
enabled = true,
x = 0.670,
y = 1.325,
scale = 0.42
}
Config.Notify = {
-- 'auto' tries qb-core, mythic_notify, then native GTA notification/chat.
type = 'auto',
-- Since this resource has its own AOP NUI warning screen, these are off by default.
-- Turn one on only if you also want qb-core/native/mythic notifications for that action.
useOutOfAOP = false,
useBorder = false,
useTeleport = false,
-- Peacetime still uses small notifications by default because it is separate from the AOP screen.
usePeacetime = true,
}
Config.TextUI = {
-- Fallback DrawText card used only when Config.WarningScreen.enabled is false.
enabled = true,
title = 'OUT OF AOP',
message = 'You are outside the current AOP. Return back to the active patrol area or face staff punishments.',
subMessage = 'Current AOP: %s',
blockedTitle = 'AOP BORDER',
blockedMessage = 'You cannot cross into the restricted area.',
teleportTitle = 'RETURNING TO AOP',
teleportMessage = 'You are being moved back to the current AOP.',
countdownLabel = 'Teleporting in',
x = 0.5,
y = 0.215,
width = 0.62,
height = 0.205,
titleScale = 0.82,
messageScale = 0.37,
countdownScale = 0.58,
background = true
}
-- Warning UI screen type. Keep this simple:
-- 1 = main/top warning UI
-- 2 = compact bottom-right warning UI
Config.ScreenType = 1
Config.WarningScreen = {
enabled = true,
-- true keeps the screen visible the whole time someone is out of AOP.
persistentWhileOutOfAOP = true,
-- true shows the teleport timer on the screen.
showCountdown = true,
-- true darkens and blurs the game view behind the warning card.
blurBackground = false,
-- true adds a subtle vignette and red pulse.
pulse = false,
-- true plays a warning beep when the warning first opens.
playSound = true,
-- How often the NUI countdown text updates. Lower = smoother, but no need to go crazy.
updateIntervalMs = 250,
-- These are auto-selected by Config.ScreenType, but can stay here as fallback values.
position = 'top', -- ScreenType 1 = top, ScreenType 2 = bottom_right
backdropOpacity = 0.00,
-- You said you do NOT want a separate AOP BORDER screen.
-- When false, hitting the border only uses the normal notification/pushback behavior.
showBorderScreen = false,
-- Text shown on the NUI screen.
outTitle = 'OUT OF AOP',
outSubtitle = 'You are outside the current Area of Patrol.',
outBody = 'Return to the active patrol area immediately or you will be moved back automatically.',
borderTitle = 'AOP BORDER',
borderSubtitle = 'Restricted patrol boundary.',
borderBody = 'You cannot cross into this restricted area.',
teleportTitle = 'RETURNING TO AOP',
teleportSubtitle = 'Moving you back to the active patrol area.',
teleportBody = 'You ignored the AOP boundary or spawned outside the active patrol zone.',
countdownLabel = 'Teleporting in',
currentAopLabel = 'Current AOP',
statusLabel = 'Status',
}
Config.Debug = {
-- Shows PolyZone debug polygons when supported. Keep false on live servers.
debugPoly = false
}
Config.BoundaryVisuals = {
enabled = true,
drawGroundLines = true,
-- Solid wall draws filled red panels from the ground into the sky.
-- This looks much more like a real barrier than thin DrawLine-only borders.
drawSolidWall = true,
-- 'dense_lines' is the most reliable FiveM wall rendering. It draws a heavy red grid from ground to sky.
-- 'poly' can look smoother on some servers, but dense_lines is harder to miss.
wallRenderMode = 'poly', -- 'poly' or 'dense_lines'
wallHeight = 360.0,
wallBottomOffset = -4.0,
wallPanelLength = 10.0,
wallPanelAlpha = 150,
-- Dense wall controls. Lower spacing = more solid looking, but more draw calls.
verticalLineSpacing = 5.0,
horizontalLineSpacing = 6.0,
sideThickness = 3,
sideOffset = 0.35,
-- Extra red grid lines on the wall make the edge easier to see while driving.
drawWallGrid = true,
wallGridSpacing = 8.0,
-- DrawLine itself cannot be thickened in FiveM, so this adds a few nearby lines
-- to fake a thicker glowing border at ground level.
groundLineThickness = 4,
groundLineOffset = 0.18,
maxDrawDistance = 2600.0,
color = { r = 255, g = 0, b = 0, a = 255 }
}
Config.MapBlips = {
enabled = true,
-- Native GTA/FiveM cannot draw a real striped polygon on the pause map.
-- This uses many overlapping red radius blips to make the restricted area look filled instead of dotted.
cleanOutlineOnly = false,
showAreaBlips = false,
showBoundaryDots = false,
showBoundaryMarkers = true,
-- Better pause-map fill: stacked native area blips that behave more like a filled restricted zone.
showHazardArea = true,
-- Legacy circle fill. Keep false unless you prefer the dotted/circle look.
showHazardFill = false,
markerSpacing = 220.0,
markerSprite = 1,
markerScale = 0.34,
markerName = 'AOP Boundary',
hazardAreaStripHeight = 175.0,
hazardAreaSampleSpacing = 135.0,
hazardAreaAlpha = 52,
hazardAreaMaxBlips = 120,
hazardGridSpacing = 220.0,
hazardGridRadius = 260.0,
hazardGridAlpha = 34,
hazardGridMaxBlips = 850,
hazardGridName = 'Restricted AOP Area',
-- Legacy settings, only used if you manually turn showAreaBlips/showBoundaryDots back on.
areaAlpha = 25,
boundaryAlpha = 75,
boundaryDotSpacing = 300.0,
boundaryDotRadius = 12.0,
color = 1 -- GTA blip color 1 = red
}
Config.DefaultCommand = 'state'
Config.KillswitchCode = 'off'
Config.MoveTimerSeconds = 120 -- Time before auto action if player remains out of AOP.
Config.WarningIntervalSeconds = 10
Config.TimerTickSeconds = 1
Config.SpeedWarningMph = 100
Config.Enforcement = {
-- Hard border blocks normal players from crossing from the allowed AOP side into the banned/out-of-AOP side.
-- If a player spawns/loads already outside AOP and no safe position is known yet, they get warnings/timer handling.
hardBorder = true,
-- standalone default behavior: physically push/teleport players.
standaloneMode = 'pushback', -- 'pushback', 'teleport', or 'warn'
-- qbcore default behavior: warning first, but hardBorder still blocks crossing at the wall.
qbcoreMode = 'pushback', -- 'warn', 'pushback', or 'teleport'
-- If true, QBCore players who remain out of AOP longer than Config.MoveTimerSeconds get teleported.
qbcoreTeleportAfterTimer = true,
-- If true, standalone players who remain out of AOP longer than Config.MoveTimerSeconds get teleported.
standaloneTeleportAfterTimer = true,
-- Attempts to correct location after QBCore finishes loading/spawning the player.
qbcoreCheckAfterSpawn = false,
qbcoreSpawnCheckDelaySeconds = 3,
-- Legacy fallback. Config.Permissions.staffBypass is the main setting now.
staffBypass = false,
-- If someone is already outside AOP after a resource restart and no last-valid spot exists,
-- teleport is the only reliable way to stop them from driving deeper into the banned side.
noLastValidAction = 'warn', -- 'teleport' or 'warn'
-- Jail/prison zone bypass.
jailBypass = true
}
Config.DefaultTeleport = vector3(2042.7, 3445.5, 44.69)
Config.TeleportsByClientAop = {
statewide = vector3(2042.7, 3445.5, 44.69),
blaine = vector3(2042.7, 3445.5, 44.69),
santos = vector3(161.45, -987.28, 31.3),
}
-- /aop command options.
-- clientAop decides what large out-of-AOP zone gets created:
-- statewide = only banned sub-zone enforcement
-- blaine = Los Santos is out of AOP
-- santos = Blaine County is out of AOP
-- banned can be nil, sandy, paleto, legion, grove
Config.AOPOptions = {
['state'] = { label = 'Statewide', clientAop = 'statewide', banned = nil },
['bc'] = { label = 'Blaine County', clientAop = 'blaine', banned = nil },
['ls'] = { label = 'Los Santos', clientAop = 'santos', banned = nil },
['sb'] = { label = 'Statewide | Sandy Banned', clientAop = 'statewide', banned = 'sandy' },
['pb'] = { label = 'Statewide | Paleto Banned', clientAop = 'statewide', banned = 'paleto' },
['lg'] = { label = 'Statewide | Legion Banned', clientAop = 'statewide', banned = 'legion' },
['gb'] = { label = 'Statewide | Grove Banned', clientAop = 'statewide', banned = 'grove' },
['bcsb'] = { label = 'Blaine County | Sandy Banned', clientAop = 'blaine', banned = 'sandy' },
['bcpb'] = { label = 'Blaine County | Paleto Banned', clientAop = 'blaine', banned = 'paleto' },
['lslg'] = { label = 'Los Santos | Legion Banned', clientAop = 'santos', banned = 'legion' },
['lsgb'] = { label = 'Los Santos | Grove Banned', clientAop = 'santos', banned = 'grove' },
}
-- Zone definitions.
-- IMPORTANT: length/width are the real PolyZone dimensions.
-- The old resource used options.scale, but BoxZone ignores that for size.
Config.ZoneDefinitions = {
jailZone = {
center = vector3(1688.0, 2585.8, 52.57),
length = 70.0,
width = 70.0,
options = { name = 'jailZone', heading = 40, debugPoly = false }
},
sandy = {
center = vector3(1800.8, 3760.57, 35.59),
length = 430.0,
width = 320.0,
options = { name = 'sandy', heading = 30, debugPoly = false }
},
paleto = {
center = vector3(-158.0, 6345.6, 31.57),
length = 1100.0,
width = 900.0,
options = { name = 'paleto', heading = 40, debugPoly = false }
},
legion = {
center = vector3(195.4, -936.6, 36.2),
length = 340.0,
width = 330.0,
options = { name = 'legion', heading = 250, debugPoly = false }
},
grove = {
center = vector3(105.0, -1940.6, 20.57),
length = 145.0,
width = 120.0,
options = { name = 'grove', heading = 47, debugPoly = false }
},
-- Out-of-AOP area when current AOP is Blaine County.
-- This represents the Los Santos side below the county line.
blaine = {
center = vector3(920.0, -660.0, 55.0),
length = 5600.0,
width = 4500.0,
options = { name = 'blaine', heading = 338, debugPoly = false }
},
-- Out-of-AOP area when current AOP is Los Santos.
-- This represents the Blaine County side above the county line.
ls = {
center = vector3(260.0, 3400.0, 80.0),
length = 6500.0,
width = 4400.0,
options = { name = 'ls', heading = 338, debugPoly = false }
},
}
-- More accurate large out-of-AOP shapes for county-line AOPs.
-- These are used when PolyZone is available. BoxZone fallback remains in Config.ZoneDefinitions.
Config.PolygonDefinitions = {
-- Banned sub-zones use polygon shapes matching the visible red wall lines.
-- This keeps enforcement lined up with what players actually see.
sandy = {
points = {
vector2(1659.27, 3505.70),
vector2(2092.28, 3755.65),
vector2(1942.33, 4015.53),
vector2(1509.33, 3765.51),
},
options = { name = 'sandy', minZ = -100.0, maxZ = 1000.0, debugGrid = false }
},
paleto = {
points = {
vector2(-347.42, 5795.03),
vector2(417.02, 6437.58),
vector2(33.03, 6895.95),
vector2(-732.02, 6251.81),
},
options = { name = 'paleto', minZ = -100.0, maxZ = 1000.0, debugGrid = false }
},
legion = {
points = {
vector2(164.34, -776.28),
vector2(322.21, -833.77),
vector2(226.40, -1096.88),
vector2(68.60, -1039.43),
},
options = { name = 'legion', minZ = -100.0, maxZ = 1000.0, debugGrid = false }
},
grove = {
points = {
vector2(51.99, -1942.58),
vector2(103.17, -1887.61),
vector2(158.00, -1938.75),
vector2(106.91, -1993.53),
},
options = { name = 'grove', minZ = -100.0, maxZ = 1000.0, debugGrid = false }
},
-- When AOP is Blaine County, this polygon represents the Los Santos/out-of-AOP side of the border.
blaine = {
points = {
vector2(-3300.0, 3350.0),
vector2(-2712.2, 3067.07),
vector2(-2592.4, 3018.27),
vector2(-1306.17, 2498.27),
vector2(-1283.17, 2490.27),
vector2(-800.17, 2295.27),
vector2(-704.17, 2255.27),
vector2(-209.17, 2055.27),
vector2(-82.17, 2005.27),
vector2(-50.17, 1991.27),
vector2(73.0, 1944.1),
vector2(444.8, 1791.1),
vector2(524.5, 1761.6),
vector2(1036.2, 1552.2),
vector2(1305.5, 1443.4),
vector2(1696.1, 1285.6),
vector2(2028.7, 1153.3),
vector2(2685.4, 885.9),
vector2(4500.0, -4000.0),
vector2(-4500.0, -4000.0),
vector2(-4500.0, 3800.0),
},
options = { name = 'blaine', minZ = -100.0, maxZ = 1000.0, debugGrid = false }
},
-- When AOP is Los Santos, this polygon represents the Blaine County/out-of-AOP side of the border.
ls = {
points = {
vector2(-3300.0, 3350.0),
vector2(-2711.1, 2534.4),
vector2(-2477.1, 2435.57),
vector2(-2074.19, 2277.17),
vector2(-1472.6, 2035.28),
vector2(-854.8, 1785.6),
vector2(-757.3, 1746.2),
vector2(262.57, 1334.22),
vector2(1206.57, 951.78),
vector2(1221.9, 945.5),
vector2(1302.9, 901.2),
vector2(1560.8, 809.7),
vector2(2518.0, 423.0),
vector2(2615.11, 383.7),
vector2(4500.0, 4500.0),
vector2(-4500.0, 4500.0),
},
options = { name = 'ls', minZ = -100.0, maxZ = 1000.0, debugGrid = false }
}
}
Config.BoundaryLines = {
sandy = {
{1659.27, 3505.70, 36.91, 2092.28, 3755.65, 34.13},
{1659.27, 3505.70, 36.91, 1509.33, 3765.51, 35.15},
{2092.28, 3755.65, 34.13, 1942.33, 4015.53, 33.29},
{1509.33, 3765.51, 35.15, 1942.33, 4015.53, 33.29},
},
paleto = {
{-347.42, 5795.03, 38.22, -732.02, 6251.81, 24.78},
{-347.42, 5795.03, 38.22, 417.02, 6437.58, 31.41},
{-732.02, 6251.81, 24.78, 33.03, 6895.95, 30.12},
{417.02, 6437.58, 31.41, 33.03, 6895.95, 30.12},
},
legion = {
{164.34, -776.28, 32.72, 322.21, -833.77, 30.29},
{164.34, -776.28, 32.72, 68.6, -1039.43, 30.46},
{322.21, -833.77, 30.29, 226.4, -1096.88, 30.29},
{226.4, -1096.88, 30.29, 68.6, -1039.43, 30.46},
},
grove = {
{51.99, -1942.58, 22.49, 103.17, -1887.61, 22.04},
{106.91, -1993.53, 21.3, 51.99, -1942.58, 22.49},
{103.17, -1887.61, 22.04, 158.0, -1938.75, 20.28},
{106.91, -1993.53, 21.3, 158.0, -1938.75, 20.28},
},
blaine = {
{-2712.2, 3067.07, 13.83, -2592.4, 3018.27, 16.53},
{-2592.4, 3018.27, 16.53, -1306.17, 2498.27, 22.53},
{-1306.17, 2498.27, 22.53, -1283.17, 2490.27, 21.53},
{-1283.17, 2490.27, 21.53, -800.17, 2295.27, 78.53},
{-800.17, 2295.27, 78.53, -704.17, 2255.27, 81.53},
{-704.17, 2255.27, 81.53, -209.17, 2055.27, 142.53},
{-209.17, 2055.27, 142.53, -82.17, 2005.27, 180.53},
{-82.17, 2005.27, 180.53, -50.17, 1991.27, 180.53},
{-50.17, 1991.27, 180.53, 73.0, 1944.1, 169.3},
{73.0, 1944.1, 169.3, 444.8, 1791.1, 231.3},
{444.8, 1791.1, 231.3, 473.1, 1779.1, 229.1},
{473.1, 1779.1, 229.1, 524.5, 1761.6, 227.2},
{524.5, 1761.6, 227.2, 1020.7, 1558.4, 171.6},
{1020.7, 1558.4, 171.6, 1036.2, 1552.2, 171.2},
{1036.2, 1552.2, 171.2, 1282.0, 1452.8, 99.4},
{1282.0, 1452.8, 99.4, 1305.5, 1443.4, 99.5},
{1305.5, 1443.4, 99.5, 1515.8, 1358.8, 97.7},
{1562.2, 1339.6, 96.0, 1515.8, 1358.8, 97.7},
{1562.2, 1339.6, 96.0, 1653.3, 1303.4, 86.3},
{1653.3, 1303.4, 86.3, 1696.1, 1285.6, 86.7},
{1696.1, 1285.6, 86.7, 1751.1, 1263.3, 133.7},
{1751.1, 1263.3, 133.7, 1766.4, 1257.4, 135.2},
{1766.4, 1257.4, 135.2, 2028.7, 1153.3, 192.4},
{2028.7, 1153.3, 192.4, 2000.4, 1162.6, 189.3},
{2000.4, 1162.6, 189.3, 2358.8, 1017.8, 80.0},
{2358.8, 1017.8, 80.0, 2391.3, 1004.7, 84.8},
{2391.3, 1004.7, 84.8, 2489.4, 965.1, 85.6},
{2489.4, 965.1, 85.6, 2574.4, 930.7, 83.3},
{2574.4, 930.7, 83.3, 2685.4, 885.9, 77.0},
},
ls = {
{-2711.1, 2534.4, 20.0, -2477.1, 2435.57, 18.43},
{-2477.1, 2435.57, 18.43, -2074.19, 2277.17, 40.85},
{-2074.19, 2277.17, 40.85, -1472.6, 2035.28, 64.38},
{-1472.6, 2035.28, 64.38, -854.8, 1785.6, 173.6},
{-854.8, 1785.6, 173.6, -838.2, 1777.2, 173.8},
{-838.2, 1777.2, 173.8, -757.3, 1746.2, 201.3},
{-757.3, 1746.2, 201.3, 262.57, 1334.22, 239.43},
{262.57, 1334.22, 239.43, 1206.57, 951.78, 147.03},
{1206.57, 951.78, 147.03, 1221.9, 945.5, 143.6},
{1221.9, 945.5, 143.6, 1280.6, 905.9, 106.8},
{1280.6, 905.9, 106.8, 1302.9, 901.2, 105.8},
{1302.9, 901.2, 105.8, 1479.2, 842.4, 77.73},
{1479.2, 842.4, 77.73, 1560.8, 809.7, 77.13},
{1560.8, 809.7, 77.13, 2518.0, 423.0, 113.9},
{2518.0, 423.0, 113.9, 2615.11, 383.7, 109.13},
},
}
-- Backwards compatibility for old files that used lowercase config.
config = Config
Next
AOP Screens
→
Last updated August 6, 2026