Script docs

Weapon Licenses

A theory test and a timed shooting exam for weapon licenses, graded on the server.

Version
v3.0.0
Frameworks
ESX · QBCore · Qbox
Requires
ox_lib, esx_license (ESX only)
Source
Escrow
resmon
0.00 ms idle · 0.01 ms theory exam open
Updated
6 Oct 2026

Weapon licenses earned the right way: a theory test and a timed shooting-range exam, plus an optional practice mode. ESX, QBCore and Qbox. Everything that grants a license is validated on the server.

Requirements

  • ox_lib
  • One framework: ESX (with esx_license), QBCore or Qbox
  • Optional: ox_inventory (supported: the range weapon is enabled through its weapon wheel)

Install

  1. Drop xex_weaponlicense into your resources folder.
  2. ESX only: run install/esx.sql (adds the two license types).
  3. Add to server.cfg after your framework and ox_lib:
    ensure xex_weaponlicense
  4. Set the language for UI and notifications with setr ox:locale en (or es).

ox_inventory

Nothing to change. The range weapon works through ox_inventory’s public weaponWheel export, which pauses its “weapon not in inventory” check for that player only while the exam or practice lasts. Do not add the range weapon to inventory:ignoreweapons: that would let anyone hold that weapon without owning it.

If you used an older version that required editing ox_inventory, you can revert that change.

Configure

Everything lives in config.lua:

Setting What it does
Config.Framework auto, or force esx / qb / qbox
Config.Key Control that opens each point (38 = E)
Config.Licenses License names. Change them to match your existing license system
Config.RequiredLicense Optional license required before the theory test (e.g. a medical check)
Config.UI Brand name, title, accent colour and optional rules link shown in the test
Config.Theory Location, price, number of questions and correct answers needed
Config.Practical Location, price, weapon, ammo, targets, time limit and countdown
Config.Practice Optional training mode with its own price and settings
Config.Range One player at a time or shared, exit point, target model, target positions and anti-cheat pace

Texts (prompts, notifications, UI and blip names) are in locales/*.json. The theory test is only charged when the player presses Start, so closing the intro is free.

Questions are in questions/<locale>.lua. They are loaded only on the server, so players can never read the answers.

Upgrading from v2 (ESX)

v2 used the license names theoretical_weapons and practical_weapons. Keep them so your players don’t lose their licenses:

Config.Licenses = {
    theory = 'theoretical_weapons',
    practical = 'practical_weapons',
}

In that case you don’t need to run install/esx.sql. Delete the old resource folder before adding v3.

For developers

-- server
local hasLicense = exports.xex_weaponlicense:HasWeaponLicense(source)

bridge/server.lua is open: adapt it if you use a custom framework or license system.

Security

  • The server picks the questions, grades the answers and grants the license.
  • The shooting exam is started, charged and timed on the server; results that are too fast or too slow are rejected.
  • Targets are local objects, so there is nothing to clean up and no entity can be deleted by other players.