FiveM Docs
Addons

esx_boat

esx_boat adds a boat shop, a boat license and six boat garages to ESX Legacy. Covers setup, every config key, callbacks, the getGarages export and pitfalls.

esx_boat lets players buy boats at a marina, store them in boat garages along the coast and buy a boat license through esx_license. Purchased boats are saved in owned_vehicles with type = 'boat', so they are separate from cars handled by esx_garage.

Overview

FactValue
Resourceesx_boat
SideClient + server
Dependenciesesx_lib, es_extended, esx_vehicleshop (plus oxmysql)
Optionalesx_license (when Config.LicenseEnable = true)
Databaseowned_vehicles (from es_extended), licenses row boat

In-game flow

  1. At the boat shop marker press E. If the license is required and missing, a menu offers the license for Config.LicensePrice.
  2. Pick a boat, preview it on the water and choose Buy. Money is taken from the cash account.
  3. At a garage marker press E to take out a stored boat at the garage's SpawnPoint.
  4. Drive into the large red marker (StorePos) as the driver and press E to store the boat. You are teleported to StoreTP.

Installation

Database

The resource uses the esx_lib SQL catalog and inserts the boat license row automatically, with a label in your esx:locale. The manual equivalent is esx_boat.sql (translations live in localization/):

esx_boat.sql
INSERT INTO `licenses` (`type`, `label`) VALUES
	('boat', 'Boat License');

server.cfg

server.cfg
ensure esx_vehicleshop
ensure esx_license
ensure esx_boat

Configuration

All keys live in config.lua.

KeyDefaultDescription
Config.LocaleGetConvar('esx:locale', 'en')Locale used for texts.
Config.LicenseEnabletrueRequire the boat license to open the shop. Needs esx_license.
Config.LicensePrice50000Cash price of the boat license.
Config.MarkerType1Marker type for shop and garage markers.
Config.DrawDistance10.0Distance at which markers are drawn.
Config.Marker{ r = 100, g = 204, b = 100, x = 1.5, y = 1.5, z = 1.0 }Color and size of shop and garage markers. x is also the interaction radius.
Config.StoreMarker{ r = 255, g = 0, b = 0, x = 5.0, y = 5.0, z = 1.0 }Color and size of the store marker. x is also the interaction radius.
Config.Zones.Garages6 garagesList of garages (see below).
Config.Zones.BoatShops1 shop (Shank St)List of shops with Outside (vector3) and Inside (vector4 preview spot).
Config.Vehicles11 boatsBoats for sale: { model, label, price, props? }.

Each garage entry has four positions:

FieldTypeDescription
GaragePosvector3Marker to open the garage.
SpawnPointvector4Where a boat is spawned (w = heading).
StorePosvector3Marker where you drive the boat in to store it.
StoreTPvector4Where the player is teleported after storing.

Default boats and prices:

ModelPrice
seashark, seashark37500
suntrap10000
dinghy232500
dinghy40000
jetmax45000
squalo61000
tropic265000
speeder85000
toro200000
submersible750000
config.lua
Config.Vehicles = {
    { model = 'seashark', label = 'Seashark (Random Color)', price = 7500 },
    -- optional props are applied in the preview and saved on purchase
    { model = 'speeder', label = 'Speeder (Black)', price = 90000, props = { color1 = 0, color2 = 0 } },
}

Exports

getGarages

Shared export defined in config.lua. Returns the Config.Zones.Garages table, for example to show boat garages on a phone map.

local garages = exports['esx_boat']:getGarages()

for i, garage in ipairs(garages) do
    print(i, garage.GaragePos)
end

Server callbacks and events

These are triggered by the esx_boat client. They are listed so you can audit them or call them from your own UI. All are validated on the server.

NameTypeArgumentsServer checks
esx_boat:buyBoatcallbackvehiclePropsModel must be in Config.Vehicles, player within 20 m of a shop Outside or 35 m of Inside, enough cash. Plate is generated on the server (BO + 2 letters + 4 digits); only model, plate and config props are stored.
esx_boat:buyBoatLicensecallbacknoneNear a shop, enough cash, no boat license yet. Refunds if adding the license fails.
esx_boat:getGaragecallbacknoneWithin 20 m of a GaragePos. Returns the JSON of stored boats.
esx_boat:storeVehiclecallbackplateWithin 25 m of a StorePos and a boat with that plate within 20 m. Returns rows changed.
esx_boat:takeOutVehiclenet eventplateWithin 20 m of a GaragePos, boat owned and stored.

Security notes

esx_boat:takeOutVehicle is a client-triggerable net event. It only flips stored to false in the database; the boat itself is spawned by the client. The license requirement is only checked on the client before the shop opens: esx_boat:buyBoat does not verify the boat license on the server. If the license matters on your server, add an esx_license:checkLicense check to that callback.

Integration tips

  • Other garage scripts can read boats with SELECT * FROM owned_vehicles WHERE type = 'boat'.
  • The client still calls exports['esx_vehicleshop']:GeneratePlate() before buying, which is why esx_vehicleshop must be running even though the server replaces the plate.
  • Blips: garages use sprite 356, the shop uses sprite 427, both color 3.

Common issues

  • "Unknown model" in the garage: the boat's model is no longer in Config.Vehicles. Keep old entries or change the label lookup.
  • Cannot store the boat: you must be the driver and inside the red StorePos marker. The server also requires the boat with your plate to be within 20 m.
  • Shop does not open, license menu appears every time: esx_license is not started or the boat row is missing in licenses.
  • Resource fails at start: esx_vehicleshop is a hard dependency in fxmanifest.lua. Start it before esx_boat.

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