FiveM Docs
Addons

esx_dmvschool

esx_dmvschool adds a theory test and car, motorcycle and truck driving tests to ESX Legacy. Covers licenses, config keys, checkpoints, events and common issues.

esx_dmvschool is the driving school for ESX Legacy. Players first pass a multiple-choice theory test (dmv license) and then take practical road tests for cars (drive), motorcycles (drive_bike) and trucks (drive_truck). Licenses are stored through esx_license, so police and vehicle scripts can check them.

Overview

FactValue
Resourceesx_dmvschool
SideClient + server + NUI
Dependenciesesx_lib, es_extended, esx_license (plus oxmysql)
Licensesdmv, drive, drive_bike, drive_truck

In-game flow

  1. Go to the DMV marker (blip sprite 408) and press E.
  2. Pay for the theory test. Answer 10 questions; 5 correct answers pass and grant dmv.
  3. With dmv, the menu offers the road tests you do not own yet. The test vehicle spawns at VehicleSpawnPoint.
  4. Drive through all checkpoints. Speeding and vehicle damage count as errors. Speed limits switch between residence, town and freeway at certain checkpoints.
  5. At the last checkpoint the vehicle is deleted and, if you passed, the license is granted.

Installation

Database

esx_dmvschool uses the esx_lib SQL catalog and inserts the four licenses rows automatically, labeled in your esx:locale. The bundled esx_dmvschool.sql contains French labels; localized versions live in localization/.

esx_dmvschool.sql (English labels)
INSERT INTO `licenses` (`type`, `label`) VALUES
	('dmv', 'Driving Permit'),
	('drive', 'Drivers License'),
	('drive_bike', 'Motorcycle License'),
	('drive_truck', 'Commercial Drivers License');

server.cfg

server.cfg
ensure esx_license
ensure esx_dmvschool

Configuration

KeyDefaultDescription
Config.DrawDistance10.0Marker draw distance.
Config.MaxErrors5Error budget. More than this ends the test early; you pass only with fewer than this.
Config.SpeedMultiplier3.6Converts m/s to your unit. 3.6 = km/h, 2.236936 = mph.
Config.SpeedingErrorDelay5000Cooldown in ms after a speeding error before the next one can count. Values below 5000 are raised to 5000.
Config.LocaleGetConvar('esx:locale', 'en')Locale used for texts.
Config.Pricessee belowPrice per test type, paid in cash.
Config.VehicleModelssee belowVehicle model per road test.
Config.SpeedLimitssee belowSpeed limit per zone type, in the unit of SpeedMultiplier.
Config.ZonesDMVSchool, VehicleSpawnPointMarker zones. Type = -1 hides a marker.
Config.CheckPoints16 checkpointsOrdered route with Pos and an Action function.
config.lua (defaults)
Config.Prices = {
	dmv         = 500,
	drive       = 2500,
	drive_bike  = 3000,
	drive_truck = 5000
}

Config.VehicleModels = {
	drive       = 'blista',
	drive_bike  = 'sanchez',
	drive_truck = 'mule3'
}

Config.SpeedLimits = {
	residence = 50,
	town      = 80,
	freeway   = 120
}

Checkpoints

Each checkpoint runs its Action when the player reaches it. The function receives the player ped, the test vehicle and a setter for the current speed zone:

config.lua
{
	Pos = { x = -453.790, y = -1444.726, z = 27.665 },
	Action = function(playerPed, vehicle, setCurrentZoneType)
		setCurrentZoneType('freeway')
		DrawMissionText(TranslateCap('hway_time', Config.SpeedLimits['freeway']), 5000)
	end
},

The last checkpoint must stay near the DMV: the server only grants road-test licenses when the player is within 35 m of the last checkpoint, and its default action deletes the test vehicle.

Adding a new test type needs three changes: a Config.Prices entry, a Config.VehicleModels entry and a matching row in licenses. The server rejects any type that is missing from Config.Prices or (for road tests) Config.VehicleModels. The menu itself only lists the three built-in road tests, so add a menu entry in client/main.lua too.

Server callbacks and events

esx_dmvschool:canYouPay (callback)

Called with a test type. The server checks that the type is valid, the player is within 20 m of the DMV marker, does not own that license yet and has enough cash. It then removes the money and records a paid test that is valid for 15 minutes.

esx_dmvschool:addLicense (net event)

TriggerServerEvent('esx_dmvschool:addLicense', type)

Client-triggerable

Any client can fire this event. The server only grants the license if the player paid for that exact test in the last 15 minutes and stands near the DMV (theory) or the last checkpoint (road tests). The test result itself is decided on the client (NUI quiz and checkpoint loop), so a modified client that paid could skip the actual test. Treat DMV licenses as roleplay gates, not as hard security.

esx_dmvschool:loadLicenses (client event)

Sent by the server with the player's license list on esx:playerLoaded and after a license is added. The client uses it to build the menu.

Integration tips

  • Check licenses from other resources with esx_license:
server/main.lua
TriggerEvent('esx_license:checkLicense', source, 'drive', function(hasLicense)
    if not hasLicense then
        TriggerClientEvent('esx:showNotification', source, 'You need a drivers license.')
    end
end)
  • Police can revoke drive* licenses through esx_policejob, which uses esx_license as well.
  • The test vehicle gets 100 fuel and the _FUEL_LEVEL decor, so legacy fuel scripts do not drain it.

Common issues

  • Prices or menu text show the wrong language: set setr esx:locale "en" before resources start. The license labels come from the SQL catalog in the same locale.
  • Paid but no license: the paid test expired (15 minutes) or you were too far from the last checkpoint when it finished.
  • Speeding errors on the first meters: if you use mph limits, also change Config.SpeedMultiplier to 2.236936.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page