# nm1 Scripts Documentation

#### Welcome to the **nm1 Asset Documentation Hub**.

This documentation serves as an official reference designed to provide clear, structured, and detailed guidance for the installation, configuration, and optimal use of nm1’s premium FiveM assets. Before proceeding to the technical sections, we encourage you to review a brief introduction outlining our background, values, and continued presence within the FiveM ecosystem.

#### About Us

**nm1 Scripts** was established with a clear vision: to deliver high-quality, innovative, and performance-driven FiveM scripts that enhance roleplay experiences and server stability. From the beginning, our focus has been on introducing modern features, refined mechanics, and scalable systems that meet the evolving needs of serious FiveM communities.

At nm1 Scripts, we continue to prioritize innovation, transparency, and professional support—ensuring every product we release meets the standards expected by modern FiveM servers.

### Useful Links <a href="#useful-links" id="useful-links"></a>

* [Discord](https://discord.gg/nAVCGRRwYu)
* [Youtube](https://www.youtube.com/@nm1Scripts)
* [Tebex](https://nm1.tebex.io/)

<div data-full-width="true"><figure><img src="https://2917216003-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOJIWkYsfazidAg4XFL3Z%2Fuploads%2FsrrKn8pSj6Fb1mGebNW2%2FNO_BG%20SYMBOL.png?alt=media&amp;token=18e71707-4936-4c28-b843-8a3f28245316" alt="" width="263"><figcaption></figcaption></figure></div>


# Terms & Condition

## Terms of Sale

When purchasing any script from our Tebex store (NM1 Scripts Store), you acknowledge and accept the following conditions. All transactions are handled by Tebex Limited; your purchase is made through Tebex Limited and not directly from NM1 Scripts. Tebex Limited exclusively manages the distribution rights for NM1 Scripts products. All provided digital software and assets are licensed rather than sold. This license grants you personal, limited-use rights to access and utilize the digital products solely on the account used for the original purchase.

Prohibited actions include:

(1) modifying, reverse engineering, or attempting to decompile the script in any form;

(2) sharing, distributing, leaking, or uploading the script privately or publicly;

(3) reselling, transferring, or sublicensing the script to any other party.

Any breach of these conditions may result in immediate license revocation and may also lead to your Cfx.re account being flagged or banned.

Tebex Terms

All payment processing, fulfilment, customer billing support, and refund matters are managed exclusively by Tebex Limited. By making a purchase through our platform, you also consent to the Tebex Checkout Terms & Conditions as well as the Tebex Privacy Policy.

## Refund & Assistance Policy

Tebex Limited serves as our Merchant of Record (MoR), meaning they oversee all payment processing, billing matters, and general transactional support. Separately from Tebex, and entirely at our discretion, NM1 Scripts offers a voluntary 2-day satisfaction period during which a refund may be granted if you no longer want the product or if it does not perform as intended. In certain exceptional cases, and only at our judgment, we may still consider a refund after this 2-day period if we determine that the issue cannot be resolved or if the script remains unusable despite full cooperation with our support team.

IMPORTANT NOTICE: WE MAY REFUSE A REFUND REQUEST AT ANY POINT AND FOR ANY REASON.

Situations that may result in refusal include (but are not limited to):

(1) the product being transferred or redistributed to others,

(2) inability to confirm proof of purchase,

(3) buyer error such as purchasing under the wrong account, accidental ordering, or duplications,

(4) declining to engage with support or refusing to work with us to resolve the issue.

Refunds from NM1 Scripts are provided voluntarily and at our sole discretion, offered as a courtesy and a reflection of confidence in our work. If you do not wish to agree to these refund conditions, you may contact Tebex Limited instead. Please be advised that, as the platform provider of digital goods, Tebex Limited does not provide refunds for purchases made through their system, in accordance with their Checkout Terms & Conditions.

You can learn more here: [Tebex Checkout T\&Cs.](https://checkout.tebex.io/terms)

## Subscription Services

Subscription-based products, such as nm1 supreme pack (if applicable), are non-refundable under all circumstances. You may cancel your subscription at any time, and no additional charges will be made thereafter. There are no penalties or cancellation fees. Ending a subscription will immediately withdraw access to subscription-related benefits. Should you wish to dispute a subscription payment, please communicate directly with Tebex Limited.

## Contacting Tebex Limited

For billing-related inquiries, please reach out through: [Tebex.io/support-customer-form](https://www.tebex.io/support-customer-form)

## Support

Support is primarily offered through our [Discord community](https://discord.gg/nAVCGRRwYu), To access support on Discord, you must hold the Customer role. When purchasing a product, this role will automatically be applied if you were logged into Discord during checkout. If not, you may manually claim roles using the /claim command in the [#⁠🌺丨role-claim](https://discord.com/channels/1414647970636365937/1440627344799961240) channel, or by opening a ticket through the designated support channels so our staff can assist in assigning roles.

Support is available every day of the week for verified customers who obtained our scripts through the official store. Requests relating to leaked versions, pirated copies, or unauthorized resales are not eligible for assistance. To retain lifetime support access, you must remain a member of our Discord server. We enforce a strict policy against disrespectful, toxic, or hostile conduct toward our team. Such behavior may lead to temporary communication restrictions, loss of support privileges, ticket limitations, or—under severe circumstances—permanent removal from the server, which eliminates your eligibility to receive further support. This policy ensures a safe and respectful environment for both staff and customers. We appreciate professional communication, constructive comments, and cooperation, and we are committed to helping resolve issues as long as interactions remain civil and respectful.


# Advanced Scoreboard

This resource is compatible with ESX , QBcore , Qbox

<sub>Looking for a high-quality scoreboard script to elevate your FiveM server experience? Your search ends here. We provide a powerful and distinctive scoreboard solution, loaded with advanced features designed to set your server apart.</sub>

<a href="https://nm1.tebex.io/package/7125167" class="button primary">Buy yours now</a><a href="https://nm1.tebex.io/" class="button primary">Checkout all our scripts</a>

### Showcase

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


# Installation

Installation Guide of nm1-Scoreboard

#### 1. Download Resource <a href="#id-1.-download-resource" id="id-1.-download-resource"></a>

To Begin, by downloading the resource you have purchased from [our store](https://corem.tebex.io/)

Now Log in to your [cfx portal](https://portal.cfx.re/) account and navigate to the **Asset Grants** section. There, you will find a list of all resources associated with your account, from which you can download the required files.

#### 2. Frameworks Supported <a href="#id-2.-dependencies" id="id-2.-dependencies"></a>

* ESX
* QBcore
* Qbox<br>

#### 3. Ensuring Asset(s) <a href="#id-3.-asset-arrangement" id="id-3.-asset-arrangement"></a>

To ensure the asset(s) start correctly and function as intended, it is important that they are loaded in the proper order within your **server.cfg**. Below is an example illustrating the recommended startup sequence.

```
# 1. Start the core framework (choose the one your server uses)
ensure es_extended      # ESX
# ensure qb-core        # QB-Core
# ensure qbx_core       # Qbox

# 2. Start the nm1 scoreboard resource
ensure nm1-scoreboard or ensure nm1-scoreboard-xMasThemed [If using themed version]

# Or create a folder named [nm1] and start all nm1 resources.
# ensure [nm1]
```

{% hint style="danger" %}
**Important** Ensure nm1 scripts *after* your framework (es\_extended/qb-core /qbx-core).
{% endhint %}


# Full Configuration Guide

This document explains every available option in the config.lua file and how each setting affects the NM1 Scoreboard behavior, appearance, and logic.

### 1. Debug Configuration

```lua
Config.Debug = false
```

#### Purpose

Controls debug output in the server console.

#### Behavior

* `true`: Enables detailed debug logs (useful for testing and troubleshooting)
* `false`: Disables debug logs (recommended for production servers)

***

### 2. Core Framework Configuration

```lua
Config.Core = 'esx'
```

#### Purpose

Defines which framework the scoreboard integrates with.

#### Supported Values

* `'qb'` → QB-Core
* `'esx'` → ESX
* `'qbx'` → QBox

#### Important

This value **must match your server framework exactly**. Incorrect selection will cause job counts and player data to malfunction.

***

### 3. Scoreboard Display Name

```lua
Config.ScoreboardName = "YourRP Name"
```

#### Purpose

Sets the title displayed at the top of the scoreboard UI.

#### Usage

Replace this with your server’s roleplay name.

Example:

```lua
Config.ScoreboardName = "nm1 Roleplay"
```

***

### 4. Scoreboard Toggle Key

```lua
Config.ToggleKey = "F10"
```

#### Purpose

Defines the keyboard key used to open and close the scoreboard.

#### Notes

* Accepts FiveM control key names
* Common values include `F10`, `F9`, `HOME`, etc.

***

### 5. Scoreboard Position

```lua
Config.ScoreboardPosition = 'right'
```

#### Purpose

Determines where the scoreboard appears on the screen.

#### Options

* `'left'` → Left side of the screen
* `'right'` → Right side of the screen

***

### 6. Default Page on Open

```lua
Config.DefaultPage = 'players'
```

#### Purpose

Specifies which page is shown when the scoreboard is opened.

#### Options

* `'players'` → Player list page
* `'jobs_heists'` → Jobs and heists overview

***

### 7. Page Visibility Control

```lua
Config.HidePages = {
    players = false,
    jobs_heists = false
}
```

#### Purpose

Allows disabling specific scoreboard pages.

#### Behavior

* `true`: Page is hidden from the UI
* `false`: Page is visible

Example:

```lua
jobs_heists = true
```

This removes the Jobs/Heists page entirely.

***

### 8. Staff Roles Configuration

```lua
Config.StaffRoles = {
    ['admin'] = {
        label = "Administrator",
        color = "#FFD700"
    }
}
```

#### Purpose

Displays staff roles next to player names in the scoreboard.

#### Key Rules

* The role key (`admin`, `mod`, etc.) must match:
  * ESX group
  * QB permission
  * ACE permission
* `label` is the text shown in the UI
* `color` must be a valid CSS color value

***

### 9. Job Categories (Online Job Counts)

```lua
Config.JobCategories = {
    { name = "police", label = "Police Department" }
}
```

#### Purpose

Tracks and displays the number of online players per job.

#### Fields

* `name`: Exact job name from your framework configuration
* `label`: Display name shown in the scoreboard

#### Notes

* Job names are case-sensitive
* Only listed jobs are tracked

***

### 10. Heist Evaluation Configuration

```lua
Config.HeistEvaluation = {
    Jobs = { 'police', 'lspd' },
    CombineJobs = true
}
```

#### Purpose

Defines how law-enforcement jobs are counted for heist availability.

#### Jobs

* Lists all jobs considered enforcement
* Must match framework job names exactly

#### CombineJobs

* `true`: All listed jobs are summed together
* `false`: Only the first job in the list is counted

Recommended:

* Use `true` for multi-department servers

***

### 11. Heist Definitions

```lua
Config.Heists = {
    { name = "Store Robbery", isRobbery = true, minPolice = 2 }
}
```

#### Purpose

Defines all heists and how their availability is evaluated.

#### Fields

* `name`: Display name of the heist
* `isRobbery`:
  * `true`: Requires police count check
  * `false`: Always available
* `minPolice` (optional):
  * Minimum enforcement required for that specific heist

#### Notes

* If `minPolice` is not set, the global fallback value is used
* Non-robbery entries ignore police requirements

***

### 12. Global Minimum Police Requirement (Fallback)

```lua
Config.MinPoliceForRobbery = 1
```

#### Purpose

Acts as a fallback police requirement.

#### Behavior

* Used only if a robbery does not define its own `minPolice`
* Per-heist values always override this setting

***

### 13. UI Color Customization

```lua
Config.Colors = {
    PrimaryBackground = "#0A0F1A"
}
```

#### Purpose

Controls the entire visual theme of the scoreboard.

#### Customizable Elements

* Backgrounds
* Text
* Headers
* Borders
* Hover effects
* Status indicators

#### Notes

* Changes apply automatically to the UI
* No code changes required
* Accepts standard CSS color formats

***


# Configuration File

### Config Files <a href="#config-files" id="config-files"></a>

{% code title="config.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
Config = {}

-- Debug Mode:
-- Set to true to enable debug prints in the server console.
-- Set to false to disable them.
Config.Debug = false -- Set to true or false

-- Core Framework Configuration:
-- Set to 'qb' for QB-Core or 'esx' for ESX or 'qbx' for QBox
-- This determines which framework's functions the script will use.
Config.Core = 'esx' -- Options: 'qb', 'esx' , 'qbx'

-- Scoreboard Display Name:
-- This name will be displayed at the top of the scoreboard.
Config.ScoreboardName = "YourRP Name" -- As per user request, but customizable.

-- Keybind to Toggle Scoreboard:
-- Default is F10 (keyboard code 288). You can find key codes online.
-- https://docs.fivem.net/docs/game-references/controls/
Config.ToggleKey = "F10" -- Default: F10 

-- Scoreboard Position:
-- Determines if the scoreboard appears on the 'left' or 'right' side of the screen.
Config.ScoreboardPosition = 'right' -- Options: 'left', 'right'

-- Default Page on Open:
-- The page that is shown when the scoreboard is first opened.
Config.DefaultPage = 'players' -- Options: 'players', 'jobs_heists'

-- Hide Specific Pages:
-- Set to true to hide a page from the scoreboard UI.
Config.HidePages = {
    players = false,      -- Set to true to hide the Players page
    jobs_heists = false   -- Set to true to hide the Jobs/Heists page
}

-- Staff Roles Configuration:
-- Define custom roles for staff members with specific labels and colors.
-- The key should match the permission group/identifier from your framework (e.g., 'admin', 'moderator').
-- The 'color' should be a valid CSS color string (e.g., '#FF0000', 'rgb(255,0,0)').
Config.StaffRoles = {
    ['admin'] = {
        label = "Administrator",
        color = "#FFD700" -- Gold
    },
    ['mod'] = {
        label = "Moderator",
        color = "#8A2BE2" -- BlueViolet
    },
    ['support'] = {
        label = "Support",
        color = "#00BFFF" -- DeepSkyBlue
    },
    -- Add more roles as needed
}

-- Job Categories to Track:
-- List the job names (as defined in your QB-Core/ESX jobs config) that you want to count online players for.
-- The label is what will be displayed on the scoreboard.
Config.JobCategories = {
    { name = "police", label = "Police Department" },
    { name = "ambulance", label = "EMS" },
    { name = "taxi", label = "Taxi" },
    { name = "mechanic", label = "Mechanic" },
    -- Add more jobs as needed
}

Config.HeistEvaluation = {
    -- Default jobs used to count enforcement
    -- Can be one job or multiple jobs
    Jobs = {
        'police',        -- LSPD
        'lspd',       -- BCSO
        -- 'state',      -- add if needed
    },

    -- If true, sum all listed jobs
    -- If false, only the FIRST job is used
    CombineJobs = true
}

-- Heists/Operations Configuration:
-- Define heists with their names.
-- 'isRobbery': Set to true if this is a robbery and its availability depends on police count.
-- 'minPolice': (Optional, only for isRobbery = true) The minimum number of police required for this specific robbery.
--              If not set for a robbery, it will default to 0, effectively always available.
Config.Heists = {
    { name = "Gang Territory Capture", isRobbery = false },
    { name = "Vangelico Elite Robbery", isRobbery = true, minPolice = 1 },
    { name = "Black Market Delivery", isRobbery = false },
    { name = "Museum Artifact Theft", isRobbery = true, minPolice = 6 },
    { name = "Store Robbery", isRobbery = true, minPolice = 2 },   -- Requires 2 police
    { name = "Bank Robbery", isRobbery = true, minPolice = 5 },    -- Requires 5 police
    { name = "Pacific Bank", isRobbery = true, minPolice = 7 },    -- Requires 7 police
    { name = "Jewellery Robbery", isRobbery = true, minPolice = 3 }, -- Requires 3 police
    { name = "Drug Run", isRobbery = false },       -- Example of a non-robbery heist (always available unless set otherwise)
    -- Add more heists as needed
}

-- Minimum Police Count for Robberies (GLOBAL FALLBACK):
-- This setting is now a fallback. If a specific robbery in Config.Heists does NOT have
-- a 'minPolice' defined, this global value will be used for that robbery.
-- If a robbery has its own 'minPolice', that value will take precedence.
Config.MinPoliceForRobbery = 1 -- Default: 1 police officer required if not specified per heist

-- Customizable Colors for UI Elements:
-- These colors will be used in the HTML/CSS to easily theme the scoreboard.
Config.Colors = {
    PrimaryBackground   = "#0A0F1A", -- Deep navy-black background
    SecondaryBackground = "#111826", -- Slightly lighter navy tone
    AccentColor         = "#4A90E2", -- Cool steel-blue accent (matches left part of logo)
    TextColor           = "#E6E6E6", -- Soft silver-white for readability
    HeaderColor         = "#C7D0E0", -- Light metallic silver-blue tone
    ButtonHover         = "#1E2A40", -- Dark muted blue for hover effect
    SuccessColor        = "#6FA8FF", -- Soft glowing blue (instead of green)
    DangerColor         = "#FF5C5C", -- Light red-pink works universally
    BorderColor         = "#2A3347", -- Desaturated navy-gray border
}


```

{% endcode %}


# Color Presets

nm1-scoreboard/config.lua

We offer a selection of pre-designed color presets for you to choose from. Below are **10 professional color presets**, each designed for different FiveM RP styles. All presets are **ready to paste** into `Config.Colors`.

### 1. Midnight Steel

Dark, clean, and professional. Ideal for serious RP servers.

```lua
Config.Colors = {
    PrimaryBackground   = "#0B0F14",
    SecondaryBackground = "#121826",
    AccentColor         = "#3A7BD5",
    TextColor           = "#E4E7EC",
    HeaderColor         = "#B8C1D9",
    ButtonHover         = "#1B2433",
    SuccessColor        = "#5FA8FF",
    DangerColor         = "#FF6B6B",
    BorderColor         = "#2A3242",
}
```

***

### 2. Royal Purple

Modern, premium, and visually striking.

```lua
Config.Colors = {
    PrimaryBackground   = "#0E0A14",
    SecondaryBackground = "#1A1326",
    AccentColor         = "#8B5CF6",
    TextColor           = "#EDE9FE",
    HeaderColor         = "#C4B5FD",
    ButtonHover         = "#2A1F3D",
    SuccessColor        = "#A78BFA",
    DangerColor         = "#F87171",
    BorderColor         = "#3B2E5A",
}
```

***

### 3. Tactical Blue

Government, police, and EMS-focused servers.

```lua
Config.Colors = {
    PrimaryBackground   = "#0A111A",
    SecondaryBackground = "#101B2B",
    AccentColor         = "#1F6AE1",
    TextColor           = "#E5ECF5",
    HeaderColor         = "#C7D3E6",
    ButtonHover         = "#182640",
    SuccessColor        = "#4DA3FF",
    DangerColor         = "#FF4D4D",
    BorderColor         = "#263A55",
}
```

***

### 4. Carbon Red

Aggressive tone for crime-heavy RP.

```lua
Config.Colors = {
    PrimaryBackground   = "#0F0B0B",
    SecondaryBackground = "#1A1111",
    AccentColor         = "#E11D48",
    TextColor           = "#FEE2E2",
    HeaderColor         = "#FCA5A5",
    ButtonHover         = "#2B1515",
    SuccessColor        = "#FB7185",
    DangerColor         = "#DC2626",
    BorderColor         = "#3A1F1F",
}
```

***

### 5. Emerald Night

Balanced, clean, and versatile.

```lua
Config.Colors = {
    PrimaryBackground   = "#0B1411",
    SecondaryBackground = "#12201A",
    AccentColor         = "#10B981",
    TextColor           = "#ECFDF5",
    HeaderColor         = "#A7F3D0",
    ButtonHover         = "#1B2E26",
    SuccessColor        = "#34D399",
    DangerColor         = "#F87171",
    BorderColor         = "#2F4F45",
}
```

***

### 6. Obsidian Gold

Luxury and executive-style RP.

```lua
Config.Colors = {
    PrimaryBackground   = "#0A0A0A",
    SecondaryBackground = "#141414",
    AccentColor         = "#D4AF37",
    TextColor           = "#F5F5F5",
    HeaderColor         = "#E6D8A3",
    ButtonHover         = "#1F1F1F",
    SuccessColor        = "#EAD27A",
    DangerColor         = "#FF6B6B",
    BorderColor         = "#2E2E2E",
}
```

***

### 7. Neon Cyan

Tech-focused, futuristic RP servers.

```lua
Config.Colors = {
    PrimaryBackground   = "#050B10",
    SecondaryBackground = "#0B1A26",
    AccentColor         = "#22D3EE",
    TextColor           = "#ECFEFF",
    HeaderColor         = "#A5F3FC",
    ButtonHover         = "#123040",
    SuccessColor        = "#67E8F9",
    DangerColor         = "#FB7185",
    BorderColor         = "#1F3A4A",
}
```

***

### 8. Desert Sand

Civilian-focused or realism servers.

```lua
Config.Colors = {
    PrimaryBackground   = "#12100D",
    SecondaryBackground = "#1E1A15",
    AccentColor         = "#D6B36A",
    TextColor           = "#FAF7F2",
    HeaderColor         = "#EAD9B0",
    ButtonHover         = "#2A241D",
    SuccessColor        = "#E4C988",
    DangerColor         = "#EF4444",
    BorderColor         = "#3A3328",
}
```

***

### 9. Forest Command

Military, ranger, or tactical RP.

```lua
Config.Colors = {
    PrimaryBackground   = "#0B120E",
    SecondaryBackground = "#141F18",
    AccentColor         = "#4D7C0F",
    TextColor           = "#ECFDF5",
    HeaderColor         = "#BBF7D0",
    ButtonHover         = "#1E2F24",
    SuccessColor        = "#65A30D",
    DangerColor         = "#F87171",
    BorderColor         = "#2F4F3E",
}
```

***

### 10. Slate Mono

Minimalistic, neutral, and clean UI.

```lua
Config.Colors = {
    PrimaryBackground   = "#0F1115",
    SecondaryBackground = "#161A22",
    AccentColor         = "#94A3B8",
    TextColor           = "#E5E7EB",
    HeaderColor         = "#CBD5E1",
    ButtonHover         = "#1F2430",
    SuccessColor        = "#A5B4FC",
    DangerColor         = "#F87171",
    BorderColor         = "#2A2F3A",
}
```

***


# Seasonal Presets

nm1-scoreboard/config.lua

Below are **5 seasonal color themes**, each named and designed to match the mood of the season.\
All themes are **production-ready** and can be directly used in `Config.Colors`.

***

### 1. Winter Frost (Christmas / New Year)

Clean, icy tones with festive contrast. Works perfectly for Christmas and New Year events.

```lua
Config.Colors = {
    PrimaryBackground   = "#0A1220",
    SecondaryBackground = "#111B30",
    AccentColor         = "#7DD3FC",
    TextColor           = "#E0F2FE",
    HeaderColor         = "#BAE6FD",
    ButtonHover         = "#1B2A4A",
    SuccessColor        = "#A7F3D0",
    DangerColor         = "#F87171",
    BorderColor         = "#2A3B5E",
}
```

***

### 2. Autumn Ember (Halloween / Fall)

Dark, warm tones with an eerie atmosphere. Ideal for Halloween events.

```lua
Config.Colors = {
    PrimaryBackground   = "#120B08",
    SecondaryBackground = "#1F140E",
    AccentColor         = "#F97316",
    TextColor           = "#FFF7ED",
    HeaderColor         = "#FED7AA",
    ButtonHover         = "#2B1A12",
    SuccessColor        = "#FDBA74",
    DangerColor         = "#EF4444",
    BorderColor         = "#3A2418",
}
```

***

### 3. Spring Bloom (Fresh / Community Events)

Bright yet soft colors for seasonal resets, community events, or server launches.

```lua
Config.Colors = {
    PrimaryBackground   = "#0E1512",
    SecondaryBackground = "#16201A",
    AccentColor         = "#22C55E",
    TextColor           = "#ECFDF5",
    HeaderColor         = "#BBF7D0",
    ButtonHover         = "#1F2E25",
    SuccessColor        = "#4ADE80",
    DangerColor         = "#FB7185",
    BorderColor         = "#2F4F3E",
}
```

***

### 4. Summer Heat (High-Energy RP)

Vibrant and energetic. Perfect for action-heavy or crime-focused seasons.

```lua
Config.Colors = {
    PrimaryBackground   = "#140B0A",
    SecondaryBackground = "#221210",
    AccentColor         = "#FACC15",
    TextColor           = "#FEFCE8",
    HeaderColor         = "#FEF08A",
    ButtonHover         = "#2F1C18",
    SuccessColor        = "#FDE047",
    DangerColor         = "#EF4444",
    BorderColor         = "#3F2622",
}
```

***

### 5. Monsoon Night (Rainy / Dark RP)

Moody and cinematic, suited for serious or realism-focused servers.

```lua
Config.Colors = {
    PrimaryBackground   = "#0A0E14",
    SecondaryBackground = "#121926",
    AccentColor         = "#38BDF8",
    TextColor           = "#E5F3FF",
    HeaderColor         = "#BAE6FD",
    ButtonHover         = "#1B2436",
    SuccessColor        = "#60A5FA",
    DangerColor         = "#F87171",
    BorderColor         = "#2A3448",
}
```

***

####


# Advanced Crafting System

This resource is compatible with ESX , QBcore , Qbox

<sub>Looking for a high-quality crafting script to elevate your FiveM server experience? Your search ends here. We provide a powerful and distinctive scoreboard solution, loaded with advanced features designed to set your server apart.</sub>

<a href="https://nm1.tebex.io/package/crafting" class="button primary">Buy yours now</a><a href="https://nm1.tebex.io/" class="button primary">Checkout all our scripts</a>

### Showcase

{% embed url="<https://youtu.be/ge95yjaO3mg>" %}


# Installation

Installation Guide of nm1-Scoreboard

#### 1. Download Resource <a href="#id-1.-download-resource" id="id-1.-download-resource"></a>

To Begin, by downloading the resource you have purchased from [our store](https://corem.tebex.io/)

Now Log in to your [cfx portal](https://portal.cfx.re/) account and navigate to the **Asset Grants** section. There, you will find a list of all resources associated with your account, from which you can download the required files.

#### 2. Frameworks Supported <a href="#id-2.-dependencies" id="id-2.-dependencies"></a>

* ESX
* QBcore
* Qbox<br>

#### 3. Ensuring Asset(s) <a href="#id-3.-asset-arrangement" id="id-3.-asset-arrangement"></a>

To ensure the asset(s) start correctly and function as intended, it is important that they are loaded in the proper order within your **server.cfg**. Below is an example illustrating the recommended startup sequence.

```
# 1. Start the core framework (choose the one your server uses)
ensure es_extended      # ESX
# ensure qb-core        # QB-Core
# ensure qbx_core       # Qbox

# 2. Start the nm1 scoreboard resource
ensure nm1-crafting

# Or create a folder named [nm1] and start all nm1 resources.
# ensure [nm1]
```

{% hint style="danger" %}
**Important** Ensure nm1 scripts *after* your framework (es\_extended/qb-core /qbx-core).
{% endhint %}


# Full Configuration Guide

This document explains every available option in the provided config.lua file and how each setting affects the NM1 Crafting System behavior, access rules, UI logic, and crafting flow.

### 1. Debug Configuration

```lua
Config.Debug = false
```

#### Purpose

Controls debug messages printed in the client/server console.

***

### 2. Framework Configuration

```lua
Config.Framework = "auto" -- Options : "esx" or "qb" or "qbox"
```

#### Purpose

Defines which framework the crafting system integrates with for:

* player job detection
* gang detection (if supported)
* inventory / item checks
* giving crafted items

#### Supported Values

* `"auto"` → Automatically detects your framework
* `"esx"` → ESX
* `"qb"` → QB-Core
* `"qbox"` → QBox

#### Important

If this value is wrong, **job restrictions, gang restrictions, and crafting rewards may not work correctly**.

***

### 3. Interaction Mode

```lua
Config.Interaction = "target" -- Options : "target" or 'textui'
```

#### Purpose

Controls how players interact with crafting stations in-game.

#### Options

* `"target"` → Uses a target system (recommended)
* `"textui"` → Uses text UI interaction (Press key style)

#### Notes

Use `"target"` if you want clean interaction zones and better UI experience.

***

### 4. Target System Selection

```lua
Config.TargetSystem = 'ox' -- Options : "ox" or 'qb'
```

#### Purpose

Defines which target export is used when `Config.Interaction = "target"`.

#### Options

* `"ox"` → ox\_target
* `"qb"` → qb-target

#### Important

This must match what your server uses, otherwise crafting stations will **not open**.

***

### 5. Crafting Time Multiplier

```lua
Config.CraftingTimeMultiplier = 1.0
```

#### Purpose

Globally increases or decreases crafting duration for all recipes.

#### Behavior

Final crafting time = `recipe.time * Config.CraftingTimeMultiplier`

#### Examples

* `1.0` → Normal crafting speed
* `0.5` → 2x faster crafting
* `2.0` → 2x slower crafting

***

### 6. Max Level XP

```lua
Config.MaxLevelXP = 5000
```

#### Purpose

Defines the maximum XP value a player can reach.

#### Behavior

* Players will gain XP from crafting until they hit this limit.
* Used for progression systems like levels/unlocks.

#### Notes

This works together with category requirements like `minXP`.

***

### 7. Locale / Language Configuration

```lua
Config.Locale = "en" -- Options : en | de | fr | es | ta
```

#### Purpose

Controls the language shown in the crafting UI.

#### Supported Values

* `"en"` → English
* `"de"` → German
* `"fr"` → French
* `"es"` → Spanish
* `"ta"` → Tamil

#### Notes

If the locale file is missing or incomplete, the UI may fallback to another language or show blank text.

***

## 8. Crafting Stations Configuration

```lua
Config.Stations = {
    { ... },
}
```

#### Purpose

Defines all crafting stations available in the world.

Each station controls:

* where crafting is located
* what recipes/categories it can access
* who is allowed to use it (public / job / gang)
* whether a blip appears on the map

***

### 8.1 Station Fields Explained

#### `type`

```lua
type = "workbench"
```

Unique identifier for the station type.

Used internally to separate stations and logic.

***

#### `label`

```lua
label = "Public Workbench"
```

Name shown in UI / target interaction.

***

#### `model`

```lua
model = "prop_tool_bench02"
```

The object model used for the station.

#### Notes

This is usually used for:

* target attaching
* placing interaction point near the model

***

#### `coords`

```lua
coords = vec4(x, y, z, heading)
```

#### Purpose

Defines station location and direction.

#### Format

* `x, y, z` → position
* `heading` → rotation angle

***

#### `blip`

```lua
blip = { enable = true, sprite = 237, color = 3, scale = 0.8, name = "Crafting" }
```

#### Purpose

Controls map blip display for that station.

#### Fields

* `enable` → `true/false`
* `sprite` → blip icon id
* `color` → blip color id
* `scale` → size of blip
* `name` → text shown on map

#### Example (Hidden Station)

```lua
blip = { enable = false }
```

***

#### `categories`

```lua
categories = { "level1", "level2", "level3" }
```

#### Purpose

Defines which crafting categories can be used at this station.

#### Important

If a recipe belongs to a category **not listed here**, it will **not show** at that station.

***

#### `job` restriction (Optional)

```lua
job = "police"
```

#### Purpose

Restricts station access to only players with the given job.

#### Behavior

Only `police` players can open the station.

***

#### `gang` restriction (Optional)

```lua
gang = { "ballas", "families" }
```

#### Purpose

Restricts station access to only specific gangs.

#### Behavior

Only listed gangs can open the station.

***

### 8.2 Your Stations (Explained)

#### Public Workbench

* Accessible by everyone
* Shows categories: `level1`, `level2`, `level3`
* Visible on map

#### Police Armory Crafting

* Only job: `police`
* Shows category: `police_gear`
* Visible on map

#### Gang Workbench

* Only gangs: `ballas`, `families`
* Shows category: `drugs`
* Hidden on map (`blip.enable = false`)

***

## 9. Categories Configuration

```lua
Config.Categories = {
    ["level1"] = { label = "Basic", icon = "...", minXP = 0 },
}
```

#### Purpose

Defines the categories shown in the crafting UI.

Categories control:

* UI grouping of recipes
* unlock requirements using XP (`minXP`)
* icon display

***

### 9.1 Category Fields Explained

#### `label`

```lua
label = "Basic"
```

Text shown in the UI.

***

#### `icon`

```lua
icon = "fa-solid fa-star"
```

#### Purpose

FontAwesome icon class used in the UI.

#### Notes

Make sure the UI includes FontAwesome (it usually does).

***

#### `minXP`

```lua
minXP = 10
```

#### Purpose

Minimum XP required to unlock that category.

#### Behavior

If player XP is lower than `minXP`, the category may be locked or hidden depending on UI logic.

***

### 9.2 Your Categories (Summary)

| Category Key  | Label        | Min XP | Purpose                 |
| ------------- | ------------ | ------ | ----------------------- |
| `level1`      | Basic        | 0      | Starter crafting        |
| `level2`      | Expert       | 10     | Mid-tier crafting       |
| `level3`      | Master       | 20     | High-tier crafting      |
| `police_gear` | Police Gear  | 0      | Police-only crafting    |
| `drugs`       | Black Market | 500    | Gang / illegal crafting |

***

## 10. Recipes Configuration

```lua
Config.Recipes = {
    ["weapon_pistol"] = { ... }
}
```

#### Purpose

Defines every craftable recipe in the system.

Each recipe controls:

* item name / key
* label shown in UI
* crafting time
* output quantity
* XP reward
* required ingredients
* job/gang restrictions (optional)

***

### 10.1 Recipe Fields Explained

#### Recipe Key

```lua
["weapon_pistol"] = { ... }
```

#### Purpose

This is the **crafted item name** (usually matches inventory item name).

#### Important Warning

Your config includes:

* `weapon_pistol`
* `WEAPON_PISTOL`

These are treated as **different keys**.\
Most frameworks use lowercase item names, so using uppercase may cause:

* crafting failures
* items not being given
* inventory mismatch issues

***

#### `label`

```lua
label = "9mm"
```

Name shown in the crafting UI.

***

#### `category`

```lua
category = "level1"
```

#### Purpose

Assigns the recipe to a category.

#### Important

The category must exist in:

* `Config.Categories`\
  AND be allowed inside the station `categories` list.

***

#### `time`

```lua
time = 5000
```

#### Purpose

Crafting duration in milliseconds.

Example:

* `5000` = 5 seconds

Final time is affected by:\
`Config.CraftingTimeMultiplier`

***

#### `output`

```lua
output = 3
```

#### Purpose

How many items are given after crafting completes.

Example:\
If output is `3`, player receives 3 of that item.

***

#### `xp`

```lua
xp = 25
```

#### Purpose

How much XP is rewarded after crafting.

***

#### `ingredients`

```lua
ingredients = {
    { item = "steel", amount = 2 },
}
```

#### Purpose

Items required to craft.

#### Behavior

Player must have all listed ingredients in required amounts.

***

#### `job` restriction (Optional)

```lua
job = "police"
```

Only players with this job can craft the recipe.

***

#### `gang` restriction (Optional)

```lua
gang = { "ballas", "families" }
```

Only players in these gangs can craft the recipe.

***

## 11. Your Recipes Breakdown

### 11.1 Public Workbench Recipes

#### 1) weapon\_pistol

* Category: `level1`
* Time: 5s
* Output: 3
* XP: 25
* Ingredients: `sandwich x3`

#### 2) lockpick

* Category: `level2`
* Time: 4s
* Output: 2
* XP: 15
* Ingredients: `steel x2`

#### 3) WEAPON\_PISTOL (uppercase)

* Category: `level3`
* Time: 5s
* Output: 3
* XP: 25
* Ingredients: `steel x3`

**Important:** This may not work correctly depending on your inventory item naming rules.

***

### 11.2 Police Armory Recipes

#### 1) weapon\_stungun

* Category: `police_gear`
* Time: 10s
* Output: 1
* XP: 50
* Job restricted: `police`
* Ingredients: `battery x8`

#### 2) weapon\_nightstick

* Category: `police_gear`
* Time: 8s
* Output: 1
* XP: 40
* Job restricted: `police`
* Ingredients: `steel x6`

***

### 11.3 Gang Workbench Recipes

#### 1) WEAPON\_APPISTOL (uppercase)

* Category: `level1`
* Time: 5s
* Output: 3
* XP: 25
* Ingredients: `steel x3`

**Note:** This recipe is in `level1`, but your gang station only allows:

```lua
categories = { "drugs" }
```

So this recipe will **NOT appear** in the gang bench unless you add `"level1"` to that station categories.

***

#### 2) weapon\_switchblade

* Category: `drugs`
* Time: 9s
* Output: 1
* XP: 80
* Gang restricted: `ballas`, `families`
* Ingredients: `steel x7`

This one will correctly show in the gang bench.

***

## 12. Common Setup Warnings (Very Important)

### 12.1 Category Not Showing

If a recipe does not appear, check:

1. Recipe category exists in `Config.Categories`
2. Station includes that category in `stations.categories`

Example fix:

```lua
categories = { "drugs", "level1" }
```

***

### 12.2 Job/Gang Names Must Match Exactly

Restrictions like:

```lua
job = "police"
gang = { "ballas", "families" }
```

Must match your framework values exactly (case-sensitive).

***


# Configuration File

### Config Files <a href="#config-files" id="config-files"></a>

{% code title="config.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
Config = {}
Config.Debug = false
Config.Framework = "auto" -- Options : "esx" or "qb" or "qbox"
Config.Interaction = "target" -- Options : "target" or 'textui'
Config.TargetSystem = 'ox' -- Options : "ox" or 'qb'
Config.CraftingTimeMultiplier = 1.0 
Config.MaxLevelXP = 5000 
Config.Locale = "fr" -- Options : en (English) | de (German) | fr (French) | es (Spanish) | ta (Tamil)

Config.Stations = {
    {
        type = "workbench",
        label = "Public Workbench",
        model = "prop_tool_bench02", 
        coords = vec4(248.4191, -791.4229, 30.4263, 160.2911), 
        blip = { enable = true, sprite = 237, color = 3, scale = 0.8, name = "Crafting" },
        categories = { "level1", "level2", "level3" },
        -- No job/gang = Public
    },
    {
        type = "police_bench",
        label = "Police Armory Crafting",
        model = "prop_tool_bench02", 
        coords = vec4(451.5702, -978.6896, 30.6896, 270.3503), -- Example Coords
        blip = { enable = true, sprite = 60, color = 38, scale = 0.6, name = "Police Crafting" },
        categories = { "police_gear" },
        job = "police" -- [RESTRICTION] Only police can open this
    },
    {
        type = "gang_bench",
        label = "Gang Workbench",
        model = "prop_tool_bench02", 
        coords = vec4(977.8250, -92.4746, 74.8452, 320.3503), -- Example Coords
        blip = { enable = false }, -- Hidden from map
        categories = { "drugs" },
        gang = { "ballas", "families" } -- [RESTRICTION] Only these gangs can open
    },
}

Config.Categories = {
    ["level1"] = { label = "Basic", icon = "fa-solid fa-star", minXP = 0 },
    ["level2"] = { label = "Expert", icon = "fa-solid fa-medal", minXP = 10 },
    ["level3"] = { label = "Master", icon = "fa-solid fa-crown", minXP = 20 },
    ["police_gear"] = { label = "Police Gear", icon = "fa-solid fa-shield", minXP = 0 },
    ["drugs"] = { label = "Black Market", icon = "fa-solid fa-skull", minXP = 500 },
}

Config.Recipes = {

    -- =====================================================
    -- PUBLIC WORKBENCH (2 RECIPES)
    -- =====================================================

     ["weapon_pistol"] = {
        label = "9mm",
        category = "level1",
        time = 5000,
        output = 3,
        xp = 25,
        ingredients = {
            { item = "sandwich", amount = 3 },
        }
    },

    ["lockpick"] = {
        label = "Lockpick",
        category = "level2",
        time = 4000,
        output = 2,
        xp = 15,
        ingredients = {
            { item = "steel", amount = 2 },
        }
    },


    ["WEAPON_PISTOL"] = {
        label = "9mm Pistol",
        category = "level3",
        time = 5000,
        output = 3,
        xp = 25,
        ingredients = {
            { item = "steel", amount = 3 },
        }
    },

    -- =====================================================
    -- POLICE ARMORY (2 RECIPES)
    -- =====================================================

    ["weapon_stungun"] = {
        label = "Taser",
        category = "police_gear",
        time = 10000,
        output = 1,
        xp = 50,
        job = "police",
        ingredients = {
            { item = "battery", amount = 8 },
        }
    },

    ["weapon_nightstick"] = {
        label = "Nightstick",
        category = "police_gear",
        time = 8000,
        output = 1,
        xp = 40,
        job = "police",
        ingredients = {
            { item = "steel", amount = 6 },
        }
    },

    -- =====================================================
    -- GANG WORKBENCH (2 RECIPES)
    -- =====================================================
     ["WEAPON_APPISTOL"] = {
        label = "AP Pistol",
        category = "level1",
        time = 5000,
        output = 3,
        xp = 25,
        ingredients = {
            { item = "steel", amount = 3 },
        }
    },


    ["weapon_switchblade"] = {
        label = "Switchblade",
        category = "drugs",
        time = 9000,
        output = 1,
        xp = 80,
        gang = { "ballas", "families" },
        ingredients = {
            { item = "steel", amount = 7 },
        }
    },
}
```

{% endcode %}


# Loading Screen

This resource is compatible with ESX , QBcore , Qbox

**nm1 Loading Screen** is a premium FiveM loading screen resource built for the Classy series. It displays a fullscreen video background, an animated music widget, rotating server tips, social links, and an optional team modal — all fully configurable from a single `config.js` file. The screen shuts down automatically once the player is fully loaded into the session.

<a href="https://nm1.tebex.io/package/loadingscreen" class="button primary">Buy yours now</a><a href="https://nm1.tebex.io/" class="button primary">Checkout all our scripts</a>

### Showcase

<figure><img src="https://2917216003-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOJIWkYsfazidAg4XFL3Z%2Fuploads%2FBScSHvX9LJtvcI4jfeID%2Fimage.png?alt=media&amp;token=9edc1380-fa4f-43bf-8c80-1dc420232630" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2917216003-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOJIWkYsfazidAg4XFL3Z%2Fuploads%2Fd3M1abwLAwqv9v5f8nna%2Fimage.webp?alt=media&amp;token=a5e3ca5e-0bfb-40b9-a100-3a524fbed5d0" alt=""><figcaption></figcaption></figure>


# Installation

Installation Guide of nm1-Scoreboard

#### 1. Download Resource <a href="#id-1.-download-resource" id="id-1.-download-resource"></a>

To Begin, by downloading the resource you have purchased from [our store](https://corem.tebex.io/)

Now Log in to your [cfx portal](https://portal.cfx.re/) account and navigate to the **Asset Grants** section. There, you will find a list of all resources associated with your account, from which you can download the required files.

#### 2. Frameworks Supported <a href="#id-2.-dependencies" id="id-2.-dependencies"></a>

* Standalone

#### 3. Ensuring Asset(s) <a href="#id-3.-asset-arrangement" id="id-3.-asset-arrangement"></a>

To ensure the asset(s) start correctly and function as intended, it is important that they are loaded in the proper order within your **server.cfg**. Below is an example illustrating the recommended startup sequence.

```
# 1. Start the core framework (choose the one your server uses)
ensure es_extended      # ESX
# ensure qb-core        # QB-Core
# ensure qbx_core       # Qbox

# 2. Start the nm1 scoreboard resource
ensure nm1-loadingscreen

# Or create a folder named [nm1] and start all nm1 resources.
# ensure [nm1]
```

{% hint style="danger" %}
**Important** Ensure nm1 scripts *after* your framework (es\_extended/qb-core /qbx-core).
{% endhint %}


# Full Configuration Guide

This document explains every available option in the provided config.js file and how each setting affects the nm1 Loading screen

Video Background

js

```js
video: {
    source: '...',
    blur: '0px',
    volume: 0.2
}
```

| Property | Type     | Description                                                                                                                     |
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `source` | `string` | Direct URL to the background video (.mp4 recommended). Also used for the dynamic preload — changing this is all you need to do. |
| `blur`   | `string` | CSS blur value. Use `'0px'` for no blur, e.g. `'4px'` to blur                                                                   |
| `volume` | `number` | Initial volume for music. Range: `0.0` (muted) to `1.0` (full)                                                                  |

***

### Music

js

```js
music: {
    enabled: true,
    playlist: [
        {
            artist: "ARTIST NAME",
            song:   "SONG NAME",
            cover:  'https://...',
            source: 'https://...'
        }
    ]
}
```

| Property            | Type      | Description                                                                                                                          |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled`           | `boolean` | Set to `true` to use a separate audio track. Video will be muted automatically. Set to `false` to use the video's own audio instead. |
| `playlist[]`        | `array`   | List of songs. The ⏮ / ⏭ buttons cycle through all entries. No limit on how many you add.                                            |
| `playlist[].artist` | `string`  | Artist name displayed on the music card                                                                                              |
| `playlist[].song`   | `string`  | Song name displayed on the music card                                                                                                |
| `playlist[].cover`  | `string`  | URL to the album/cover artwork image                                                                                                 |
| `playlist[].source` | `string`  | Direct URL to the audio file (.mp3 recommended). Host on FiveManage and paste the r2 URL.                                            |

> 💡 When a track ends it automatically advances to the next song in the playlist. All volume and play/pause controls target the audio player, not the video.

***

### Project / Branding

js

```js
project: {
    titlePart1: "NM1",
    titlePart2: "SCRIPTS",
    description: "...",
    color: "#00a2ff",
    topbarLabel: "...",
    version: "v1.0.0"
}
```

| Property      | Type     | Description                                                                       |
| ------------- | -------- | --------------------------------------------------------------------------------- |
| `titlePart1`  | `string` | First part of the large center title (rendered in the accent color)               |
| `titlePart2`  | `string` | Second part of the large center title (rendered in white)                         |
| `description` | `string` | Subtitle text displayed below the title                                           |
| `color`       | `string` | Primary accent color (hex). Applied to highlights, particles, and active elements |
| `topbarLabel` | `string` | Text shown in the top-left status bar                                             |
| `version`     | `string` | Version tag shown in the top-right corner                                         |

***

### Social Links

js

```js
socials: [
    { icon: "fa-brands fa-discord", link: "https://discord.gg/..." },
]
```

Each entry in the `socials` array creates a clickable icon button. You can add or remove as many as you like.

| Property | Type     | Description                                               |
| -------- | -------- | --------------------------------------------------------- |
| `icon`   | `string` | Font Awesome 6 class string (e.g. `fa-brands fa-twitter`) |
| `link`   | `string` | URL that opens when the icon is clicked                   |

***

### Server Tips

js

```js
tips: [
    "Know the rules of your server - seriously.",
    "Press F1 to open the main menu.",
    "Respect the staff team at all times."
]
```

Tips are displayed one at a time in the bottom-left tip box and rotate every 5 seconds with a fade transition. Add as many strings as you want.

***

### Team Modal

js

```js
showTeamButton: true,

team: [
    { name: "Felix", role: "Owner", avatar: "https://yourlink.com/avatar.jpg" },
]
```

| Property         | Type      | Description                                           |
| ---------------- | --------- | ----------------------------------------------------- |
| `showTeamButton` | `boolean` | Set to `false` to hide the "OUR TEAM" button entirely |
| `team[].name`    | `string`  | Staff member's display name                           |
| `team[].role`    | `string`  | Staff member's role (displayed in uppercase)          |
| `team[].avatar`  | `string`  | URL to the member's avatar image                      |

> 💡 The team grid is inside a scrollable modal, so there is no member limit. Click the backdrop or the ✕ button to close it.

### How It Works (Technical)

#### Loading & Shutdown Flow

1. When the player connects, `client.lua` immediately creates a black scripted camera to prevent the default GTA bridge camera from showing.
2. The HTML loading screen (`index.html`) is displayed by FiveM via the `loadscreen` manifest entry.
3. `config.js` is loaded first in the `<head>` and immediately injects a `<link rel="preload">` for the background video using `Config.video.source`, so the video starts buffering before any other asset loads.
4. The client script polls until three conditions are all true: the network session has started, the player is active, and the player ped exists.
5. After a 2-second safety delay, it sends a `{ action: "shutdown" }` NUI message to the loading screen, triggering a fade-out animation on the HTML side.
6. After 800ms, `ShutdownLoadingScreen()` and `ShutdownLoadingScreenNui()` are called, the custom camera is destroyed, and the screen fades back in cleanly over 1 second.

#### Progress Bar

The loading bar is driven by FiveM's native `loadProgress` events sent to the NUI. The status text updates automatically through the following stages:

| Event                    | Status Text                    |
| ------------------------ | ------------------------------ |
| `startInitFunctionOrder` | Initializing Session...        |
| `initFunctionInvoking`   | Loading: `<resource name>`     |
| `startDataFileEntries`   | Loading Map Assets...          |
| `onLogLine`              | Shows the raw log line message |


# Media Hosting

We recommend using **FiveManage** to host your video, music cover, and avatar images. FiveManage is a fast, reliable media hosting platform built specifically for FiveM servers, making it the ideal choice for loading screen assets.

Upload your files at: [**https://app.fivemanage.com/**](https://app.fivemanage.com/)

Once uploaded, copy the direct media URL and paste it into the relevant fields in `config.js`:

| Config Field      | What to upload                   |
| ----------------- | -------------------------------- |
| `video.source`    | Your background video (`.mp4`)   |
| `musicInfo.cover` | Your album/cover artwork image   |
| `team[].avatar`   | Each staff member's avatar image |

> 💡 The default assets included in this resource are already hosted on FiveManage as an example of how your URLs should look.


# Configuration File

### Config File <a href="#config-files" id="config-files"></a>

{% code title="config.js" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
const Config = {
    // VIDEO CONFIGURATION
    video: {
        source: 'https://r2.fivemanage.com/m1SP9rNB8QYEmyvcw6LMp/NM1_BG_VIDEO.mp4',
        blur: '0px',
        volume: 0.2
    },

    // ── MUSIC CONFIGURATION ───────────────────────────────────────────────
    // Set enabled: true  → plays playlist below, video will be muted automatically
    // Set enabled: false → video audio is used instead, playlist is ignored
    music: {
        enabled: true,

        // Add as many songs as you want — ⏮ / ⏭ buttons cycle through them
        // Upload your audio + cover files to FiveManage and paste the r2 URLs below
        playlist: [
            {
                artist: "Anirudh Ravichander",
                song:   "Ordinary Person ",
                cover:  'https://r2.fivemanage.com/m1SP9rNB8QYEmyvcw6LMp/NM1_MUSIC_IMG.png',
                source: 'https://r2.fivemanage.com/m1SP9rNB8QYEmyvcw6LMp/NM1_MUSIC_SEP.mp3'
            },
            {
                artist: "Anirudh Ravichander",
                song:   "Anbenum",
                cover:  'https://images.indianexpress.com/2023/10/Poster-of-Anbenum-song-from-Leo.jpg?w=1200',
                source: 'https://r2.fivemanage.com/m1SP9rNB8QYEmyvcw6LMp/NM1_MUSIC_2.mp3'
            },
            {
                artist: "ARTIST NAME",
                song:   "SONG NAME",
                cover:  'https://r2.fivemanage.com/YOUR_KEY/cover3.png',
                source: 'https://r2.fivemanage.com/YOUR_KEY/song3.mp3'
            },
            {
                artist: "ARTIST NAME",
                song:   "SONG NAME",
                cover:  'https://r2.fivemanage.com/YOUR_KEY/cover4.png',
                source: 'https://r2.fivemanage.com/YOUR_KEY/song4.mp3'
            },
            // Keep adding more below — no limit
        ]
    },

    project: {
        titlePart1: "NM1",
        titlePart2: "SCRIPTS",
        description: "Welcome to NM1 Scripts. High quality resources for your server.",
        color: "#00a2ff",
        topbarLabel: "NM1 Scripts — Server Loading",
        version: "v1.0.0"
    },

    socials: [
        { icon: "fa-brands fa-discord", link: "https://discord.gg/nAVCGRRwYu" },
        { icon: "fa-brands fa-youtube", link: "https://www.youtube.com/@nm1Scripts" },
        { icon: "fa-solid fa-globe",    link: "https://nm1.tebex.io/" }
    ],

    tips: [
        "Know the rules of your server - seriously.",
        "Press F1 to open the main menu.",
        "Respect the staff team at all times."
    ],

    // ── OUR TEAM ──────────────────────────────────────────
    // Set showTeamButton: false to hide the button entirely
    // Add as many members as you want — the modal scrolls automatically
    showTeamButton: true,

    team: [
        { name: "Felix",   role: "Owner",     avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Alex",    role: "Developer", avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Sarah",   role: "Manager",   avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "James",   role: "Admin",     avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Emma",    role: "Moderator", avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Liam",    role: "Developer", avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Noah",    role: "Support",   avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Ava",     role: "Builder",   avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "William", role: "Admin",     avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" },
        { name: "Sophia",  role: "Moderator", avatar: "https://i.pinimg.com/736x/94/76/dd/9476dd3d346a3d697362da94b9aa2dc2.jpg" }
        // Add more members below — no limit
    ]
};
```

{% endcode %}


# Advanced Classy Notification

This resource is compatible with ESX , QBcore , Qbox / Standalone

<a href="https://nm1.tebex.io/package/classynotification" class="button primary">Get it for free</a><a href="https://nm1.tebex.io/" class="button primary">Checkout all our scripts</a>

### Showcase

{% embed url="<https://youtu.be/OSsaItxOVGY?si=stmStiyUqrnq49g8>" %}


# Installation

Installation Guide of nm1-Scoreboard

#### 1. Download Resource <a href="#id-1.-download-resource" id="id-1.-download-resource"></a>

To Begin, by downloading the resource you have purchased from [our store](https://corem.tebex.io/)

Now Log in to your [cfx portal](https://portal.cfx.re/) account and navigate to the **Asset Grants** section. There, you will find a list of all resources associated with your account, from which you can download the required files.

#### 2. Frameworks Supported <a href="#id-2.-dependencies" id="id-2.-dependencies"></a>

* ESX
* QBcore
* Qbox
* Standalone

#### 3. Ensuring Asset(s) <a href="#id-3.-asset-arrangement" id="id-3.-asset-arrangement"></a>

To ensure the asset(s) start correctly and function as intended, it is important that they are loaded in the proper order within your **server.cfg**. Below is an example illustrating the recommended startup sequence.

```
# 1. Start the core framework (choose the one your server uses)
# ensure es_extended      # ESX
# ensure qb-core        # QB-Core
# ensure qbx_core       # Qbox
# ensure your_own_framework # Standalone

# 2. Start the nm1 notification resource
ensure nm1-classynotify

# Or create a folder named [nm1] and start all nm1 resources.
# ensure [nm1]
```

{% hint style="danger" %}
**Important** Ensure nm1 scripts *after* your framework&#x20;
{% endhint %}


# SQL

Auto-created on resource start via oxmysql. Run this only if creating manually.

```sql
CREATE TABLE IF NOT EXISTS `nm1_notify_settings` (
    `identifier`           VARCHAR(60)  NOT NULL,
    `variant`              TINYINT      NOT NULL DEFAULT 1,
    `position`             VARCHAR(20)  NOT NULL DEFAULT 'top-right',
    `mute_sound`           TINYINT(1)   NOT NULL DEFAULT 0,
    `disable_animations`   TINYINT(1)   NOT NULL DEFAULT 0,
    `updated_at`           TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`identifier`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

```


# Exports

## nm1\_classynotify Documentation

This document describes all available exports provided by the `nm1_classynotify` resource, including client-side and server-side usage, parameters, defaults, supported types, positions, and examples.

The system is framework-compatible and works with ESX, QBCore, QBox, and standalone setups.

***

## Client Exports

### exports\['nm1\_classynotify']:Notify(data)

Displays a notification on the local client.

This is the primary and recommended client export for showing notifications.

***

### Parameters

`data` (table)

| Parameter    | Type    | Required | Default             | Description                  |
| ------------ | ------- | -------- | ------------------- | ---------------------------- |
| title        | string  | No       | "Notification"      | Notification title           |
| description  | string  | Yes      | nil                 | Main notification message    |
| type         | string  | No       | "info"              | Notification type            |
| duration     | number  | No       | 5000                | Duration in milliseconds     |
| position     | string  | No       | Saved/User Position | Notification screen position |
| icon         | string  | No       | nil                 | FontAwesome icon             |
| theme        | string  | No       | "dark"              | Notification theme           |
| sound        | boolean | No       | true                | Plays notification sound     |
| showProgress | boolean | No       | true                | Shows duration progress bar  |

***

## Supported Types

* success
* error
* info
* warning

***

## Supported Positions

* top-right
* top-left
* top-center
* bottom-right
* bottom-left
* bottom-center
* center-right
* center-left

***

## Example (Client)

```lua
exports['nm1_classynotify']:Notify({
    title = 'Success',
    description = 'Data saved successfully.',
    type = 'success',
    duration = 4000
})
```

***

## Example (Custom Position & Icon)

```lua
exports['nm1_classynotify']:Notify({
    title = 'Fuel Warning',
    description = 'Your vehicle fuel is low.',
    type = 'warning',
    position = 'bottom-left',
    icon = 'fas fa-gas-pump'
})
```

***

## Example (Light Theme)

```lua
exports['nm1_classynotify']:Notify({
    title = 'Information',
    description = 'Theme switched successfully.',
    type = 'info',
    theme = 'light'
})
```

***

## Server Exports

Server exports allow notifications to be triggered directly from server-side scripts.

***

### exports\['nm1\_classynotify']:NotifyPlayer(src, data)

Sends a notification to a specific player.

***

### Parameters

| Parameter | Type   | Description             |
| --------- | ------ | ----------------------- |
| src       | number | Player server ID        |
| data      | table  | Notification data table |

***

## Example (Server)

```lua
exports['nm1_classynotify']:NotifyPlayer(source, {
    title = 'Server',
    description = 'You received a server notification.',
    type = 'info'
})
```

***

### exports\['nm1\_classynotify']:NotifyAll(data)

Broadcasts a notification to all connected players.

***

### Parameters

| Parameter | Type  | Description             |
| --------- | ----- | ----------------------- |
| data      | table | Notification data table |

***

## Example (Broadcast)

```lua
exports['nm1_classynotify']:NotifyAll({
    title = 'Announcement',
    description = 'Server restart in 5 minutes.',
    type = 'warning',
    duration = 7000
})
```

***

## Events

### Client Event

```lua
TriggerEvent('nm1_classynotify:client:notify', data)
```

Used internally and can also be triggered manually from client scripts.

***

### Server Event

```lua
TriggerClientEvent('nm1_classynotify:client:notify', src, data)
```

Used internally by server exports.

***

## Notification Features

* Modern animated NUI notifications
* Custom notification positions
* Progress bar support
* Sound effects
* Persistent user settings
* Light/Dark theme support
* FontAwesome icon support
* ox\_lib compatibility
* ESX/QBCore/QBox compatible
* Standalone support

***

## Notes & Behavior

* Saved notification settings are persisted per player
* Position settings automatically apply on resource start
* If `position` is passed in `data`, it overrides the saved position for that notification only
* Theme defaults to `"dark"` if not provided
* Duration is automatically handled by the NUI system
* Notifications are stacked dynamically
* Supports multiple notifications simultaneously

***

## Recommended Usage

Use the export system instead of manually triggering NUI events whenever possible.

Recommended:

```lua
exports['nm1_classynotify']:Notify({
    title = 'Success',
    description = 'Action completed successfully.',
    type = 'success'
})
```

Avoid directly sending raw NUI messages unless modifying the core resource.


# Intergrations

### 🔔 Notification System Integration

After integrating our notification system **directly into the framework core and `ox_lib`**, the notification **type is set to `info` as the primary default**.\
This ensures consistent behavior across all supported frameworks while maintaining compatibility with existing notification calls.

***

### ⚙️ Quick & Easy Installation

To simplify setup and reduce integration time, we have provided **ready-to-use code snippets**.\
These snippets are designed to **replace existing notification handlers** in their respective frameworks.

All replacements are covered in detail on the **next page**


# ESX

es\_extended/client/functions.lua  \[Search **function ESX.ShowNotification** ]

{% code title="es\_extended/client/functions.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
---@param message string The message to show
---@param notifyType? string The type of the notification
---@param length? number The length of the notification
---@param title? string The title of the notification
---@param position? string The position of the notification
---@return nil
function ESX.ShowNotification(message, notifyType, length, title, position)

    local typeMap = {
        [0] = 'info',
        [1] = 'success',
        [2] = 'error',
        [3] = 'warning',
    }

    local resolvedType = typeMap[notifyType] or notifyType or 'info'

    local success = pcall(function()
        exports['nm1-classynotify']:Notify({
            type = resolvedType,
            message = message,
            title = title,
            duration = length or 5000,
            position = position or 'top-right'
        })
    end)

    if not success then
        print('^1[nm1-classynotify]^7 Failed to send notification. Is the resource started?')
    end
end
```

{% endcode %}


# qbcore

qb-core/client/functions.lua

{% code title="qb-core/client/nm1notify.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
function QBCore.Functions.Notify(text, texttype, length, icon)

    local typeMap = {
        primary = 'info',
        error = 'error',
        success = 'success',
        warning = 'warning',
        info = 'info',
    }

    local message, title

    if type(text) == 'table' then
        message = text.text or 'Placeholder'
        title = text.caption or nil
    else
        message = text
    end

    local success = pcall(function()
        exports['nm1-classynotify']:Notify({
            type = typeMap[texttype] or 'info',
            message = message,
            title = title,
            duration = length or 5000,
            icon = icon or nil,
            position = 'top-right'
        })
    end)

    if not success then
        print('^1[nm1-classynotify]^7 Failed to send notification. Is the resource started?')
    end
end
```

{% endcode %}


# ox\_lib

ox\_lib\resource\interface\client\notify.lua \[Replace Full File]

{% code title="ox\_lib\resource\interface\client\notify.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
---@class NotifyProps
---@field id?          string
---@field title?       string
---@field description? string
---@field message?     string
---@field duration?    number
---@field type?        string
---@field status?      string

-- Maps ox_lib type aliases → nm1-classynotify type keys
local typeMap = {
    [0]       = 'info',
    [1]       = 'success',
    [2]       = 'error',
    [3]       = 'warning',
    inform    = 'info',
    primary   = 'info',
    secondary = 'default',
    dark      = 'default',
}

local function resolveType(t)
    return typeMap[t] or t or 'default'
end

---@param data NotifyProps
function lib.notify(data)
    if not data then return end

    local ok, err = pcall(function()
        exports['nm1-classynotify']:Notify({
            type     = resolveType(data.type or data.status),
            title    = data.title,
            message  = data.description or data.message,
            duration = data.duration,
        })
    end)

    if not ok then
        -- nm1-classynotify not available — print once and do nothing
        print('^3[nm1-classynotify] Bridge warning: ' .. tostring(err) .. '^7')
    end
end

---@param data NotifyProps
function lib.defaultNotify(data)
    if not data then return end
    lib.notify({
        type     = resolveType(data.status or data.type),
        title    = data.title,
        message  = data.description or data.message,
        duration = data.duration,
    })
end
```

{% endcode %}


# nm1 Notification

This resource is compatible with ESX , QBcore , Qbox / Standalone

<a href="https://nm1.tebex.io/package/notification-free" class="button primary">Get it for free</a><a href="https://nm1.tebex.io/" class="button primary">Checkout all our scripts</a>

### Showcase

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


# Installation

Installation Guide of nm1-Scoreboard

#### 1. Download Resource <a href="#id-1.-download-resource" id="id-1.-download-resource"></a>

To Begin, by downloading the resource you have purchased from [our store](https://corem.tebex.io/)

Now Log in to your [cfx portal](https://portal.cfx.re/) account and navigate to the **Asset Grants** section. There, you will find a list of all resources associated with your account, from which you can download the required files.

#### 2. Frameworks Supported <a href="#id-2.-dependencies" id="id-2.-dependencies"></a>

* ESX
* QBcore
* Qbox
* Standalone

#### 3. Ensuring Asset(s) <a href="#id-3.-asset-arrangement" id="id-3.-asset-arrangement"></a>

To ensure the asset(s) start correctly and function as intended, it is important that they are loaded in the proper order within your **server.cfg**. Below is an example illustrating the recommended startup sequence.

```
# 1. Start the core framework (choose the one your server uses)
# ensure es_extended      # ESX
# ensure qb-core        # QB-Core
# ensure qbx_core       # Qbox
# ensure your_own_framework # Standalone

# 2. Start the nm1 notification resource
ensure nm1-notification 

# Or create a folder named [nm1] and start all nm1 resources.
# ensure [nm1]
```

{% hint style="danger" %}
**Important** Ensure nm1 scripts *after* your framework&#x20;
{% endhint %}


# Exports

This document describes **all available exports** provided by the `nm1_notification` resource, including **client-side** and **server-side** usage, parameters, defaults, and examples.

The system is **framework-agnostic** and works with ESX, QBCore, QBox, or standalone setups.

***

### Client Exports

#### `exports['nm1_notification']:Notify(data)`

Displays a notification **on the local client**.

This is the **primary and recommended client export** for showing notifications.

***

#### Parameters

`data` *(table)*

| Field      | Type   | Required | Default             | Description              |
| ---------- | ------ | -------- | ------------------- | ------------------------ |
| `title`    | string | No       | `"Notification"`    | Notification title       |
| `message`  | string | No       | `""`                | Notification body text   |
| `type`     | string | No       | `"info"`            | Notification type        |
| `duration` | number | No       | `5000`              | Duration in milliseconds |
| `position` | string | No       | Saved / `top-right` | Screen position          |
| `theme`    | string | No       | `"dark"`            | UI theme                 |

***

#### Supported Types

* `success`
* `error`
* `info`
* `warning`

***

#### Supported Positions

* `top`
* `top-right`
* `top-left`
* `bottom`
* `bottom-right`
* `bottom-left`
* `center-right`
* `center-left`

***

#### Example (Client)

```lua
exports['nm1_notification']:Notify({
    title = 'Success',
    message = 'Data saved successfully.',
    type = 'success',
    duration = 4000
})
```

***

#### Example (With Custom Position & Theme)

```lua
exports['nm1_notification']:Notify({
    title = 'Warning',
    message = 'Low fuel level.',
    type = 'warning',
    position = 'bottom-left',
    theme = 'light' -- or dark
})
```

***

### Server Exports

Server exports allow you to trigger notifications **from server-side code** to one or all players.

***

#### `exports['nm1_notification']:NotifyPlayer(src, data)`

Sends a notification to a **specific player**.

***

**Parameters**

| Field  | Type   | Required | Description                        |
| ------ | ------ | -------- | ---------------------------------- |
| `src`  | number | Yes      | Player server ID                   |
| `data` | table  | Yes      | Notification data (same as client) |

***

**Example (Server)**

```lua
exports['nm1_notification']:NotifyPlayer(source, {
    title = 'Server',
    message = 'You received a server notification.',
    type = 'info'
})
```

***

#### `exports['nm1_notification']:NotifyAll(data)`

Broadcasts a notification to **all connected players**.

***

**Parameters**

| Field  | Type  | Required | Description       |
| ------ | ----- | -------- | ----------------- |
| `data` | table | Yes      | Notification data |

***

**Example (Server)**

```lua
exports['nm1_notification']:NotifyAll({
    title = 'Announcement',
    message = 'Server restart in 5 minutes.',
    type = 'warning',
    duration = 6000
})
```

***

### Notes & Behavior

* All server exports internally trigger the client event\
  `nm1_notification:client:show`
* Saved notification position is persisted using **Resource KVP**
* Position is automatically applied:
  * On resource start
  * On player spawn
* If `position` is passed in `data`, it **overrides the saved position for that notification only**
* Theme defaults to `"dark"` if not provided

***

### Recommended Usage

| Scenario                | Recommended Export |
| ----------------------- | ------------------ |
| Client-only UI feedback | `Notify`           |
| Server → single player  | `NotifyPlayer`     |
| Server → all players    | `NotifyAll`        |

***


# Intergrations

### 🔔 Notification System Integration

After integrating our notification system **directly into the framework core and `ox_lib`**, the notification **type is set to `info` as the primary default**.\
This ensures consistent behavior across all supported frameworks while maintaining compatibility with existing notification calls.

***

### ⚙️ Quick & Easy Installation

To simplify setup and reduce integration time, we have provided **ready-to-use code snippets**.\
These snippets are designed to **replace existing notification handlers** in their respective frameworks.

All replacements are covered in detail on the **next page**.

***

### 📦 Snippets Available

The following framework-specific snippets are available:

* **ESX** — `es_extended`
* **Qbox** — `qbx_core`
* **ox** — `ox_lib`
* **QB** — *Not provided*
  * You may implement this manually using the same pattern shown in the other snippets.

***


# ox\_lib

ox\_lib\resource\interface\client\notify.lua \[Replace Full File]

#### Light Theme 👇

{% code title="ox\_lib\resource\interface\client\notify.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
local settings = require 'resource.settings'

---`client`
---@param data NotifyProps
---@diagnostic disable-next-line: duplicate-set-field
function lib.notify(data)
    local sound = settings.notification_audio and data.sound
    data.sound = nil

    exports['nm1_notification']:Notify({
        title = data.title or 'Notification',
        message = data.description or '',
        type = data.type or 'info',
        duration = data.duration or 5000,
        position = data.position or settings.notification_position,
        theme = settings.notification_theme or 'light'
    })

    -- ox_lib still owns sound
    if not sound then return end

    if sound.bank then lib.requestAudioBank(sound.bank) end

    local soundId = GetSoundId()
    PlaySoundFrontend(soundId, sound.name, sound.set, true)
    ReleaseSoundId(soundId)

    if sound.bank then ReleaseNamedScriptAudioBank(sound.bank) end
end
```

{% endcode %}

#### Dark Theme 👇

{% code title="ox\_lib\resource\interface\client\notify.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
local settings = require 'resource.settings'

---`client`
---@param data NotifyProps
---@diagnostic disable-next-line: duplicate-set-field
function lib.notify(data)
    local sound = settings.notification_audio and data.sound
    data.sound = nil

    exports['nm1_notification']:Notify({
        title = data.title or 'Notification',
        message = data.description or '',
        type = data.type or 'info',
        duration = data.duration or 5000,
        position = data.position or settings.notification_position,
        theme = settings.notification_theme or 'dark'
    })

    -- ox_lib still owns sound
    if not sound then return end

    if sound.bank then lib.requestAudioBank(sound.bank) end

    local soundId = GetSoundId()
    PlaySoundFrontend(soundId, sound.name, sound.set, true)
    ReleaseSoundId(soundId)

    if sound.bank then ReleaseNamedScriptAudioBank(sound.bank) end
end
```

{% endcode %}


# ESX

es\_extended/client/functions.lua  \[Search **function ESX.ShowNotification** ]

#### Light Theme 👇

{% code title="es\_extended/client/functions.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
function ESX.ShowNotification(message, notifyType, length, title, position)
    exports['nm1_notification']:Notify({
        title = title or 'Notification',
        message = message,
        type = notifyType or 'info',
        duration = length or 5000,
        position = position,
        theme = settings.notification_theme or 'light'
    })
end
```

{% endcode %}

#### Dark Theme 👇

{% code title="es\_extended/client/functions.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
function ESX.ShowNotification(message, notifyType, length, title, position)
    exports['nm1_notification']:Notify({
        title = title or 'Notification',
        message = message,
        type = notifyType or 'info',
        duration = length or 5000,
        position = position,
        theme = settings.notification_theme or 'dark'
    })
end
```

{% endcode %}


# qbcore

&#x20;NM1 Notification Override (QBCore) -- --\[\[ Setup Instructions:

1. Place this file in the qb-core/client/ resource directory and name it `nm1notify.lua`.
2. Edit the `fxmanifest.lua` file inside qb-core.
3. Append the following line at the end of the manifest to guarantee proper load order:

   client\_script 'nm1notify.lua'
4. Restart the server to apply the changes. --]]

#### Light Theme 👇

{% code title="qb-core/client/nm1notify.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
local originalNotify = QBCore.Functions.Notify

QBCore.Functions.Notify = function(text, texttype, length)
    if GetResourceState("nm1_notification") == "started" then
        local message = text
        local title = 'Notification'

        -- Handle table-based notify calls
        if type(text) == 'table' then
            message = text.text or text.caption or ''
            title = text.title or title
        end

        local notifyType = texttype or 'info'

        -- Normalize QBCore types → nm1 types
        if notifyType == 'primary' then notifyType = 'info' end
        if notifyType == 'warning' then notifyType = 'warning' end
        if notifyType == 'error' then notifyType = 'error' end
        if notifyType == 'success' then notifyType = 'success' end

        exports['nm1_notification']:Notify({
            title = title,
            message = message,
            type = notifyType,
            duration = length or 5000,
            theme = 'light' -- change to 'light' if needed
        })
    else
        -- Fallback to default QBCore notify
        originalNotify(text, texttype, length)
    end
end

```

{% endcode %}

#### Dark Theme 👇

{% code title="qb-core/client/nm1notify.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
local originalNotify = QBCore.Functions.Notify

QBCore.Functions.Notify = function(text, texttype, length)
    if GetResourceState("nm1_notification") == "started" then
        local message = text
        local title = 'Notification'

        -- Handle table-based notify calls
        if type(text) == 'table' then
            message = text.text or text.caption or ''
            title = text.title or title
        end

        local notifyType = texttype or 'info'

        -- Normalize QBCore types → nm1 types
        if notifyType == 'primary' then notifyType = 'info' end
        if notifyType == 'warning' then notifyType = 'warning' end
        if notifyType == 'error' then notifyType = 'error' end
        if notifyType == 'success' then notifyType = 'success' end

        exports['nm1_notification']:Notify({
            title = title,
            message = message,
            type = notifyType,
            duration = length or 5000,
            theme = 'dark' -- change to 'light' if needed
        })
    else
        -- Fallback to default QBCore notify
        originalNotify(text, texttype, length)
    end
end

```

{% endcode %}


# Qbox

qbx\_core/server/functions.lua  \[Search **function Notify**]&#x20;

#### Light Theme 👇

{% code title="qbx\_core/server/functions.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
---@see client.lua:Notify.Show
function Notify(source, text, notifyType, duration, subTitle, notifyPosition, notifyStyle, notifyIcon, notifyIconColor)
    local title, message

    -- Normalize text input
    if type(text) == 'table' then
        title = text.text or 'Notification'
        message = text.caption or ''
    elseif subTitle then
        title = text
        message = subTitle
    else
        title = 'Notification'
        message = text
    end

    -- Build nm1-compatible payload
    local data = {
        title = title,
        message = message,
        type = notifyType or 'info',
        duration = duration or 5000,
        theme = notifyStyle or 'dark'
    }

    -- Optional position override
    if notifyPosition then
        data.position = notifyPosition
    end

    TriggerClientEvent('nm1_notification:client:show', source, data)
end

exports('Notify', Notify)
```

{% endcode %}

#### Dark Theme 👇

{% code title="qbx\_core/server/functions.lua" overflow="wrap" lineNumbers="true" fullWidth="false" expandable="true" %}

```lua
---@see client.lua:Notify.Show
function Notify(source, text, notifyType, duration, subTitle, notifyPosition, notifyStyle, notifyIcon, notifyIconColor)
    local title, message

    -- Normalize text input
    if type(text) == 'table' then
        title = text.text or 'Notification'
        message = text.caption or ''
    elseif subTitle then
        title = text
        message = subTitle
    else
        title = 'Notification'
        message = text
    end

    -- Build nm1-compatible payload
    local data = {
        title = title,
        message = message,
        type = notifyType or 'info',
        duration = duration or 5000,
        theme = notifyStyle or 'dark'
    }

    -- Optional position override
    if notifyPosition then
        data.position = notifyPosition
    end

    TriggerClientEvent('nm1_notification:client:show', source, data)
end

exports('Notify', Notify)
```

{% endcode %}


