# Features

### Boat & Air garages

> **How Do Boat & Air Garages Work?**
>
> When a player purchases a boat or aircraft, you’ll need to update the **garage\_type** field in the database for that vehicle.
>
> If your server doesn’t use boats or aircraft, you can skip this step — the default **garage\_type** is set to **"car"**.
>
> {% hint style="success" %}
>
> #### **Compatible Code Snippets Provided by Codesign**
>
> On our [Resource Integration](/paid-scripts/garage/resource-integration.md) page, we provide:
>
> * Step-by-step photos
> * Custom code snippets
> * Exact line edits
>
> These make it easy to set up full compatibility with **ESX**, **QBCore**, and **paid resources**.
>
> 👉 [C](/paid-scripts/garage/resource-integration.md)[lick here for ESX setup](/paid-scripts/garage/resource-integration.md) [→](/paid-scripts/garage/resource-integration.md)
>
> 👉 [Click here for QBCore setup ](/paid-scripts/garage/resource-integration.md)[→](/paid-scripts/garage/resource-integration.md)
>
> 👉 [Click here for Paid Resources setup ](https://docs.codesign.pro/paid-scripts/garage/resource-integration#boat-and-air-garages-2)[→](/paid-scripts/garage/resource-integration.md)
>
> 🔗 [**View the full list of compatible scripts →**](https://docs.codesign.pro/paid-scripts/garage/resource-integration)
> {% endhint %}

<details>

<summary>Option 1: SQL Method (Server-Side)</summary>

Ideally, the **garage\_type** should be set in the same SQL query that adds the vehicle to the database when it’s purchased — for example, in your vehicle shop script.

The **garage\_type** value must be a **string** and can only be one of the following:

* `'car'`
* `'boat'`
* `'air'`

For example, to make a boat appear in the **boat garage**, edit the SQL query in your vehicle shop to insert `'boat'` into the **garage\_type** column of the **owned\_vehicles** or **player\_vehicles** table.\
Do the same with `'air'` for aircraft.

You don’t need to do this for cars or bikes — the default **garage\_type** is already set to `'car'`.

</details>

<details>

<summary>Option 2: Event Method (Client-Side)</summary>

You can trigger this **client-side event** to automatically update the **garage\_type** in the **owned\_vehicles/player\_vehicles** database table.

```lua
TriggerEvent('cd_garage:UpdateGarageType')
```

This event is triggered from the **client side** but handled on the **server**, meaning you can call it after a player purchases a vehicle to ensure the correct garage type is saved automatically.

</details>

***

### Changing Garage Names

To rename a garage (for example, change **"b"** to **"PINK MOTEL"**), edit the **Garage\_ID** in the **Config.Locations** section of the **`configs/config.lua`** file.\
The script will automatically update the database for you.

<div data-with-frame="true"><figure><img src="/files/tbUTrMZpseYYfE7rnNK1" alt=""><figcaption></figcaption></figure></div>

***

### Custom vehicle logos

*Credits to @Baby Amnesia for making this tutorial.*

{% embed url="<https://www.youtube.com/watch?v=LR9pF1GM61U>" %}

***

### Fake Plates

> **How Do Fake Plates Work?**
>
> In the `config.lua`, you can set the **spawn name** for the usable fake plate item.
>
> To use it, stand near a vehicle you own and use the item. A **random new plate** will be generated and applied to your vehicle.\
> The fake plate is **persistent** — it stays on the vehicle until it’s manually removed.
>
> You or specific jobs (such as the **police**) can remove a fake plate using the `/removefakeplate` command.
>
> {% hint style="warning" %}
>
> #### **Built-in Vehicle Keys Required**
>
> This feature only works with the **built-in vehicle key system**.\
> It won’t function with other key resources by default — unless you trigger an **event** or **export** to give the player new keys after a fake plate has been added.
> {% endhint %}

***

### Gang Garages

> **How Do Gang Garages Work?**
>
> The main difference between **job garages** and **gang garages** is how vehicle access is shared.
>
> When a player stores their **personal vehicle** in a gang garage, **any member of that gang** can take it out and use it.\
> The vehicle remains available to the gang until the **owner retrieves it** and stores it back in their personal garage.
>
> However, other gang members **cannot store your vehicle** in their own personal garages.
>
> {% hint style="warning" %}
>
> #### **Disabled on ESX**
>
> Gang garages are only available on **QBCore**, as ESX treats gangs as standard jobs.\
> If you’re using **ESX**, use **job garages** for gang-related vehicles instead.
> {% endhint %}

***

### Garage Slots

> **How Do Garage Slots Work?**
>
> The **garage slots** feature lets you control how many vehicles a player can own.
>
> By default, there’s **no limit**, but you can enable restrictions to set a maximum number of vehicles per player.\
> Players can **buy extra slots** using in-game commands, and **authorized jobs** (like car dealers) can sell these extra slots.\
> You can also set **custom prices** for extra slots, and players can check how many slots they have using a chat command.

<details>

<summary><strong>Usage Example (Server-Side Only)</strong></summary>

Place this code in your **vehicle shop resource**.\
It checks if a player has enough garage slots before allowing them to buy another vehicle.

```lua
if exports['cd_garage']:GetGarageCount(source, 'car') + 1 <= exports['cd_garage']:GetGarageLimit(source) then
    print('allow purchase') -- Player has space, allow the purchase
else
    print('garage limit reached') -- Player is at their limit, deny the purchase
end
```

**What the Code Does**

* **GetGarageCount(source, 'car')** → Checks how many cars the player currently owns.
* **GetGarageLimit(source)** → Checks the player’s maximum allowed garage slots.

The script adds **+1** to simulate the new car purchase and checks if it still fits within the limit.\
If it does, the purchase goes through.\
If not, it shows the message:

> `"garage limit reached"`

</details>

***

### Job Garages

> **How Do Job Garages Work?**
>
> There are **three types of job garages**, and each one works differently.\
> You can configure each garage location to use a different method depending on how you want vehicles to be managed.
>
> This garage script does **not** include a built-in vehicle shop. If you use **Personal Owned** or **Society Owned** methods, you’ll need to handle that setup yourself.
>
> **TL;DR – Job Garage Types**
>
> * **Regular:**\
>   Shared job vehicles that are spawned in and not owned by anyone. Simple and no database setup needed.
>
> * **Personal:**\
>   Vehicles bought by individual players that only they can access from their job garage.
>
> * **Society:**\
>   Shared job vehicles that belong to the entire job — any member of that job can use them.
>
> {% hint style="success" %}
>
> #### **Compatible Code Snippets Provided by Codesign**
>
> On our [Resource Integration](/paid-scripts/garage/resource-integration.md) page, we provide:
>
> * Step-by-step photos
> * Custom code snippets
> * Exact line edits
>
> These make it easy to set up full compatibility with **ESX**, **QBCore**, and **paid resources**.
>
> 👉 [Click here for ESX setup ](/paid-scripts/garage/resource-integration.md)[→](/paid-scripts/garage/resource-integration.md)
>
> 🔗 [**View the full list of compatible scripts →**](https://docs.codesign.pro/paid-scripts/garage/resource-integration)
> {% endhint %}

<table data-full-width="true"><thead><tr><th width="105.33331298828125">Type</th><th>Ownership</th><th>Access</th><th>Saved In Database</th><th>Best Used For</th></tr></thead><tbody><tr><td><strong>Regular</strong></td><td>None — vehicles are spawned, not owned.</td><td>All players with the job.</td><td>❌ Not saved.</td><td>Shared or temporary job vehicles.</td></tr><tr><td><strong>Personal</strong></td><td>Owned by the player.</td><td>Only the vehicle owner.</td><td>✅ Saved with <code>job_personalowned</code> = player’s job name.</td><td>Employee-owned job vehicles.</td></tr><tr><td><strong>Society</strong></td><td>Owned by the job.</td><td>All members of the same job.</td><td>✅ Saved with <code>identifier</code> = job name.</td><td>Shared company or organization vehicles.</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr></tbody></table>

#### Setup: Regular Job Vehicles

<details>

<summary>Config.lua</summary>

Go to **`config.lua`** → **`Config.JobVehicles`**.\
Under your job’s **`Locations`**, set the **`method`** to `'regular'`.\
Then scroll to the **`RegularMethod`** section and add the vehicles you want that job to spawn.

</details>

#### Setup: Personal-Owned Job Vehicles

<details>

<summary><strong>SQL (preferred)</strong></summary>

Set this in the **same SQL query** that inserts the vehicle on purchase:

* Table: `owned_vehicles` / `player_vehicles`
* Column: `job_personalowned`
* Value: **player’s job name** (string)

👉 [**View Usage Example Event →**](https://docs.codesign.pro/paid-scripts/garage/resource-integration/esx#personal-owned-job-garage)

<div data-full-width="false" data-with-frame="true"><figure><img src="/files/yujO78YSukikXVfPO7MF" alt=""><figcaption><p><strong>ESX Personal:</strong> <em>Example of how a personal owned job vehicle should appear in the database (ESX).</em></p></figcaption></figure></div>

<div data-with-frame="true"><figure><img src="/files/s9dwStIkApvITluiH2IV" alt=""><figcaption><p><strong>QBCore Personal:</strong> <em>Example of how a personal owned job vehicle should appear in the database (QBCore).</em></p></figcaption></figure></div>

</details>

<details>

<summary><strong>Event</strong></summary>

You can also assign a vehicle as **personal owned** using this event while seated inside it.

👉 [**View SetJobOwnedVehicle Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#set-job-owned-vehicle)

</details>

#### Setup: Society Owned Job Vehicles

<details>

<summary><strong>SQL (preferred)</strong></summary>

Set this in the **same SQL query** that inserts the vehicle on purchase:

* Table: `owned_vehicles` / `player_vehicles`
* Column: `identifier`
* Value: **player’s job name** (string)

👉 [**View Usage Example Event →**](/paid-scripts/garage/resource-integration.md)

<figure><img src="/files/F7PzXZ6hp8uCvalT7cpJ" alt=""><figcaption><p><strong>ESX Society:</strong> <em>Example of how a society owned job vehicle should appear in the database (ESX).</em></p></figcaption></figure>

</details>

<details>

<summary><strong>Event</strong></summary>

You can also assign a vehicle as **society owned** using this event while seated inside it.

👉 [**View SetJobOwnedVehicle Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#set-job-owned-vehicle)

</details>

***

### Persistent Vehicles

> **How Do Persistent Vehicles Work?**
>
> The **persistent vehicle** system automatically saves and respawns vehicles that despawn, even after you leave and rejoin the server.\
> By default, only vehicles spawned from the garage are persistent, but you can make others persistent using the events below.\
> A vehicle’s position is saved when it stays still for more than **5 seconds**.
>
> {% hint style="success" %}
>
> #### **Compatible Code Snippets Provided by Codesign**
>
> On our [Resource Integration](/paid-scripts/garage/resource-integration.md) page, we provide:
>
> * Step-by-step photos
> * Custom code snippets
> * Exact line edits
>
> These make it easy to set up full compatibility with **ESX**, **QBCore**, and **paid resources**.
>
> 👉 [Click here for ESX setup ](/paid-scripts/garage/resource-integration.md)[→](/paid-scripts/garage/resource-integration.md)
>
> 👉 [Click here for QBCore setup ](/paid-scripts/garage/resource-integration.md)[→](/paid-scripts/garage/resource-integration.md)
>
> 🔗 [**View the full list of compatible scripts →**](https://docs.codesign.pro/paid-scripts/garage/resource-integration)
> {% endhint %}
>
> {% hint style="warning" %}
>
> #### **Possible Modifications Required**
>
> If you enable this feature, you’ll need to add the event below to any external resource that removes vehicles (for example, your `/dv` command, impound scripts, or when changing a plate).\
> Otherwise, the vehicle will automatically respawn.
> {% endhint %}

👉 [**View Add Persistent Vehicle Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#add-persistent-vehicle)

👉 [**View Remove Persistent Vehicle Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#remove-persistent-vehicle)

***

### Private Garages

> **How Private Garages Work**
>
> Private garages function the same as public garages but can be placed anywhere using a chat command. Only the player who purchases a private garage can see and use it.\
> In the **`config.lua`**, you can enable certain jobs (such as real estate) to create and sell private garages to players.

👉 [**View Chat Command →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/chat-commands#privategarage)

***

### Property Garages

> **How Do Property Garages Work?**
>
> Property garages work by opening the **garage UI** directly from your property script.\
> When a player accesses their property garage, the script simply triggers the event to open the Codesign garage interface, allowing them to store or retrieve vehicles from that location.

👉 [**View Open Property Garage Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#open-property-garage)

👉 [**View Store Vehicle Property Garage Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#store-vehicle-property-garage)

***

### Vehicles Display Names

> **Vehicle Display Names and Data**\
> Vehicle display data provides key details—such as the vehicle’s name, class, price, and garage tax—used in the garage UI.\
> This information helps ensure accurate and consistent vehicle listings across all garages.

<details>

<summary>ESX</summary>

On **ESX**, vehicle data is pulled from the **`vehicles`** database table, which is standard on most servers.\
This information is used to display details in the garage UI.

If **`Config.VehiclesData`** is enabled, the script will automatically fetch:

* Vehicle display name
* Vehicle class
* Vehicle price
* Garage tax amount *(if `Config.VehiclesData.garage_tax` is enabled)*

This is the simplest way to configure vehicle data for your server.

<figure><img src="/files/WqL2lYhQuNFsn9aOfbkm" alt=""><figcaption><p>The <strong>"vehicles"</strong> database table, commonly used on <strong>ESX</strong> servers.</p></figcaption></figure>

***

#### **Multiple “vehicles” Tables**

If your server uses multiple **`vehicles`** tables (for example, donator or emergency vehicles),\
add each table name to **`Config.VehiclesData.VehicleDatabase_TableNames`** in your **`config.lua`** file.

</details>

<details>

<summary>QBCore</summary>

On **QBCore**, vehicle data is retrieved from **qb-core/shared.lua → QBShared.Vehicles**, which is standard on most QBCore servers.\
This data is used to display information in the garage UI.

If **`Config.VehiclesData`** is enabled, the script will automatically pull the vehicle’s display name, class, price, and garage tax amount *(if `Config.VehiclesData.garage_tax` is enabled)* from **shared.lua**.\
This provides the simplest way to configure vehicle data for your server.

</details>

<details>

<summary>Disabled</summary>

If **`Config.VehiclesData`** is disabled, the script will instead retrieve vehicle display names from the vehicle handling files (**vehicles.meta**) — for example: `<gameName>Adder</gameName>`.\
However, vehicle **classes** and **prices** will not be shown in the garage UI, and **`Config.VehiclesData.garage_tax`** will be automatically disabled.

</details>

***

### Vehicle Keys

> **How Vehicle Keys Work**
>
> If you’re using the built-in vehicle keys system, you must trigger a specific event whenever a vehicle is spawned outside of Codesign resources — for example, from a `/car` command, vehicle shop, or civilian job script.\
> This ensures the player automatically receives the correct keys for that vehicle.
>
> {% hint style="success" %}
>
> #### **Compatible Code Snippets Provided by Codesign**
>
> On our [Resource Integration](/paid-scripts/garage/resource-integration.md) page, we provide:
>
> * Step-by-step photos
> * Custom code snippets
> * Exact line edits
>
> These make it easy to set up full compatibility with **ESX**, **QBCore**, and **paid resources**.
>
> 👉 [Click here for ESX setup →](https://docs.codesign.pro/paid-scripts/garage/resource-integration/esx#add-keys-server-side)
>
> 👉 [Click here for QBCore setup →](https://docs.codesign.pro/paid-scripts/garage/resource-integration/qbcore#has-keys-check)
>
> 👉 [Click here for Paid Resources setup →](https://docs.codesign.pro/paid-scripts/garage/resource-integration/paid-resources)
>
> 🔗 [**View the full list of compatible scripts →**](https://docs.codesign.pro/paid-scripts/garage/resource-integration)
> {% endhint %}
>
> {% hint style="warning" %}
>
> #### **Vehicle Key Script Conflicts**
>
> If you’re using the built-in key system, you **must remove or disable all other key scripts** to prevent conflicts.\
> Make sure they are completely stopped — some scripts can still start automatically if listed as dependencies, even if they’ve been removed from your server start configuration.
> {% endhint %}

👉 [**View Add Keys Event →**](https://docs.codesign.pro/paid-scripts/garage/developer-api/events#add-keys)

***

### Vehicle Plate Format

{% hint style="success" %}
{% hint style="danger" %} <mark style="color:red;">**PLEASE READ CAREFULLY!**</mark>

You must complete this step correctly. You must read the information below and confirm your server's plate format.

Please read all 3 options below carefully before confirming which one you use.

*Please note that you NEED to use the plate format your server already uses; changing them just because you like the benefits can cause script-breaking issues.*
{% endhint %}

> #### What is vehicle plate formats?
>
> Your vehicle shop/car dealer is the script that usually decides what plate format owned vehicles will use on your server. So you need to configure the `Config.PlateFormats` in the \[configs/config.lua] file to what plate format your server uses. We have added compatibility with all 3 known plate formats.
>
> #### Short Explanation
>
> By default, every vehicle's plate in FiveM is [8 characters long](https://i.imgur.com/3wrMtKC.png). So for example if your vehicle shop forces the plate to be [4 characters long](https://i.imgur.com/kHsBd6q.png), when you use the FiveM native to get a vehicle's plate `GetVehicleNumberPlateText(vehicle)`, this will return a [string that is 8 characters long](https://imgur.com/a/fTlktur) even though the plate is 4 characters long on your vehicle in-game (ABCD); because FiveM will add [whitespaces ](https://en.wikipedia.org/wiki/Whitespace_character)until the plate is 8 characters long including whitespaces.

{% tabs %}
{% tab title="1. Trimmed" %}
**What do you mean by "trimmed" plate format?**

By "trimmed", we mean your vehicle shop removes all spaces and [whitespaces ](https://en.wikipedia.org/wiki/Whitespace_character)from the default 8-character plate.

#### Example of what the **"trimmed"** plate looks like when using DEBUG PRINTS.

<div align="left"><img src="/files/l0zeA3PnoEJ4daeb5MP3" alt=""></div>

**Example of what the "trimmed" plate looks like in the DATABASE.**

<div align="left"><img src="/files/zzy0iravHmvsNU1gyzuF" alt=""></div>

**Example of what the "trimmed" plate looks like IN-GAME.**

<div align="left"><img src="/files/IstX6nbXSOCVl1htgMyH" alt=""></div>

#### <mark style="background-color:green;">Does your server use the "trimmed" vehicle plate format?</mark>

Then you need to set the `Config.PlateFormats` in the `config.lua` to **`'trimmed'`**.
{% endtab %}

{% tab title="2. With Spaces" %}
**What do you mean by "with spaces" plate format?**

By **"**&#x77;ith spaces", we mean your vehicle shop does not modify the plate, so all plates will be 8 characters long no matter how many letters or numbers are in the plate because it will include [whitespaces](https://en.wikipedia.org/wiki/Whitespace_character) to make the length 8.

#### Example of what the **"with spaces"** plate looks like when using DEBUG PRINTS.

<div align="left"><img src="/files/d0I9X6P2c9eCK37Wo7uP" alt=""></div>

**Example of what the "with spaces" plate looks like in the DATABASE.**

<div align="left"><img src="/files/D5OjpcB6cx9lqgYYnGUY" alt=""></div>

**Example of what the "with spaces" plate looks like IN-GAME.**

<div align="left"><img src="/files/IstX6nbXSOCVl1htgMyH" alt=""></div>

#### <mark style="background-color:green;">Does your server use the "</mark><mark style="background-color:green;">**with\_spaces**</mark><mark style="background-color:green;">" vehicle plate format?</mark>

Then you need to set the `Config.PlateFormats` in the `config.lua` to **`'with_spaces'`**.
{% endtab %}

{% tab title="3. Mixed (qbcore+esx\_vehicleshop)" %}
**What do you mean by "mixed" plate format?**

By "mixed", we mean your vehicle shop will remove any [whitespaces](https://en.wikipedia.org/wiki/Whitespace_character) at the start and the end of the plate, but it will not remove spaces in the centre of the plate. You should only be using this option if you use Qbcore or esx\_vehicleshop.

**QBCore:** This option is recommended for QBCore servers as this is what QBCore also uses in its get plate function. Normally, QBCore's plates are 8 characters long with no spaces, so the examples below may not be relevant to you.

**esx\_vehicleshop:** If your vehicle plates in the database are the same format as the examples below, you should use this option, as some esx vehicle shops by default, force the plate format to be 7 characters long with a space in the middle.

#### Example of what **the "mixed"** plate looks like when using DEBUG PRINTS.

<div align="left"><img src="/files/o5xi3p9GOc0kjNpPgBPj" alt=""></div>

**Example of what the "mixed" plate looks like in the DATABASE.**

<div align="left"><img src="/files/Yu5QuUYhZl9meMtTljxO" alt=""></div>

**Example of what the "mixed" plate looks like IN-GAME.**

<div align="left"><img src="/files/mNL4lQ5LIfIO6Z1UgjQq" alt=""></div>

#### <mark style="background-color:green;">Does your server use the "</mark><mark style="background-color:green;">**mixed**</mark><mark style="background-color:green;">" vehicle plate format?</mark>

Then you need to set the `Config.PlateFormats` in the `config.lua` to **`'`mixed`'`**.
{% endtab %}
{% endtabs %}

{% hint style="info" %}

### <mark style="color:blue;">To sum up the above:</mark>

**Do you use QBCore?**

Use the "mixed" option.

**Do you use esx\_vehicleshop, and are your plates formatted like \[ABC 123]?**

Use the "mixed" option.

**My plates are 8 characters with no spaces \[ABCD1234]?**

Use the "trimmed" option.
{% endhint %}
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.codesign.pro/paid-scripts/garage/features.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
