Nord Inventory · v2.0.0 Documentation Complete production documentation for Nord Inventory v2.0.0 by Nord Lab. Welcome · Nord Inventory Welcome · Nord Inventory Nord Inventory is Nord Lab's production inventory platform for FiveM. It combines server-authoritative item state, metadata, durability, containers, vehicle storage, Admin Studio, Operations & Forensics, a provider-aware developer SDK, player inventory customization and modular integrations in one resource. Applies to: Nord Inventory v2.0.0 What this documentation covers This book is audited against the production 2.0.0 resource. It covers: installation, startup order, SQL and production packaging; ESX, QB-Core, QBX/Qbox, Nord Core, Standalone and custom framework modes; item definitions, metadata, durability, expiration, rarity and containers; Fast Slots, hotbar, Equipment Slots 2.0, ground drops and player interactions; Admin Studio, provider registry, diagnostics, backups, audit and recommended scripts; Operations & Forensics: Ledger, Anti-Dupe, Item Instance Explorer, Inventory Manager and snapshots; persistent placed items and per-item/per-category movement policies; the public server/client export surface present in v2.0.0; vehicle trunk/glovebox storage and lock/session security; Nord ecosystem integrations and migration patterns from OX/QB-style inventories. Design principle Nord Inventory treats the server as the authority. NUI state is presentation only. Item mutations, ownership, capacity, metadata, robbery transfers, vehicle sessions, persistent placement and administrative changes are validated server-side. Resource name Keep the resource folder named exactly: nord_inventory Many integrations intentionally call exports.nord_inventory:.... Documentation status This edition is the v2.0.0 reference. When older notes disagree with this book, use the v2.0.0 configuration, SQL map, permissions and export index documented here as the source of truth. Quick Start Quick Start Minimal production installation for a new server. Applies to: Nord Inventory v2.0.0 1. Install dependencies Nord Inventory requires oxmysql. ensure oxmysql ensure nord_inventory Start the selected framework before nord_inventory when the framework itself requires that order. Start resources that register Nord Inventory items after nord_inventory. 2. Import SQL Import: nord_inventory/sql/nord_inventory.sql v2.0.0 also uses nord_inventory_snapshots, nord_inventory_forensics_alerts and nord_inventory_placed_items. Auto-SQL creates missing Operations tables with CREATE TABLE IF NOT EXISTS, but production servers should still import the supplied schema. 3. Select framework config/core.lua: Config.Framework = 'auto' Supported values: auto, esx, qb, qbox, nord, standalone, custom. 4. Configure administrator access Recommended ACE setup: add_ace group.dev nord_inventory.dev allow add_ace group.admin nord_inventory.admin allow add_ace group.owner nord_inventory.owner allow The default Admin Studio command is /norditems. Operations permissions are mapped through the same role bridge. 5. Choose language Config.Locale = 'pt' -- pt | en Config.LocaleFallback = 'en' 6. Review v2.0.0 Operations defaults Check config/operations.lua before production. Important sections: scan/result limits; snapshot retention; persistent placed items; optional clothing bridge; item/category movement policies. All policy fields default to allow when omitted, so upgrading does not silently block old flows. 7. First verification After startup confirm: player inventory opens with TAB; /norditems opens for an authorized user; System Health reports no critical database/provider errors; Operations opens for an admin; create one manual snapshot and verify it appears; run one Anti-Dupe scan and review the result; give/remove a test item and confirm reconnect/restart persistence; place a disposable persistent item and confirm it survives a resource restart; equip/use a long weapon and confirm the back prop updates immediately; trunk/glovebox sessions close when the vehicle is locked or leaves range. 8. Integrate other resources Prefer the public exports documented in Developer API & Integrations. Do not rely on private events, NUI callbacks or direct writes to Nord Inventory tables. Architecture at a Glance Architecture at a Glance How the resource is separated into editable configuration, public integration surfaces and protected inventory authority. Applies to: Nord Inventory v2.0.0 Layers Layer Purpose Typical files Configuration Owner-editable policy and defaults config/*.lua Shared definitions Categories, items, weapons and common utilities shared/*.lua Bridges Framework/notify/TextUI/target/lock compatibility client/bridge/*, server/bridge/* Runtime core Inventory authority, persistence, sessions server/core/*, client/core/* Modules Admin, commands, vehicles, public SDK server/modules/*, client/modules/* NUI Player inventory and Admin Studio web/* Locales PT/EN visible strings locales/*.json Database Persistent registry/state/history sql/nord_inventory.sql Authority boundaries The server owns item state, slot state, money bridge operations, metadata, durability and storage sessions. The client owns presentation, input and a read-only local inventory snapshot used by client exports. The NUI never grants itself permissions; administrative mutations are revalidated by the server. Runtime providers register through explicit exports and are tracked by resource ownership. Open vs protected release surface The production package is designed for Tebex/Cfx Asset Escrow. Configuration, public bridge points, shared registries, locale files, SQL/reference files and item art stay owner-editable where appropriate. Core server authority remains protected. Compatibility strategy Integrations should prefer capability detection: local caps = exports.nord_inventory:GetCapabilities() if caps and caps.runtime_items then -- Register items dynamically. end This avoids assuming that every server uses the same optional features. Build Compatibility · 2.0.0 Build Compatibility · 2.0.0 Snapshot of the production defaults and documented surfaces in this package. Applies to: Nord Inventory v2.0.0 Production identity Resource: nord_inventory Version: 2.0.0 Author: Nord Lab Required dependency: oxmysql Default locale: pt Default inventory key: TAB Default Admin Studio command: /norditems Default quick hotbar key: Z v2.0.0 additions Operations & Forensics Center; searchable transaction Ledger and clear-records action; Anti-Dupe Center with persisted alerts; Item Instance Explorer; live/offline Inventory Manager; manual, automatic and pre-restore snapshots; persistent placed world items; item/category movement policies; provider dependency graph; Equipment Slots 2.0 explicit item allowlists; optional physical-clothing hand-off bridge; Operations exports for policy, snapshot, ledger and instance lookup; Nord Lab/Renovax Store + Documentation links in Recommended Scripts; runtime hardening for back weapons, ground props, metadata identities, non-stackable items and save/restart synchronization. Framework compatibility Config.Framework accepts: auto | esx | qb | qbox | nord | standalone | custom Database compatibility No destructive migration is required from the recent v1.x line. Existing storage is preserved. v2.0.0 adds three idempotent Operations tables and keeps the old public permission/export behavior unless explicitly expanded in this documentation. Upgrade rule Install the complete v2.0.0 resource and merge intentional values into the new config/ files. Do not overwrite the new configuration directory with an older copy; config/operations.lua is required for the new systems. Setup & Configuration Overview · Setup & Configuration 1 · Setup & Configuration Install Nord Inventory, configure frameworks, permissions, locales, bridges and production packaging. Requirements & Installation Requirements & Installation Production installation, dependency order and first-run checks. Applies to: Nord Inventory v2.0.0 Requirements FiveM/FXServer using a modern artifact compatible with cerulean. oxmysql running before Nord Inventory. A supported framework, or standalone/custom mode. MySQL/MariaDB database access. Recommended start order ensure oxmysql # framework resources here ensure nord_inventory # resources which register into Nord Inventory afterwards If a third-party resource registers items at startup, start it after nord_inventory unless it implements its own retry/readiness logic. Resource naming Do not rename nord_inventory unless you are also prepared to change every external integration that calls exports.nord_inventory. Database Install sql/nord_inventory.sql. Keep database backups before migration. Never let two inventory resources simultaneously own the same player inventory state during a live migration. First boot checklist no SQL migration/query errors; framework detected as intended; locale JSON loads; inventory opens and closes correctly; Admin Studio permission works; one test item survives reconnect; one stash and one vehicle session can be opened; System Health is reviewed before production traffic. Production Resource Structure Production Resource Structure The important folders and what server owners should edit. Applies to: Nord Inventory v2.0.0 Production structure nord_inventory/ ├── config/ # all owner configuration │ ├── core.lua │ ├── commands.lua │ ├── inventory.lua │ ├── bridges.lua │ ├── vehicles.lua │ ├── world.lua │ ├── items.lua │ ├── ui.lua │ ├── stashes.lua │ ├── locales.lua │ └── admin.lua # server-only access settings ├── client/ │ ├── bridge/ # OPEN compatibility layer │ ├── core/ # protected runtime/UI interaction core │ └── modules/ # protected public integration implementation ├── server/ │ ├── bridge/ # OPEN compatibility layer │ │ ├── framework/ │ │ │ ├── core.lua │ │ │ ├── standalone.lua │ │ │ ├── qb.lua │ │ │ ├── qbox.lua │ │ │ ├── esx.lua │ │ │ ├── nord.lua │ │ │ └── custom.lua │ │ ├── permissions.lua │ │ ├── notify.lua │ │ └── textui.lua │ ├── core/ # protected database/registry/inventory engine │ └── modules/ # protected admin/runtime/integration modules ├── shared/ # definitions + protected shared helpers ├── locales/ # owner-editable EN / PT-PT JSON ├── sql/ # installation/reference schema ├── web/ # NUI + item artwork └── docs/ # server/developer documentation Design rules Owner configuration belongs only in config/. Framework-specific server code belongs only in server/bridge/framework/. Notify/TextUI/Target compatibility belongs in bridge files, not in the inventory engine. Database, transaction, registry and provider ownership rules belong in protected core modules. config/admin.lua is server-only and must never move into shared_scripts. Lua files are loaded explicitly in the manifest because configuration and bridge order is intentional. The Nord Lab Recommended Scripts catalog remains in protected server/core/ecosystem.lua. Modular Configuration Modular Configuration All supported owner configuration is split by responsibility under config/. Applies to: Nord Inventory v2.0.0 File Responsibility config/core.lua framework, debug, ecosystem visibility, inventory command/key config/inventory.lua capacities, sessions, ammo, durability/history config/operations.lua Operations/forensics limits, persistent placement, clothing bridge and movement policies config/ui.lua UI, Fast Slots, special slots, hotbar, item feedback config/admin.lua server-only ACE/license/Nord Staff admin access config/commands.lua Admin Studio and administration command aliases config/bridges.lua notify, TextUI, target and interaction mode config/locales.lua active language and fallback config/player_interactions.lua search/rob/hands-up rules config/world.lua ground item/drop/throw behavior config/vehicles.lua registry, trunks, gloveboxes, locks, NPC loot config/items.lua prop rules, back weapons, use animations, aliases config/stashes.lua static stashes config/rarities.lua rarity levels and UI behavior Rule for upgrades Merge your intentional values into the new files. Do not blindly copy an old config/ directory over a newer release. Core Configuration Core Configuration Current config/core.lua defaults. Applies to: Nord Inventory v2.0.0 -- Nord Inventory - core configuration -- Loaded on both client and server. Keep secrets out of this file. Config = Config or {} Config.Framework = 'auto' -- auto | esx | qb | qbox | nord | standalone | custom Config.Debug = false -- Developer ecosystem / Admin Studio extensions. Config.Ecosystem = { Debug = false, -- verbose provider/export resolution logs MaxImageBytes = 2 * 1024 * 1024, -- Nord Lab curated recommendations are read-only. Server owners can only -- choose whether the Recommended Scripts button/catalog is visible in Admin Studio. -- The catalog itself remains inside the protected Asset Escrow server core. ShowRecommendedScripts = true } Config.OpenCommand = 'inventory' Config.OpenKey = 'TAB' Inventory Runtime Configuration Inventory Runtime Configuration Slot/weight limits, session behavior and weapon magazine defaults. Applies to: Nord Inventory v2.0.0 -- Nord Inventory - inventory limits, weapon ammo and runtime rules Config = Config or {} Config.DefaultPlayerSlots = 40 Config.DefaultPlayerWeight = 80000 -- grams Config.DefaultStashSlots = 60 Config.DefaultStashWeight = 150000 Config.TrunkSlots = 50 Config.TrunkWeight = 120000 Config.GloveboxSlots = 10 Config.GloveboxWeight = 15000 -- Weapon magazine handling. Nord keeps ONLY the currently loaded magazine on the -- weapon metadata; reserve ammunition always remains as inventory items until a -- reload transaction removes exactly the rounds that fit in the magazine. Config.WeaponAmmo = { Enabled = true, DefaultMagazineSize = 30, -- used only until a weapon instance has magazineSize metadata MaxMagazineSize = 999, DetectMagazineFromGame = true, -- first equip can seed metadata.magazineSize from GTA's native clip size -- Keep the weapon physically equipped when the magazine reaches 0. -- GTA may try to switch the ped to WEAPON_UNARMED when the last round is -- fired; Nord immediately restores the empty weapon. The weapon is only -- holstered when the player uses/clicks that same inventory item again. KeepEquippedWhenEmpty = true, -- Automatic mode is intentionally slower than pressing R manually. -- First Nord waits before requesting the reload, then it keeps the weapon -- empty for an additional preparation period before the native reload starts. AutoReloadDelay = 1400, -- ms after the magazine reaches zero before automatic reload is requested AutomaticReloadPrepareTime = 900, -- extra ms before the automatic reload animation / rounds enter the weapon ReloadCooldown = 650, -- protects against duplicate reload requests ManualReloadControl = 45, -- INPUT_RELOAD (R) } Config.InventorySessionSeconds = 300 Config.SaveIntervalSeconds = 30 Config.MaxTransferAmount = 100000 Config.MaxContainerDepth = 3 Config.EnableWeight = true Config.EnableVolume = false Config.EnableDurability = true Config.EnableItemHistory = true Config.TransactionLogRetentionDays = 14 Framework Detection & Custom Bridge Framework Detection & Custom Bridge Framework selection and how to handle unsupported/custom cores. Applies to: Nord Inventory v2.0.0 Config.Framework = 'auto' auto lets the bridge inspect known resources. Explicit values are preferable on heavily customized servers because startup intent is unambiguous. Supported values: esx qb qbox nord standalone custom Custom integrations Keep custom framework logic in bridge code instead of modifying inventory authority. A custom bridge should resolve player identity, jobs/groups where required, and any framework-owned money/account behavior while leaving item state to Nord Inventory. Troubleshooting auto detection If more than one framework-like resource is present, set an explicit framework value. Restart nord_inventory after changing framework mode so the runtime initializes against one consistent provider. Admin Access & Roles Admin Access & Roles ACE, server-only license fallback and Nord Staff grants. Applies to: Nord Inventory v2.0.0 -- Nord Inventory - SERVER ONLY admin access configuration -- This file is loaded only through server_scripts. FiveM identifiers in this file are never sent to clients. Config = Config or {} Config.AdminAce = 'nord_inventory.admin' Config.AdminAccess = { -- ACE is checked first. The default matches server.cfg.example: -- add_ace group.admin nord_inventory.admin allow UseAce = true, Ace = Config.AdminAce or 'nord_inventory.admin', -- If ACE does not grant access, allow an exact FiveM identifier from this list. -- Recommended format: license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -- You may also paste only the hash; Nord will automatically prefix "license:". LicenseFallback = true, Licenses = { -- 'license:0123456789abcdef0123456789abcdef01234567', }, -- Automatic Nord Staff access integration. nord_staff detects the public -- HasAdminAccess/GiveAdminAccess/RemoveAdminAccess exports and can grant or -- revoke this role without changing ACE or the static license lists above. NordStaffBridge = { Enabled = true, Role = 'admin', -- developer | admin | owner AllowedResources = { 'nord_staff' } } } -- Optional Admin Studio role separation. -- Legacy `nord_inventory.admin` keeps full day-to-day administration access. Config.AdminRoles = { UseAce = Config.AdminAccess.UseAce ~= false, OwnerAce = 'nord_inventory.owner', AdminAce = Config.AdminAccess.Ace or 'nord_inventory.admin', DeveloperAce = 'nord_inventory.dev', -- License fallback entries may stay as strings (treated as admin) or use: -- { identifier = 'license:...', role = 'owner' } LicenseRoles = { -- { identifier = 'license:012345...', role = 'owner' }, } } Role order developer < admin < owner Owner should be restricted because restore operations can replace persistent inventory state. Admin Commands Admin Commands Current command aliases and access expectations. Applies to: Nord Inventory v2.0.0 -- Nord Inventory - commands configuration -- Command names are shared because the inventory/Admin Studio commands are registered client-side too. Config = Config or {} Config.AdminCommand = 'norditems' -- All commands below require Admin access (ACE first, then the server-only license fallback in config/admin.lua). -- Rename/remove aliases here if they conflict with another resource. Config.AdminCommands = { Enabled = true, GiveItem = { 'giveitem', 'nordgiveitem' }, GiveCash = { 'givecash', 'nordgivecash' }, GiveDirtyMoney = { 'givedirtymoney', 'nordgivedirtymoney' }, RemoveItem = { 'removeitem', 'nordremoveitem' }, RemoveSlot = { 'removeslot', 'nordremoveslot' }, ClearInventory = { 'clearinventory', 'clearinv' }, OpenInventory = { 'openinventory', 'openinv' }, SetMetadata = { 'setmetadata', 'setmeta' }, SetDurability = { 'setdurability', 'repairitem' }, ItemCount = { 'itemcount' }, ItemInfo = { 'iteminfo' }, SaveInventory = { 'saveinventory', 'saveinv' }, ListItems = { 'listitems' } } All configured administration commands are server-authorized. Renaming the command in NUI or client code does not grant access. Notify, Text UI & Target Bridges Notify, Text UI & Target Bridges Independent bridge selection for notifications, world prompts and target interactions. Applies to: Nord Inventory v2.0.0 -- Nord Inventory - bridge and interaction providers Config = Config or {} -- Bridges: one resource name per system. -- Keep each integration independent so changing Notify never affects TextUI/Target. Config.Notify = 'nord_inventory' -- nord_inventory | ox_lib | qb-core | es_extended | resource name | false Config.TextUI = 'nord_inventory' -- nord_inventory | ox_lib | qb-core | es_extended | resource name | false Config.Target = 'auto' -- auto | ox_target | qb-target | nord_target | resource name | false -- World interaction mode only. Provider selection lives above in Config.TextUI / Config.Target. Config.Interaction = { Mode = 'textui', -- textui | target Key = 'E', Control = 38 -- INPUT_CONTEXT (E) } Config.Target = 'auto' checks supported target resources and falls back according to the configured interaction mode. Notify, TextUI and Target are deliberately independent so swapping one provider does not force the others to change. Locales & Translation Locales & Translation PT/EN locale architecture and the rule for adding visible UI strings. Applies to: Nord Inventory v2.0.0 The build ships with: locales/en.json locales/pt.json Selection is controlled in config/locales.lua: Config.Locale = 'pt' Config.LocaleFallback = 'en' Locale data is grouped into notifications, nui, patterns, and server namespaces. The Lua L() helper resolves active language first and fallback second. NUI waits for locale data before rendering localized text. Adding a new visible string Add the English key/value to locales/en.json. Add the matching Portuguese key/value to locales/pt.json. Use the existing translation helper in Lua/NUI instead of hard-coding a visible label. Verify both locales after changing dynamic components such as modals/tabs/search states. This is especially important for the Recommended Scripts modal: tabs are derived from integration values, but visible compatibility labels and UI actions remain locale-aware. Static Stashes Static Stashes Static configuration plus dynamic registration options. Applies to: Nord Inventory v2.0.0 -- Nord Inventory - static stash definitions Config = Config or {} -- Stashes use Config.Interaction (Nord Text UI / ox_lib / target). -- Dynamic stashes can also be registered from other server resources through exports. Config.Stashes = { -- ['police_evidence'] = { -- label = 'Police Evidence', -- coords = vector3(474.6, -996.8, 26.27), -- slots = 100, -- maxWeight = 300000, -- jobs = { police = 0 } -- } } Dynamic stashes should normally use RegisterStash or RegisterInventory from a trusted server resource. Avoid creating storage by writing directly to Nord database tables. Tebex / Asset Escrow Release Tebex / Asset Escrow Release Production packaging and distribution notes. Applies to: Nord Inventory v2.0.0 Tebex / Asset Escrow release This package is structured as the production distribution of Nord Inventory. Resource name Keep the installed resource folder named exactly: nord_inventory Start oxmysql before the inventory: ensure oxmysql ensure nord_inventory What stays open Nord Inventory intentionally keeps only the parts a server owner or integration developer may reasonably need to edit outside Asset Escrow. Owner configuration Everything under config/ stays open: config/ ├── core.lua ├── commands.lua ├── inventory.lua ├── bridges.lua ├── vehicles.lua ├── world.lua ├── items.lua ├── ui.lua ├── stashes.lua ├── locales.lua └── admin.lua There is no root config.lua and no server/config.lua. Compatibility bridges Framework/provider compatibility stays open so a server can adapt Nord Inventory without modifying its protected core: server/bridge/ ├── framework/ │ ├── core.lua │ ├── standalone.lua │ ├── qb.lua │ ├── qbox.lua │ ├── esx.lua │ ├── nord.lua │ └── custom.lua ├── permissions.lua ├── notify.lua └── textui.lua The client bridge layer is open as well: client/bridge/ ├── common.lua ├── notify.lua ├── target.lua └── textui.lua Use server/bridge/framework/custom.lua for unsupported frameworks instead of changing the inventory core. Data intended for owner edits These files also remain open: shared/items.lua shared/weapons.lua shared/vehicles.lua shared/categories.lua locales/en.json locales/pt.json item images under web/images/items/ What stays protected The inventory engine, database/registry implementation, Admin Studio server actions, provider ecosystem implementation, runtime transaction logic and the main NUI source remain protected by Asset Escrow. In particular, do not add the following to escrow_ignore: server/core/ecosystem.lua That file contains the Nord Lab curated Recommended Scripts catalog. Server owners can choose whether the read-only button is visible through Config.Ecosystem.ShowRecommendedScripts, but cannot edit the catalog itself. Framework bridge layout Set the framework in config/core.lua: Config.Framework = 'auto' Supported values: auto qb qbox esx nord standalone custom auto detects Qbox, QB-Core, ESX and Nord Core in that order. If an explicitly configured framework is unavailable, Nord falls back safely to standalone identifiers and logs the reason. Client download footprint Documentation, changelogs and SQL files are included in the Tebex ZIP for server owners, but are deliberately not listed in the manifest files block. Connecting players only download the runtime NUI/locales/item artwork required by the resource. Encryption note A source ZIP is not itself Cfx.re-encrypted. FiveM Asset Escrow protection is applied when Nord Lab publishes the resource through the Cfx.re/Tebex Asset Escrow pipeline. Before publishing, verify that: fxmanifest.lua contains the intended escrow_ignore list. server/core/ecosystem.lua is not ignored. No protected server/core/, server/modules/, client/core/ or client/modules/ file was accidentally added to the ignore list. The resource folder is named nord_inventory. The production checklist passes on a staging FXServer. Asset Escrow Map Asset Escrow Map Which surfaces are intended to stay configurable and which remain protected. Applies to: Nord Inventory v2.0.0 Asset Escrow map Nord Inventory uses a deliberately small open surface for server configuration and compatibility work. Open in production config/** server/bridge/** client/bridge/** shared/items.lua shared/weapons.lua shared/vehicles.lua shared/categories.lua locales/en.json locales/pt.json web/images/items/* These files are listed in escrow_ignore because server owners need to configure providers, frameworks, permissions, reference items, translations and artwork. Protected in production server/core/** server/modules/** client/core/** client/modules/** shared/utils.lua web/index.html web/style.css web/app.js The protected area contains Nord Inventory business logic, transaction rules, database registry behavior, Admin Studio backend, integration ownership implementation and the curated Nord Lab recommendation catalog. Recommended Scripts security server/core/ecosystem.lua must remain protected. The only server-owner control is: Config.Ecosystem.ShowRecommendedScripts = true Setting it to false hides the Recommended Scripts button. It does not expose or alter the Nord Lab catalog. Production Checklist Production Checklist Pre-release checklist for server owners and Nord Lab builds. Applies to: Nord Inventory v2.0.0 Production Checklist Use this checklist before replacing an inventory on a live server. Tebex / Asset Escrow package Confirm the ZIP contains a single resource folder named nord_inventory. Confirm all owner settings are under config/; there must be no root config.lua or server/config.lua. Confirm server/bridge/ and client/bridge/ are listed in escrow_ignore as intended. Confirm server/core/ecosystem.lua is not in escrow_ignore. Confirm protected server/core/, server/modules/, client/core/ and client/modules/ files were not accidentally exposed. Confirm docs/SQL/changelog are not listed in the manifest files block, so clients do not download release documentation. Publish through Cfx.re/Tebex Asset Escrow before calling the distributed build encrypted/protected. Files and dependencies Keep a copy of the currently deployed inventory resource and database. Start oxmysql before nord_inventory. Start any target/notification/TextUI providers in the order required by your configuration. Start nord_inventory before resources that call its registration exports. Confirm fxmanifest.lua and all listed files are present. Database Let Nord create its tables automatically on a staging database, or import sql/nord_inventory.sql manually. Confirm nord_inventory_custom_items, nord_inventory_disabled_reference_items, audit and backup tables exist. Create an Admin Studio backup before a migration/import. Keep a full database backup outside Nord before the first production deployment. Permissions Verify Developer/Admin/Owner ACE roles with test accounts. Confirm Developer cannot save/delete/import/restore through direct NUI/server event attempts. Confirm backup restore is restricted to Owner unless you intentionally change the permission bridge. If Config.AdminAccess.UseAce = false, verify only configured license fallback entries receive access. Item registry Open System Health and resolve errors before launch. Review missing images and invalid/offline exports. Verify reference-item disable/restore behavior. Verify a DB-authoritative definition cannot be overwritten by RegisterItem. Verify runtime provider items disappear when their provider stops and re-register when it starts. External integrations For each native integration: Confirm the provider appears on Integrations. Confirm dependencies are online. Confirm item/provider ownership is what you expect. Test client and server external use handlers separately. Test return false and stopped-resource failure paths. Test item actions and metadata schema extensions. Stop/restart the provider and confirm cleanup/re-registration. Player inventory Add/remove/transfer/split/give/drop items. Open Ground, stash, trunk, glovebox and item containers. Test overweight and slot-limit rejection. Test reconnect persistence. Test two players interacting with the same secondary inventory. Lifecycle Test normal durability loss. Test durability repair items with missing, full and damaged targets. Test GetDurability, SetDurability, AddDurability, RemoveDurability and RepairItem from a trusted test resource. Test expiration on online and offline-loaded items. Weapons Equip/unequip weapons. Verify serial/durability/ammo metadata. Verify manual and automatic magazine reload modes. Verify reserve ammunition remains inventory-authoritative. Vehicles Test trunk and glovebox capacities by model/category. Test addon front/rear trunk placement. Test vehicles with no trunk. Test locked/unlocked/NPC vehicle behavior according to config. Admin Studio Create/edit/delete/restore a database and reference item. Run an import preview before committing. Test templates. Create a backup, make a harmless change, restore it, then verify registry reload. Confirm audit records the administrative changes. Static validation included with this package The packaged build should pass: Lua compile/syntax validation for all .lua files. JavaScript syntax validation for web/app.js. JSON parsing and EN/PT locale-key parity. duplicate HTML-ID check. NUI callback and Nord client/server event mapping checks. Static validation cannot reproduce a real FXServer, framework, OneSync, database driver, target provider or third-party resource. Run the checklist on a staging FXServer before swapping a live production server. v2.0.0 Operations smoke test Confirm nord_inventory_snapshots, nord_inventory_forensics_alerts and nord_inventory_placed_items exist. Open all Operations tabs and confirm Ledger/Instance filters remain usable on your Admin Studio resolution. Run Anti-Dupe once; verify it records diagnostics but does not delete items. Create and delete a manual snapshot. Restore a disposable test snapshot and verify a pre-restore snapshot is created. Edit an online player's inventory and confirm the live client refreshes immediately. Test a simulated persistence failure on staging if possible; runtime state should roll back rather than diverge from SQL. Place a disposable persistent world item, restart the resource/server and verify it returns. Configure one test movement policy and verify server-side rejection for the blocked destination/action. Verify Recommended Scripts shows Nord Lab/Renovax Store and Documentation buttons and that only http/https URLs open. Player Experience Overview · Player Experience 2 · Player Experience Player inventory behavior, quick slots, lifecycle, item visuals, world drops and player-to-player interactions. Inventory UI & Dual Inventory Inventory UI & Dual Inventory Player inventory behavior and the left/right storage model. Applies to: Nord Inventory v2.0.0 Nord uses a dual-inventory layout: the player inventory remains on the left, while the active stash/container/vehicle/ground/player inventory is shown on the right. Server sessions determine what the right-hand inventory represents and when that session must close. Key properties slot-based item instances; weight authority on the server; per-instance metadata; Fast Slots and dedicated special slots; drag/drop and context actions; live item feedback without requiring the full inventory to be open; storage session invalidation when access conditions change. The default player capacity is 40 slots / 80,000 g. Fast Slots, Hotbar & Special Slots Fast Slots, Hotbar & Special Slots Default slots 1–7 and quick-use behavior. Applies to: Nord Inventory v2.0.0 Special Slots & Quick Actions Nord Inventory reserves two dedicated real player inventory slots after the Fast Slots. Default slots Config.UI.specialSlots = { enabled = true, slots = { { key = 'keys', slot = 6, category = 'key', label = 'Keys', icon = 'fa-key' }, { key = 'technology', slot = 7, category = 'technology', label = 'Technology', icon = 'fa-microchip' } } } With the normal 5 Fast Slots: slots 1–5 = Fast Slots; slot 6 = Keys; slot 7 = Technology; normal inventory grid begins at slot 8. The server validates the item category before every move. Client-side validation is only visual feedback. Existing inventories When an older player inventory already has an incompatible item in slot 6 or 7, Nord Inventory relocates it to the first free normal slot on load. If the inventory is completely full, the item is never deleted: it remains visible in the special slot with a warning until the player moves it out. Amount control The bottom Amount field controls drag quantity. Example: stack contains 10; Amount = 3; drag the stack to another empty slot; server moves 3 and leaves 7 in the original slot. This works for same-inventory splitting and cross-inventory transfers. Use Select a player item and press Use. Containers open normally; usable items call the standard server-authoritative use flow. Give Select a player item and press Give. The configured amount is given. If several players are within 3 meters, a compact player chooser is shown. Unified bottom dock Fast Slots, Special Slots, Amount, Use and Give share the same bottom row. Personal Studio > Layout now controls the bottom player tools with: Fast Slots width; Player tools size; Fast / tools spacing. The new tools also inherit the player's slot opacity, border opacity, corner radius, item image size, accent and icon color settings. Personal Studio · Player Tools The complete right-side bottom group is configurable from a dedicated Player Tools page in Personal Studio. Per-player settings include: overall Player Tools size; Special Slot size; Amount control size; Use / Give button size; spacing between Fast Slots and Player Tools; Special Slot label visibility; helper-text visibility. Appearance and Layout settings still provide the shared slot opacity, border visibility, corner radius, accent, item-image scale and icon color. Drag directly to Use / Give Use and Give are real drag targets. Drag a player-inventory item onto Use to execute the standard use flow. Drag a player-inventory item onto Give to open/execute the nearby-player flow. Give respects the Amount control. Items dragged from a secondary inventory must first be moved into the player inventory. Pinned Fast Slot items cannot be given until unpinned. Quantity zero means all The Player Tools Amount input accepts 0. 0 = the complete current stack; 1+ = exactly that quantity, clamped to the available stack; dragging with 0 moves the full stack; dragging with a smaller value splits the stack; Give uses the same rule, so 0 gives the complete selected stack. The NUI always resolves 0 to a positive server-side amount before sending the action, so the inventory core does not need unsafe zero-amount transfers. -- Nord Inventory - player UI, hotbar and received-item feedback Config = Config or {} Config.UI = { theme = 'dark', columns = 7, slotSize = 'medium', showWeight = true, animations = true, -- Slots 1-5 are reserved for the normal Fast Slots. hotbarSlots = 5, hotbarKeybinds = true, -- Dedicated player slots shown in the bottom action dock. -- They are REAL inventory slots and are validated server-side by category. -- With the default 5 Fast Slots these reserve slots 6 and 7. specialSlots = { enabled = true, slots = { { key = 'keys', slot = 6, category = 'key', label = 'Keys', icon = 'fa-key' }, { key = 'technology', slot = 7, category = 'technology', label = 'Technology', icon = 'fa-microchip' } } } } -- Standalone quick hotbar. This is independent from the full inventory NUI and -- never takes mouse/keyboard focus, so the player can keep moving normally. Config.Hotbar = { Enabled = true, Command = 'hotbar', OpenKey = 'Z', Mode = 'timed', -- timed | toggle Duration = 3200, -- milliseconds when Mode = timed ShowOnSlotUse = false -- automatic use feedback uses compact item cards, not the full hotbar; pressing 1-5 also reveals the hotbar } -- Compact OX-style item feedback. Multiple different item cards can be shown -- at the same time, so reward/crafting bursts no longer wait in a long queue. -- Repeated feedback for the same item is merged into the visible card. Config.ItemNotifications = { Enabled = true, Receive = true, Duration = 1800, -- milliseconds each visible card remains on screen MaxVisible = 8 -- safety cap for simultaneous cards; oldest is replaced first } Player Shortcuts Player Shortcuts Default keyboard shortcuts and commands. Applies to: Nord Inventory v2.0.0 Player shortcuts Hover + E quick transfer With two inventories open, place the mouse directly over an item and press E. Player item → open ground/trunk/glovebox/stash/container. Item in the open secondary inventory → player inventory. The complete stack is transferred. A matching stack is preferred; otherwise the first valid free slot is used. Fast/Special player slots are never chosen automatically. Pinned items and search/rob restrictions keep their normal protection. The shortcut does nothing when the mouse is not over an item. Inventory open / close TAB: opens the player inventory when closed and closes it when open. ESC: closes the player inventory immediately. The TAB close is handled inside the NUI because, while the inventory has keyboard focus, the browser receives the key instead of FiveM's normal key mapping. Received Item Feedback Received Item Feedback Compact item notifications for rewards, crafting and received items. Applies to: Nord Inventory v2.0.0 Current defaults: Config.ItemNotifications = { Enabled = true, Receive = true, Duration = 1800, MaxVisible = 8 } Different item notifications can be visible simultaneously. Repeated feedback for the same item is merged into the visible card. MaxVisible caps concurrent cards and the oldest is replaced first when the cap is reached. Ground Items, Pickup & Throw Ground Items, Pickup & Throw Server-synchronized ground drops and safe throw limits. Applies to: Nord Inventory v2.0.0 Ground behavior is configured in config/world.lua and is server-authoritative. The current build uses a default cardboard-box fallback prop and category/definition-aware visual models where available. Core defaults include: open distance: 3.0 m; draw distance: 15.0 m; prop distance: 35.0 m; lifetime: 1800 seconds; ground inventory: 30 slots / 250,000 g; maximum throw distance: 8.0 m; maximum throw height difference: 4.0 m. The server validates actual inventory removal and resulting ground state. Client-side throw presentation is not treated as authoritative. Container Items & Backpacks Container Items & Backpacks Items that own their own nested inventory. Applies to: Nord Inventory v2.0.0 An item definition may expose a container inventory. Container state is tied to an item instance and opened through the server API. local ok, result = exports.nord_inventory:OpenItemContainer(source, slot) Use GetContainerInventory(target, slot) when a trusted server integration needs to inspect container storage. Config.MaxContainerDepth = 3 prevents unbounded nesting. Integrations should never attempt to bypass the configured depth by directly constructing database identifiers. Metadata, Durability & Expiration Metadata, Durability & Expiration Per-instance data, lifecycle state and presentation. Applies to: Nord Inventory v2.0.0 Every item instance can carry arbitrary metadata. Common Nord-managed fields may include durability/lifecycle data, weapon magazine state, container identity, rarity override, custom label/image presentation, and integration-specific values. Use SetMetadata, UpdateMetadata and GetMetadata from trusted server code. Never trust a metadata payload sent directly by a browser/NUI or arbitrary client event. Config.EnableDurability = true by default. Item history is also enabled in the current build. Metadata Privacy & Hidden Fields Metadata Privacy & Hidden Fields How integrations can store internal identifiers without exposing them in item details. Applies to: Nord Inventory v2.0.0 Metadata may be required for identity while still being inappropriate to show in the player item details UI. Item definitions can suppress detailed metadata presentation while retaining server-side metadata. The included phone-style reference item demonstrates this pattern with hideMetadataDetails = true and persistent metadata defaults. Use this for device IDs, internal ownership references, signed values, provider state or other technical fields which should remain available to scripts but not clutter player UI. Durability Repair Items Durability Repair Items Internal repair consumables and the public durability API. Applies to: Nord Inventory v2.0.0 Durability repair items Nord Inventory can create internal usable items that restore durability on a specific target item without relying on another script. Admin Studio In Behavior → Use behavior, keep the handler on Internal (Nord) and set: Item effect: Restore durability Target item: choose an item that has durability enabled Restore amount: percentage points restored per successful use Remove on use: enable it if the repair item should be consumed Nord only consumes the repair item when durability was actually restored. Lua definition ['weapon_cleaning_kit'] = { label = 'Weapon Cleaning Kit', weight = 250, stack = true, close = true, use = { duration = 3500, actionText = 'Repairing with {item}', remove = 1, repair = { item = 'weapon_pistol', amount = 25 } } } Server-authoritative behavior When the repair item is used successfully, Nord Inventory: validates that the configured target definition exists and uses durability; searches the player's inventory for matching target instances; selects the most damaged matching instance; restores the configured amount without exceeding the target maximum; consumes the repair item only after a real repair is applied; updates inventory watchers immediately. The same effect works with weapons and normal items because both use the standard metadata.durability state. Safe failure cases The use is rejected without consuming the repair item when: the player does not have the configured target item; the target definition does not use durability; every matching target is already at maximum durability; the repair configuration is invalid. If several copies of the target exist, the most damaged copy is repaired first. Runtime registration example External resources can register repair items through the normal runtime API: exports.nord_inventory:RegisterItem('pistol_cleaning_kit', { label = 'Pistol Cleaning Kit', weight = 200, stack = true, close = true, use = { duration = 3000, remove = 1, repair = { item = 'weapon_pistol', amount = 30 } } }) The repair itself remains server-authoritative inside Nord Inventory. Rarity System & Slot Presentation Rarity System & Slot Presentation Opt-in rarity, metadata override and current levels. Applies to: Nord Inventory v2.0.0 Item Rarities Nord Inventory includes an opt-in rarity presentation system for item definitions and individual item instances. Important: rarity is disabled by default An item only has rarity when its definition explicitly contains a valid rarity value, or when an individual instance provides metadata.rarity and metadata overrides are enabled. This item has no rarity: ['water'] = { label = 'Water', weight = 500 } This item has rarity enabled: ['special_key'] = { label = 'Special Key', weight = 5, rarity = 'rare' } Config.Rarities.Default is only the level selected when rarity is enabled in Admin Studio. It is not automatically applied to all items. Slot presentation When rarity is enabled on an item: The slot border and subtle inner tint use the rarity color. A compact rarity icon appears in the slot corner. The rarity name is not shown on the slot. Hotbar and item feedback use the same icon/color identity. The Item Information modal can still show the readable rarity label. Creating rarity levels, icons and colors Edit config/rarities.lua: Config.Rarities.Levels = { rare = { label = 'Rare', color = '#4f8cff', icon = 'fa-gem', order = 3 }, mythic = { label = 'Mythic', color = '#ff4fd8', icon = 'fa-star', order = 6 } } icon uses a Font Awesome Free Solid icon class. Examples: fa-circle fa-leaf fa-gem fa-star fa-crown fa-diamond fa-wand-magic-sparkles New configured levels automatically appear in Admin Studio → Item Management → Rarity. Admin Studio Rarity now has its own page in the item editor. The page contains: An explicit Enable rarity toggle. A live slot preview. Rarity level cards showing each configured icon and color. The current color and level information. New items start with rarity disabled. Runtime registration exports.nord_inventory:RegisterItem('special_key', { label = 'Special Key', weight = 5, rarity = 'legendary' }) To register an item without rarity, simply omit the field. Instance rarity override When Config.Rarities.AllowMetadataOverride = true, a specific item instance may provide its own rarity: exports.nord_inventory:AddItem(source, 'special_key', 1, { rarity = 'legendary' }) This lets one physical instance have a rarity identity without requiring another item definition. Rarity remains presentation-first Rarity does not automatically change: damage weight price durability drop chance crafting output Other resources may read the rarity value and build gameplay rules on top of it if desired. Slot background behavior When rarity is enabled on an item, the slot background itself uses the configured rarity color. Rarity does not control: durability bar color; validity/expiry bar color; interaction/selected border color; item label color; item image. Those remain controlled by the player's normal inventory customization. The implementation intentionally avoids CSS color-mix() for the slot background so the result remains reliable in FiveM CEF builds. Slot opacity integration When a rarity is enabled on an item, the slot uses the same transparency/opacity system as the player inventory editor. This means: the rarity changes only the slot color; the slot still respects the player's configured slotOpacity; the border still uses the player's normal border/interation styling; the durability bar keeps using the player's lifecycle colors. In practice, the normal slot background: rgb(8 8 13 / var(--user-slot-opacity)) is replaced by the rarity color equivalent: rgb(R G B / var(--user-slot-opacity)) So the opacity behavior remains the same and only the base color comes from the rarity definition. Slot opacity behavior with rarity The rarity slot background keeps its rarity color/tint, but all of its background layers now obey the same player Slot opacity slider used by normal slots. This means: lowering Slot opacity also lowers the visibility of rarity backgrounds; raising Slot opacity makes rarity backgrounds stronger; the rarity color remains visible; the durability bar remains independent. Current configured levels common uncommon rare epic legendary Item Props & Use Animations Item Props & Use Animations Definition-driven held props and safe fallbacks. Applies to: Nord Inventory v2.0.0 config/items.lua controls generic/category/keyword prop fallback plus model-specific hand offsets. Normal tools/objects can use the Pocket transition and weapons use a dedicated draw/holster transition. Ammo and magazine items are intentionally excluded from generic held-prop fallback because their primary visual feedback is the weapon reload itself. Integrations should define item-specific presentation where accuracy matters, and rely on fallback only for generic items. Large Weapons on the Back Large Weapons on the Back Cosmetic long-weapon display for unequipped inventory weapons. Applies to: Nord Inventory v2.0.0 Current defaults: Config.BackWeapons = { Enabled = true, MaxVisible = 2, HideInVehicle = true, HideWhenDead = true, RefreshInterval = 750 } This is presentation only. Weapon ownership, ammunition and durability remain server-authoritative inventory data. Two default back attachment slots use opposite diagonals to reduce model overlap. Item Context Actions Item Context Actions Built-in and provider-registered actions available from an item. Applies to: Nord Inventory v2.0.0 Right-click/context actions are assembled from built-in inventory behavior plus registered provider actions. External resources can add controlled actions with RegisterItemAction and remove them with UnregisterItemAction. Action visibility should never be treated as permission. The server resource handling the action must still validate player/item state before mutation. Personal Studio Personal Studio Player-facing preferences without changing server-wide authority. Applies to: Nord Inventory v2.0.0 Personal Studio is for player presentation/preferences, not administrative item definitions. It can manage user-level presentation choices such as reload behavior or UI preferences while preserving server policy. Preferences are persisted separately from inventory item definitions in the nord_inventory_preferences table. Player Search & Robbery Player Search & Robbery Server-authoritative player-to-player viewing and one-way transfer. Applies to: Nord Inventory v2.0.0 Player Search & Robbery Nord Inventory can expose Search player and Rob player interactions when the target player is surrendering with their hands up. Security model The target option is only a client-side convenience. The server revalidates: target server ID; distance between both players; the target's replicated hands-up state; the mode ( search or rob); every inventory transfer while the session is open. The session closes automatically if the target lowers their hands, disconnects, or moves outside the configured distance. Search Search is read-only. The searching player can inspect the target inventory, including items stored in Fast Slots and Special Slots, but cannot move items from/to the target inventory. Rob Robbery is one-way: victim inventory -> robber inventory The robber can never use the session to put/swap their own items into the victim inventory. Pinned Fast Slot items are not protected from a valid robbery. If stolen, the victim's pin marker is removed before the item enters the robber inventory. Configuration Edit: config/player_interactions.lua Main options: Config.PlayerRobbery = { Enabled = true, Distance = 2.5, SearchEnabled = true, RobEnabled = true, RequireHandsUp = true } Hands-up detection Nord automatically detects common hands-up animation dictionaries and publishes: nord_inventory:handsup as a replicated player state. If your hands-up resource uses a custom animation, add it to Animations. If it already publishes a player state, add the key to ExternalStateKeys. An external client resource can also explicitly tell Nord: exports['nord_inventory']:SetHandsUpState(true) Return to automatic detection: exports['nord_inventory']:SetHandsUpState('auto') Check the local state: local handsUp = exports['nord_inventory']:IsHandsUp() Target providers When the inventory interaction mode uses Target, Nord registers global-player options for ox_target / qb-target / compatible providers. When Target is not active, the TextUI fallback uses: E -> Search G -> Rob The controls and labels are configurable. Server exports Trusted server resources can request the same validated flow: exports['nord_inventory']:OpenPlayerSearch(source, target) exports['nord_inventory']:OpenPlayerRobbery(source, target) exports['nord_inventory']:IsPlayerSurrendered(target) Reliable interaction mode Player Search/Rob now has its own interaction selector and does not depend on Config.Interaction.Mode: Config.PlayerRobbery.Interaction = 'auto' auto: use ox_target/qb-target when available, otherwise TextUI; target: target only; textui: TextUI only. This prevents a world-interaction setting from silently disabling player robbery. Built-in hands up The system now works without a separate surrender resource: X -> toggle hands up /handsup -> toggle hands up Configure or disable it in Config.PlayerRobbery.BuiltInHandsUp. Remote Search/Rob options only appear after the target's replicated hands-up state is visible. This ensures the server and the robber agree on the surrender state before the interaction can be selected. Server-synchronized surrender state Hands-up detection is performed on the surrendering player's own client and sent to the server. The server then broadcasts a compact surrender cache to all clients. Target/TextUI checks use that server-synchronized cache. This avoids differences between FiveM artifacts in how remote Player state bags and ped Entity state bags are exposed. A joining/restarting client requests a full snapshot automatically. Hands-Up Integration Hands-Up Integration Built-in surrender state plus compatibility with external hands-up resources. Applies to: Nord Inventory v2.0.0 Current player-interaction defaults include built-in hands-up support: Command: /handsup Key: X State key: nord_inventory:handsup External systems can synchronize through: exports.nord_inventory:SetHandsUpState(true) local surrendered = exports.nord_inventory:IsHandsUp() On the server: local surrendered = exports.nord_inventory:IsPlayerSurrendered(target) Search can be read-only while robbery is one-way from victim to robber. The server revalidates distance, target identity, surrender state and transfer constraints. Equipment Slots 2.0 Equipment Slots 2.0 Applies to: Nord Inventory v2.0.0 Special/equipment slots remain real player inventory slots and are validated server-side. Existing category matching still works, and v2.0.0 adds explicit item allowlists. { key = 'phone', slot = 8, items = { 'phone', 'nord_phone' }, label = 'Phone', icon = 'fa-mobile-screen' } A slot may use category = 'technology' or items = { ... } depending on how strict the equipment rule should be. Additional equipment slots are intentionally opt-in: v2.0.0 does not reserve more slots automatically on an upgraded server. If you add slots 8+ to Config.UI.specialSlots.slots, account for them when choosing total player slot count and when migrating old inventories. Incompatible legacy items are relocated to a normal free slot when possible and are never intentionally deleted simply because a special-slot rule changed. Admin Studio & Item Management Overview · Admin Studio & Item Management 3 · Admin Studio & Item Management Manage definitions, roles, imports, providers, health, backups, vehicles and the curated ecosystem catalog. v2.0.0 extends Admin Studio with the Operations Center and aligned Integrations actions. Admin Studio Overview Admin Studio Overview Server-authoritative administration for items, providers, diagnostics and vehicles. Applies to: Nord Inventory v2.0.0 Admin Studio System Admin Studio is server-authoritative. Hiding a button in NUI is only UX; every mutation is checked again on the server. Roles Default ACE objects: add_ace group.dev nord_inventory.dev allow add_ace group.admin nord_inventory.admin allow add_ace group.owner nord_inventory.owner allow Default capability levels: Developer: view Admin Studio, integrations, health diagnostics and item testing. Admin: Developer access plus item/category management, imports, vehicle storage, backup creation/deletion and audit log. Owner: Admin access plus backup restore. The exact ACE names and optional license-based roles are configured in the server-only config/admin.lua. Integrations page Shows resources that register through Nord APIs, including: provider resource and display name online/offline state provider version/author when supplied items associated with the provider custom action and image counts dependency state registration failures/conflicts The Recommended Scripts catalog opens in a read-only modal from the Integrations page. It is maintained only by Nord Lab developers in protected server source; no Admin Studio role, command, event or public export can edit its contents. Server owners can only hide/show the read-only button with Config.Ecosystem.ShowRecommendedScripts in config/core.lua. Recommendations are curated by Nord Lab. Server owners, administrators and developers can never add, edit or remove catalog entries. The only public option is visibility: Config.Ecosystem.ShowRecommendedScripts = true/false in config/core.lua. The catalog data lives in the protected server core and is updated by Nord Lab as part of inventory releases. System Health Health Check reports problems such as: item image missing from web/images/items unknown category durability item not unique/non-stackable malformed external export export/provider/dependency offline runtime item without a tracked provider provider registration conflict orphan item action invalid/offline action export orphan/offline metadata schema provider The report is diagnostic only; it does not silently rewrite definitions. Backups and restore A backup contains Nord-managed configuration: database-authoritative custom item definitions disabled reference-item markers custom categories vehicle storage categories vehicle model overrides Before restore, Nord automatically creates a pre-restore safety backup. Runtime items supplied by external resources are not persisted as authoritative database definitions; active providers are reapplied after the registry reload. Restore is Owner-only by default. Audit log The server records administrative changes such as item/category/vehicle mutations, imports and backup operations. Audit data is only sent to roles with the audit permission. Migration Center The import UI supports: ox_inventory QB/QBCore ESX Quasar CodeM Nord JSON Files are read by the NUI as text/data; imported Lua is not executed by Nord. Always review the conversion preview and warnings before applying a large migration. Database-authoritative conflicts can be skipped or explicitly overwritten when the user's role allows imports. Reference/source items remain protected from direct source-file rewriting. Item Templates Admin Studio includes templates for common definitions such as food, drink, medical, reusable tool, document, container, durability repair item and external usable item. Templates are starting points only; review the resulting definition before production use. Testing Mode Authorized developers/admins can select an item and exercise controlled testing flows from System Health. Testing uses the real server-authoritative inventory path, so it is suitable for verifying use handlers, metadata and durability behavior before rollout. Source-aware item management Nord distinguishes the source of each item: Reference ( shared/items.lua / shared/weapons.lua): deleting from Admin Studio disables the reference instead of rewriting the Lua file. Reference + DB override: delete removes the database override and leaves the reference disabled. Database-only: delete removes the custom database row. Runtime provider item: protected from Admin Studio deletion; its provider owns unregister/cleanup. Restoring a disabled reference returns to the original Lua definition. Permission Matrix Permission Matrix Exact role hierarchy used by the v2.0.0 server permission bridge. Applies to: Nord Inventory v2.0.0 Roles are ordered: developer < admin < owner Capability Minimum role View Admin Studio developer Integrations/provider registry developer System health developer Test items developer Manage/create/edit items admin Delete/disable items admin Import/migrate items admin Manage vehicle registry admin Create backups admin Audit log admin Operations / Forensics admin Inventory Manager / offline_inventory admin Create/delete snapshots admin Restore snapshots admin Restore full Admin Studio backups owner The permission keys added for v2.0.0 are forensics, offline_inventory and restore_snapshots. The older offline_inventory name is intentionally retained for backwards compatibility even though the manager now handles both online and offline players. Runtime Nord Staff grants are persisted without rewriting ACE or static license lists. Item Registry & Categories Item Registry & Categories Built-in categories and the provider-aware item registry. Applies to: Nord Inventory v2.0.0 Built-in categories in the current shared registry include: generic food drink medical weapon ammo tool document evidence container clothing key technology Categories can also be registered at runtime by trusted providers. Provider ownership is tracked so one resource cannot silently masquerade as another provider when using the public SDK. Creating & Editing Items Creating & Editing Items Core item fields and DB-authoritative editing workflow. Applies to: Nord Inventory v2.0.0 Admin Studio supports quick creation and detailed editing. Depending on the item, common fields include: canonical item name and label; category; weight/stack/close behavior; image and presentation properties; internal/external use behavior; metadata defaults/schema/display rules; durability and expiration/lifecycle behavior; container settings; rarity; provider ownership/source state. After a DB-backed admin edit, the database definition is intended to remain authoritative across restarts instead of being overwritten by a runtime registration using the same canonical name. Internal & External Use Behavior Internal & External Use Behavior Choose one clear authority for item use. Applies to: Nord Inventory v2.0.0 External item use exports Nord Inventory has two mutually exclusive usable-item modes: internal: Nord handles duration, animation, hand prop, player effects and optional removal. export: Nord validates the item/slot transaction and delegates the gameplay action to another resource export. The Admin Studio exposes this under Item Management → Behavior → Use handler with Internal (Nord) and External export. OX-style item definition A resource can register an item and point its use directly at one of its own exports. When the export name is bare, Nord automatically binds it to the resource calling RegisterItem. exports.nord_inventory:RegisterItem('scanner', { label = 'Scanner', weight = 250, client = { export = 'UseScanner', -- automatically :UseScanner remove = 0 } }) exports('UseScanner', function(item, slot) -- item.name, item.label, item.metadata, item.count, item.slot, ... -- Return false to cancel the transaction. return true end) The full resource name is still accepted: client = { export = 'my_scanner:UseScanner', remove = 0 } -- or client = { export = 'my_scanner.UseScanner', remove = 0 } Server export exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, close = true, server = { export = 'UseRepairKit', remove = 1 } }) exports('UseRepairKit', function(source, item, slot, definition) -- Return false to cancel and prevent Nord from removing the item. return true end) The Nord-native descriptor is also supported: exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, use = { mode = 'export', export = 'my_mechanic:UseRepairKit', side = 'server', remove = 1 } }) mode = 'export' may be omitted when use.export is present. Register an external handler for an existing item Compact form, bound to the calling resource: exports.nord_inventory:RegisterUseExport('repair_kit', 'UseRepairKit', 'server') Explicit resource form: exports.nord_inventory:RegisterUseExport('repair_kit', 'my_mechanic', 'UseRepairKit', 'server') Descriptor/string forms through RegisterUsableItem are also accepted: exports.nord_inventory:RegisterUsableItem('repair_kit', 'UseRepairKit', 'server') exports.nord_inventory:RegisterUsableItem('repair_kit', 'my_mechanic:UseRepairKit', 'server') exports.nord_inventory:RegisterUsableItem('scanner', { export = 'UseScanner', side = 'client' }) A normal server Lua callback remains supported: exports.nord_inventory:RegisterUsableItem('repair_kit', function(source, item, definition, slot) return true end) Register the item and handler in one call The third RegisterItem argument can be a function, export string or export descriptor. The optional fourth argument selects server or client for string handlers. exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, use = { remove = 1 } }, 'UseRepairKit', 'server') Bulk registration RegisterItems registers multiple runtime items from one resource and applies the same caller-resource binding rules. local ok, result = exports.nord_inventory:RegisterItems({ scanner = { label = 'Scanner', weight = 250, client = { export = 'UseScanner', remove = 0 } }, repair_kit = { label = 'Repair Kit', weight = 500, server = { export = 'UseRepairKit', remove = 1 } } }) Transaction behavior Nord validates that the player still owns the same item/slot before the external action is committed. If an export is unavailable, errors, or returns false, the use is cancelled and Nord does not remove the item. remove stays server-authoritative: remove = 0: keep the item. remove = 1: remove one item after a successful external action. Higher values remove that amount, limited by the current stack. External mode is exclusive: Nord does not also run its internal duration, animation, hand prop, hunger, thirst, health or armor effects. The external resource owns those effects. Hands-only animations ( prop = false) An internal usable item can explicitly disable every hand-prop fallback while keeping its animation. use = { duration = 2500, animation = { dict = 'missheistdockssetup1clipboard@idle_a', clip = 'idle_a', flag = 49 }, prop = false } prop = false is authoritative for the use action. Nord Inventory will not fall back to: worldModel; keyword prop rules; category prop rules; the generic fallback prop. The item's worldModel can still be kept for ground/drop presentation. The default bandage uses this mode so the player performs a hands-only bandaging animation with no object attached. Lifecycle Editor Lifecycle Editor Durability, shelf life and repair behavior in item definitions. Applies to: Nord Inventory v2.0.0 Lifecycle settings are definition-level defaults applied to item instances where enabled. Use the lifecycle editor instead of custom client-side timers when the state must persist. Public durability exports are documented in the Developer API chapter. Integrations should modify lifecycle state through those exports rather than editing raw metadata/storage rows. Metadata Editor Metadata Editor Structured metadata defaults, display rules and provider schemas. Applies to: Nord Inventory v2.0.0 Metadata can be free-form, but the SDK also supports RegisterMetadataSchema so an integration can describe expected fields and display behavior. Schemas improve consistency without giving the browser authority over values. Use hidden metadata display for technical identifiers that scripts need but players do not. Rarity Editor Rarity Editor Opt-in rarity configuration in Admin Studio. Applies to: Nord Inventory v2.0.0 Rarity is not forced onto every item. An item can opt into a configured level and an individual instance can override the base level through metadata when AllowMetadataOverride = true. Current levels: Common, Uncommon, Rare, Epic and Legendary. Imports & Migration Center Imports & Migration Center Preview-first item-definition migrations and compatibility imports. Applies to: Nord Inventory v2.0.0 The migration workspace is for item definitions, not a blind database replacement. Preview mappings first, resolve name/category/image/use differences, and keep canonical Nord names stable after import. For live servers, migrate player item state only after testing a complete mapping in staging and taking a database backup. DB-Authoritative Definitions & Precedence DB-Authoritative Definitions & Precedence Why Admin Studio edits survive runtime registration and restart. Applies to: Nord Inventory v2.0.0 Database item persistence Item-definition precedence is strict and restart-safe: If nord_inventory_custom_items contains a row for an item name, that row owns the definition. shared/items.lua / shared/weapons.lua are consulted only if no database row exists for that name. Resource startup is read-only for item definitions. It never seeds, updates, replaces, or deletes DB item rows. A disabled DB row remains authoritative and blocks file fallback. The only way to restore the reference definition is an explicit Revert action, which deletes the DB override row. This prevents edited base items from returning to file defaults after restart nord_inventory. Item definition precedence Nord Inventory uses one deterministic rule: Database row exists for the item name → the database definition is authoritative. No database row exists → shared/items.lua / shared/weapons.lua is used as reference fallback. Editing a reference/base item from Admin Studio creates or updates its database row. The reference file is never mutated. Reverting a base override removes the database row; only then does the reference definition become active again. This prevents a base item from being simultaneously resolved from the file and the database. Restart behaviour Resource/server startup is read-only for item definitions. Existing rows in nord_inventory_custom_items are never replaced, disabled, deleted, or reseeded from the Lua reference files during boot. Disabled DB rows still own their names and block reference fallback. Delete, Disable & Restore Items Delete, Disable & Restore Items Source-aware item removal without losing track of reference/runtime ownership. Applies to: Nord Inventory v2.0.0 Nord separates built-in/reference definitions, database definitions and provider/runtime definitions. Deletion behavior is source-aware so an admin can disable a reference item, remove a database override or unregister a provider definition without pretending all sources are identical. Disabled reference entries are persisted in nord_inventory_disabled_reference_items. Historical versions are stored in nord_inventory_item_versions where applicable. Vehicle Registry Vehicle Registry Vehicle model/category capacity management in Admin Studio. Applies to: Nord Inventory v2.0.0 The vehicle workspace can combine framework vehicle data with GTA model scanning and Nord overrides. Capacity is resolved from model/category/default rules rather than hard-coded only by plate. Config.VehicleRegistry.AutoImportFramework = true and ScanGameVehicles = true in the current build. Use model-specific overrides only when category defaults are insufficient. Integrations & Provider Registry Integrations & Provider Registry Runtime provider ownership, health and registration visibility. Applies to: Nord Inventory v2.0.0 The Provider Registry shows resources that register items, categories, actions, schemas or images through the developer SDK. Provider ownership is useful for diagnostics: server owners can see where a runtime item came from instead of guessing which resource injected it. Use GetProviderRegistry() and GetIntegrationInfo() for trusted programmatic diagnostics. v2.0.0 header actions Recommended scripts and Refresh are presented as one aligned action group in the Integrations provider header. Their callback/provider behavior is unchanged; the change is layout/responsiveness only. The dependency graph in Operations uses provider registry data to show active provider/resource relationships. System Health, Backups & Audit System Health, Backups & Audit Operational visibility and recovery controls. Applies to: Nord Inventory v2.0.0 System Health summarizes provider/database/runtime issues. Backups and the audit log support controlled operations and traceability. Relevant persistent tables include: nord_inventory_backups nord_inventory_audit_log nord_inventory_transactions Backup creation is an admin operation. Restore requires owner role by default. Recommended Scripts Modal Recommended Scripts Modal Read-only curated catalog with automatic compatibility tabs, search and safe browser links. Applies to: Nord Inventory v2.0.0 Recommended Scripts security The Recommended Scripts catalog is a Nord Lab-owned, read-only catalog. Who can edit it? Only Nord Lab developers editing the source before a release. There is no runtime editing path for server owners, Admin Studio administrators, or third-party developers. Where is it stored? The catalog is a local table inside server/core/ecosystem.lua. It is not in Config or the database. Production protection server/core/ecosystem.lua is intentionally not listed in escrow_ignore. When the package is published through Cfx.re/Tebex Asset Escrow, the file is protected by Asset Escrow. The raw development/source ZIP is not Asset-Escrow encrypted. Encryption is applied by Cfx.re/Tebex during the publishing process. Release rule Never add server/core/ecosystem.lua to escrow_ignore. Server owner visibility setting Server owners cannot edit the Nord Lab curated catalog. They can only hide or show the read-only button in Admin Studio from config/core.lua: Config.Ecosystem.ShowRecommendedScripts = true -- true = show, false = hide When disabled, the button is hidden and the curated catalog is not included in the Admin Studio payload. The protected Nord Lab catalog itself remains unchanged inside the Asset Escrow server core. Optional external links Nord Lab can attach browser links to a curated recommendation. Links remain part of the protected catalog and are still read-only for server owners. For one link, use the shorthand: { name = 'Example Script', resource = 'example_script', developer = 'Example Developer', integration = 'Compatible', url = 'https://example.com/script' } For several destinations, use links: links = { { label = 'Store', url = 'https://example.com/store' }, { label = 'Documentation', url = 'https://example.com/docs' }, { label = 'Discord', url = 'https://example.com/discord' } } The server only exposes http:// and https:// links to the NUI, removes duplicates and limits each recommendation to four external buttons. The NUI validates the URL again before asking FiveM to open it in the user's external browser. Current UI behavior tabs are created automatically from the integration values in the catalog; Native, Compatible, and future values such as Bridge can appear without hard-coding a fixed tab list; each tab shows its result count; search matches name, resource, developer, status, integration, notes and link metadata; cards show status, resource, developer and compatibility clearly; all new visible labels are represented in EN/PT locales; external buttons open the system browser, not an embedded untrusted webpage. Link safety Only http:// and https:// URLs are emitted. URLs are trimmed/deduplicated, capped in length, and each catalog entry exposes at most four buttons. NUI validates the URL again before opening it. v2.0.0 developer link registry Current curated developers inherit shared Store/Documentation links by developer name, so the same URLs do not need to be repeated in every recommendation. Developer Store Documentation Nord Lab https://nord-lab.tebex.io/ https://documentation.lunarocketeer.com/books/ Renovax Scripts https://renovax-scripts.tebex.io/ https://renovax-scripts.gitbook.io/renovax-scripts-docs Per-entry url/ links remain supported and are merged through the same sanitizer. Only http/https URLs are exposed, duplicates are removed and a recommendation exposes at most four link buttons. Developer API & Integrations Overview · Developer API & Integrations 4 · Developer API & Integrations Complete public export surface, runtime registration, provider ownership and migration examples. v2.0.0 adds four trusted server-side Operations/Forensics exports. Integration API Overview Integration API Overview Public, versioned integration surface for trusted FiveM resources. Applies to: Nord Inventory v2.0.0 Nord Inventory — Integration API Nord Inventory remains a Nord-native inventory. The public API intentionally uses familiar slot-inventory contracts so existing FiveM resources need minimal inventory-specific code. Typical migration A resource that reads an item count can use: local count = exports.nord_inventory:GetItemCount(source, 'water') Slot lookup: local slot = exports.nord_inventory:GetSlotWithItem(source, 'water', { type = 'clean' }) Search: local count = exports.nord_inventory:Search(source, 'count', 'water') local slots = exports.nord_inventory:Search(source, 'slots', 'water') The same read-only search helpers are also available client-side for the local player's inventory: local count = exports.nord_inventory:Search('count', 'water') local items = exports.nord_inventory:GetPlayerItems() UI bridge exports Notifications and world prompts are also exposed as a stable Nord gateway. The visual resources are selected only by name in Config.Notify, Config.TextUI and Config.Target; consuming resources do not need to know which notification/TextUI resource is installed. Server: Notify(source, message, kind?, duration?, title?) ShowTextUI(source, text, options?) HideTextUI(source) ShowTextUIEntry(source, id, data) HideTextUIEntry(source, id) Client: Notify(message, kind?, duration?, title?) ShowTextUI(text, options?) HideTextUI() ShowTextUIEntry(id, data) HideTextUIEntry(id) See docs/UI_BRIDGE.md for the minimal resource-name configuration and bridge contracts. Server exports Core catalogue and registry: GetInventoryType() GetItemDefinition(name) GetItems() GetItemList() Items(itemName?) ItemList(itemName?) RegisterItem(name, definition, useHandler?, side?) RegisterItems(definitions) RegisterInventory(id, options) RegisterStash(id, label, slots, maxWeight, owner?, groups?, coords?) Inventory operations: AddItem(inv, item, count, metadata?, slot?, cb?) RemoveItem(inv, item, count, metadata?, slot?, ignoreTotal?, strict?) CanCarryItem(inv, item, count, metadata?) CanCarryAmount(inv, item) CanCarryWeight(inv, weight) CanSwapItem(inv, firstItem, firstCount, testItem, testCount) ClearInventory(inv, keep?) RemoveInventory(inv) SetMaxWeight(inv, maxWeight) SetSlotCount(inv, slots) Read/search helpers: GetInventory(inv, owner?) GetInventories(type?, detailed?) GetInventoryItems(inv, owner?) GetItem(inv, item, metadata?, returnsCount?) GetItemCount(inv, item, metadata?, strict?) GetItemSlots(inv, item, metadata?) GetSlot(inv, slot) GetSlotForItem(inv, item, metadata?) GetSlotWithItem(inv, item, metadata?, strict?) GetSlotsWithItem(inv, item, metadata?, strict?) GetSlotIdWithItem(inv, item, metadata?, strict?) GetSlotIdsWithItem(inv, item, metadata?, strict?) GetEmptySlot(inv) Search(inv, 'slots'|'count', item|string[], metadata?) SearchInventory(inv, 'slots'|'count', item|string[], metadata?) Metadata/use: SetMetadata(inv, slot, metadata) GetMetadata(inv, slot) UpdateMetadata(inv, slot, patch) RegisterUsableItem(item, callback|export, side?) RegisterUseExport(item, export, side?) / RegisterUseExport(item, resource, export, side?) RegisterHook(name, callback) / registerHook(name, callback) Inventory identifiers Player inventories use the server id ( source). Registered stashes can be addressed by their registered id. Full Nord keys such as stash:police_armory, trunk:ABC123, and glovebox:ABC123 are also accepted when they exist. Metadata strings are normalized to { type = value }. The strict flag on slot/count helpers switches between exact metadata matching and partial matching. Runtime item registration with an external use export Trusted server resources can register an item definition without editing shared/items.lua and can declare its external use handler in the same definition. A bare client.export or server.export name is automatically bound to the resource that called RegisterItem. local ok, def = exports.nord_inventory:RegisterItem('service_token', { label = 'Service Token', description = 'Issued by another resource', weight = 5, stack = true, close = false, category = 'document', schema = 'generic', image = 'service_token.png', metadataDefaults = { issuer = '', issuedAt = 0 }, -- OX-style external use handler. Because the export name is bare, -- Nord resolves it as :UseServiceToken. client = { export = 'UseServiceToken', remove = 0 } }) exports('UseServiceToken', function(item, slot) -- Return false to cancel the use transaction. return true end) For a server-side handler, use server instead of client: server = { export = 'UseServiceToken', remove = 1 } exports('UseServiceToken', function(source, item, slot, definition) return true end) Important precedence rule A runtime item cannot overwrite an authoritative database row with the same name. RegisterItem returns a failure such as database_authoritative in that case. This protects Admin Studio/database definitions from being silently replaced by a third-party resource on restart. Runtime lifetime RegisterItem is transient. If you need a definition to be permanently managed by Nord Inventory, create/import it into the database-backed registry or maintain it in the reference Lua files. External item use exports Usable items can delegate their action to another resource while Nord remains responsible for inventory validation and optional removal. See docs/EXTERNAL_ITEM_USE.md. -- Compact: UseRepairKit belongs to the resource calling this export. exports.nord_inventory:RegisterUseExport('repair_kit', 'UseRepairKit', 'server') -- Explicit resource form remains supported. exports.nord_inventory:RegisterUseExport('repair_kit', 'my_mechanic', 'UseRepairKit', 'server') Or register the definition and export in one call: exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, use = { export = 'my_mechanic:UseRepairKit', side = 'server', remove = 1 } }) Internal durability repair items A registered item can use Nord's built-in server-authoritative durability repair effect instead of an external use export: exports.nord_inventory:RegisterItem('pistol_cleaning_kit', { label = 'Pistol Cleaning Kit', weight = 200, stack = true, close = true, use = { duration = 3000, remove = 1, repair = { item = 'weapon_pistol', amount = 30 } } }) repair.item is the internal name of the target definition and repair.amount is the number of durability percentage points restored. Nord repairs the most damaged matching instance, never exceeds the target maximum, and only consumes the repair item when a repair was actually applied. Developer Ecosystem API For provider-aware integrations, prefer the ecosystem APIs below. Full examples are in docs/DEVELOPER_ECOSYSTEM.md. -- Feature detection / diagnostics exports.nord_inventory:HasFeature('integration_manifest') exports.nord_inventory:GetCapabilities() exports.nord_inventory:GetRegisteredProvider('item_name') exports.nord_inventory:GetProviderRegistry() exports.nord_inventory:DebugItem('item_name') exports.nord_inventory:GetHealthReport() -- Full provider manifest exports.nord_inventory:RegisterIntegration({ ... }) exports.nord_inventory:UnregisterIntegration() -- Runtime ownership exports.nord_inventory:UnregisterItem('item_name') exports.nord_inventory:UnregisterItems({ 'item_one', 'item_two' }) exports.nord_inventory:UnregisterUseHandler('item_name') -- Context-menu actions exports.nord_inventory:RegisterItemAction('item_name', { ... }) exports.nord_inventory:UnregisterItemAction('item_name', 'action_id') exports.nord_inventory:GetItemActions('item_name') -- Metadata extensions exports.nord_inventory:RegisterMetadataSchema('item_name', schema, display) exports.nord_inventory:UnregisterMetadataSchema('item_name') exports.nord_inventory:GetMetadataSchema('item_name') -- Provider item images exports.nord_inventory:RegisterItemImage('path/in/provider.png', 'item_name.png') -- Item containers exports.nord_inventory:OpenItemContainer(source, slot) exports.nord_inventory:GetContainerInventory(source, slot) -- Durability exports.nord_inventory:GetDurability(source, slot) exports.nord_inventory:SetDurability(source, slot, value) exports.nord_inventory:AddDurability(source, slot, amount) exports.nord_inventory:RemoveDurability(source, slot, amount) exports.nord_inventory:RepairItem(source, slot, amount) All provider mutation APIs above are server-side. Provider ownership is resolved from the resource calling the export. Hide player metadata details exports['nord_inventory']:RegisterItem('example_item', { label = 'Example Item', weight = 100, hideMetadataDetails = true }) metadata.label and metadata.image remain presentation fields and still affect the visible item name/image. Other metadata remains available to scripts but is not shown in the player's item-information metadata section. Register category + items in one call exports['nord_inventory']:RegisterCategoryItems({ name = 'mechanic_materials', label = 'Mechanic Materials', icon = 'fa-screwdriver-wrench', order = 80 }, { mech_sandpaper = { label = 'Sandpaper', weight = 150 }, mech_primer = { label = 'Paint Primer', weight = 500 }, mech_clearcoat = { label = 'Clear Coat', weight = 500 } }) All item definitions inherit mechanic_materials automatically. For multiple folders in the same resource: exports['nord_inventory']:RegisterItemCatalog({ mechanic_paint = { label = 'Paint Materials', icon = 'fa-spray-can-sparkles', items = { mech_basecoat = { label = 'Base Coat', weight = 500 } } }, mechanic_tools = { label = 'Mechanic Tools', icon = 'fa-screwdriver-wrench', items = { mech_wrench = { label = 'Workshop Wrench', weight = 900 } } } }) Register categories exports['nord_inventory']:RegisterCategory('restaurant_food', { label = 'Restaurant Food', icon = 'fa-utensils', order = 100 }) RegisterCategory is idempotent. Existing categories are reused. A RegisterIntegration manifest can install categories = { ... } before its items = { ... }, or an individual RegisterItem can use an inline category table containing name, label, icon, and order. Canonical Item IDs & Aliases Canonical Item IDs & Aliases Keep one item identity while supporting legacy third-party names. Applies to: Nord Inventory v2.0.0 Nord Inventory resolves legacy aliases before authoritative item operations. The default alias map includes common QBCore-style ammunition IDs such as pistol_ammo, rifle_ammo, shotgun_ammo, etc. local canonical = exports.nord_inventory:ResolveItemName('pistol_ammo') -- -> ammo-9 with the default alias table Add server-specific legacy names to Config.ExternalItemAliases instead of duplicating item definitions under multiple names. Server Exports · Catalog & Opening Server Exports · Catalog & Opening Catalog lookup, item identity and inventory opening. Applies to: Nord Inventory v2.0.0 Common exports: exports.nord_inventory:GetInventoryType() exports.nord_inventory:GetItemDefinition(name) exports.nord_inventory:GetItems() exports.nord_inventory:GetItemList() exports.nord_inventory:ResolveItemName(value) exports.nord_inventory:GetExternalItemDefinition(value) exports.nord_inventory:GetItemCatalog() exports.nord_inventory:GetItemImage(value, mode) exports.nord_inventory:GetItemImageData(value) exports.nord_inventory:OpenInventory(target, invType, data) exports.nord_inventory:openInventory(target, invType, data) exports.nord_inventory:forceOpenInventory(target, invType, data) Use canonical item names for persistence and external aliases only at the boundary of third-party compatibility. Server Exports · Add, Remove & Carry Server Exports · Add, Remove & Carry Safe item/money mutations and preflight capacity checks. Applies to: Nord Inventory v2.0.0 local ok, result = exports.nord_inventory:AddItem(source, 'water', 2, { quality = 100 }) local removed = exports.nord_inventory:RemoveItem(source, 'water', 1) local canCarry = exports.nord_inventory:CanCarryItem(source, 'water', 5) local remaining = exports.nord_inventory:CanCarryAmount(source, 'water') Available money helpers: exports.nord_inventory:AddCash(target, amount, metadata) exports.nord_inventory:RemoveCash(target, amount) exports.nord_inventory:AddDirtyMoney(target, amount, metadata) exports.nord_inventory:RemoveDirtyMoney(target, amount) Also available: CanCarryWeight and CanSwapItem. Do not assume a successful client animation means an item mutation succeeded. Check the export return value and handle failure paths. Server Exports · Read & Search Server Exports · Read & Search Inventory snapshots, slot queries and count/search helpers. Applies to: Nord Inventory v2.0.0 Key exports: GetInventory GetInventories GetInventoryItems GetInventorySnapshot GetSlot GetSlotWithItem GetSlotsWithItem GetSlotIdWithItem GetSlotIdsWithItem GetEmptySlot GetSlotForItem GetItemCount GetItemSlots GetItem SearchInventory Search Use metadata arguments when item identity depends on instance metadata. strict matching is useful when an integration requires an exact metadata shape/value match instead of a looser subset match. Server Exports · Metadata & Inventory Management Server Exports · Metadata & Inventory Management Metadata mutation plus capacity and inventory lifecycle controls. Applies to: Nord Inventory v2.0.0 SetMetadata(target, slot, metadata) GetMetadata(target, slot) UpdateMetadata(target, slot, metadata) RepairInventoryCapacity(target) SetMaxWeight(target, maxWeight) SetSlotCount(target, slots) ClearInventory(target, keep) RemoveInventory(target) These are trusted server operations. Avoid exposing them 1:1 through unrestricted net events. Client Read-Only Exports Client Read-Only Exports Local snapshot helpers for UI/gameplay checks. Applies to: Nord Inventory v2.0.0 Current client read exports: Search(searchType, item, metadata) GetPlayerItems() GetPlayerWeight() GetPlayerMaxWeight() GetItemCount(itemName, metadata, strict) GetSlotWithItem(itemName, metadata, strict) GetSlotsWithItem(itemName, metadata, strict) GetSlotIdWithItem(itemName, metadata, strict) GetSlotIdsWithItem(itemName, metadata, strict) OpenInventory(...) openInventory(...) Client data is ideal for presentation and convenience checks. Final permission/item transfer decisions belong on the server. Registering Stashes & Custom Inventories Registering Stashes & Custom Inventories Dynamic storage registration from another server resource. Applies to: Nord Inventory v2.0.0 exports.nord_inventory:RegisterStash( 'mechanic_storage', 'Mechanic Storage', 80, 250000, false, { mechanic = 0 }, vector3(0.0, 0.0, 0.0) ) For more general storage: exports.nord_inventory:RegisterInventory('my_inventory_id', { label = 'My Inventory', slots = 40, maxWeight = 100000 }) Register storage from trusted server code and open it through the public inventory API. Usable Items & External Handlers Usable Items & External Handlers Attach behavior without making the browser authoritative. Applies to: Nord Inventory v2.0.0 External item use exports Nord Inventory has two mutually exclusive usable-item modes: internal: Nord handles duration, animation, hand prop, player effects and optional removal. export: Nord validates the item/slot transaction and delegates the gameplay action to another resource export. The Admin Studio exposes this under Item Management → Behavior → Use handler with Internal (Nord) and External export. OX-style item definition A resource can register an item and point its use directly at one of its own exports. When the export name is bare, Nord automatically binds it to the resource calling RegisterItem. exports.nord_inventory:RegisterItem('scanner', { label = 'Scanner', weight = 250, client = { export = 'UseScanner', -- automatically :UseScanner remove = 0 } }) exports('UseScanner', function(item, slot) -- item.name, item.label, item.metadata, item.count, item.slot, ... -- Return false to cancel the transaction. return true end) The full resource name is still accepted: client = { export = 'my_scanner:UseScanner', remove = 0 } -- or client = { export = 'my_scanner.UseScanner', remove = 0 } Server export exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, close = true, server = { export = 'UseRepairKit', remove = 1 } }) exports('UseRepairKit', function(source, item, slot, definition) -- Return false to cancel and prevent Nord from removing the item. return true end) The Nord-native descriptor is also supported: exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, use = { mode = 'export', export = 'my_mechanic:UseRepairKit', side = 'server', remove = 1 } }) mode = 'export' may be omitted when use.export is present. Register an external handler for an existing item Compact form, bound to the calling resource: exports.nord_inventory:RegisterUseExport('repair_kit', 'UseRepairKit', 'server') Explicit resource form: exports.nord_inventory:RegisterUseExport('repair_kit', 'my_mechanic', 'UseRepairKit', 'server') Descriptor/string forms through RegisterUsableItem are also accepted: exports.nord_inventory:RegisterUsableItem('repair_kit', 'UseRepairKit', 'server') exports.nord_inventory:RegisterUsableItem('repair_kit', 'my_mechanic:UseRepairKit', 'server') exports.nord_inventory:RegisterUsableItem('scanner', { export = 'UseScanner', side = 'client' }) A normal server Lua callback remains supported: exports.nord_inventory:RegisterUsableItem('repair_kit', function(source, item, definition, slot) return true end) Register the item and handler in one call The third RegisterItem argument can be a function, export string or export descriptor. The optional fourth argument selects server or client for string handlers. exports.nord_inventory:RegisterItem('repair_kit', { label = 'Repair Kit', weight = 500, use = { remove = 1 } }, 'UseRepairKit', 'server') Bulk registration RegisterItems registers multiple runtime items from one resource and applies the same caller-resource binding rules. local ok, result = exports.nord_inventory:RegisterItems({ scanner = { label = 'Scanner', weight = 250, client = { export = 'UseScanner', remove = 0 } }, repair_kit = { label = 'Repair Kit', weight = 500, server = { export = 'UseRepairKit', remove = 1 } } }) Transaction behavior Nord validates that the player still owns the same item/slot before the external action is committed. If an export is unavailable, errors, or returns false, the use is cancelled and Nord does not remove the item. remove stays server-authoritative: remove = 0: keep the item. remove = 1: remove one item after a successful external action. Higher values remove that amount, limited by the current stack. External mode is exclusive: Nord does not also run its internal duration, animation, hand prop, hunger, thirst, health or armor effects. The external resource owns those effects. Hands-only animations ( prop = false) An internal usable item can explicitly disable every hand-prop fallback while keeping its animation. use = { duration = 2500, animation = { dict = 'missheistdockssetup1clipboard@idle_a', clip = 'idle_a', flag = 49 }, prop = false } prop = false is authoritative for the use action. Nord Inventory will not fall back to: worldModel; keyword prop rules; category prop rules; the generic fallback prop. The item's worldModel can still be kept for ground/drop presentation. The default bandage uses this mode so the player performs a hands-only bandaging animation with no object attached. Additional handler exports: RegisterUsableItem RegisterUseExport UnregisterUseHandler Developer Ecosystem SDK Developer Ecosystem SDK Provider-aware runtime items, actions, schemas, images, hooks and health reporting. Applies to: Nord Inventory v2.0.0 Developer Ecosystem Nord Inventory exposes a provider-aware server SDK so another resource can own its items and behavior without editing shared/items.lua or the Nord core. Core rules Runtime registrations are transient and should be repeated when the provider resource starts. The calling FiveM resource is detected with GetInvokingResource(); integrations do not need to hard-code their own provider name for bare export handlers. A runtime definition cannot replace a database-authoritative item. RegisterItem / RegisterIntegration return database_authoritative for that definition. A provider may still attach an external use handler to an already-authoritative item. Runtime ownership, use handlers, item actions, metadata schemas and hooks are cleaned up by provider ownership when the resource stops or calls UnregisterIntegration(). One provider cannot silently steal a runtime item, external use handler, metadata schema or an action ID owned by another provider. Capability detection if not exports.nord_inventory:HasFeature('integration_manifest') then return end local capabilities = exports.nord_inventory:GetCapabilities() Useful capability names include runtime_items, external_use, provider_registry, integration_manifest, item_actions, metadata_schema_api, durability_api, containers, image_registration, health_check and backups. RegisterIntegration Use one server-side manifest when your resource owns several pieces of an integration: local ok, result = exports.nord_inventory:RegisterIntegration({ name = 'Example Medical', version = '1.0.0', author = 'Example Studio', description = 'Native Nord Inventory integration', dependencies = { 'nord_inventory' }, items = { medical_scanner = { label = 'Medical Scanner', description = 'Portable diagnostic device', weight = 1200, stack = false, close = true, -- Optional asset copied from this provider resource. imageSource = 'install/nord_inventory/medical_scanner.png', client = { export = 'UseMedicalScanner', remove = 0 }, metadataDefaults = { serial = '', owner = '' }, metadataSchema = { serial = { type = 'text', label = 'Serial' }, owner = { type = 'text', label = 'Owner' } }, actions = { { id = 'inspect', label = 'Inspect Scanner', icon = 'fa-magnifying-glass', side = 'client', export = 'InspectMedicalScanner', close = false } } } }, hooks = { itemUsed = function(payload) -- Provider-scoped hook; removed automatically with the integration. end } }) Client exports in the provider resource: exports('UseMedicalScanner', function(item, slot) StartMedicalScanner(item, slot) return true end) exports('InspectMedicalScanner', function(item, slot, actionId) InspectScanner(item, slot) return true end) RegisterItem / RegisterItems local ok, def = exports.nord_inventory:RegisterItem('service_token', { label = 'Service Token', weight = 5, stack = true, close = false, metadataDefaults = { issuer = '', issuedAt = 0 }, client = { export = 'UseServiceToken', remove = 0 } }) Batch form: exports.nord_inventory:RegisterItems({ item_one = { label = 'Item One', weight = 100 }, item_two = { label = 'Item Two', weight = 200 } }) Use handlers Attach a callback/funcref: exports.nord_inventory:RegisterUsableItem('legacy_item', function(source, item, definition, slot) return true end, 'server') Or attach an external export: exports.nord_inventory:RegisterUseExport('carplay', 'carplay', 'client') Full explicit form: exports.nord_inventory:RegisterUseExport('service_token', { resource = 'my_resource', export = 'UseServiceToken', side = 'server' }) Cross-resource FiveM funcrefs are accepted and wrapped safely; they are not indexed as ordinary Lua tables. Unregister ownership exports.nord_inventory:UnregisterItem('service_token') exports.nord_inventory:UnregisterItems({ 'item_one', 'item_two' }) exports.nord_inventory:UnregisterUseHandler('legacy_item') exports.nord_inventory:UnregisterIntegration() These calls are provider-scoped. A resource cannot unregister another provider's owned registration. Provider inspection local provider = exports.nord_inventory:GetRegisteredProvider('service_token') local providers = exports.nord_inventory:GetProviderRegistry() local debug = exports.nord_inventory:DebugItem('service_token') DebugItem reports the definition source, provider, registered actions, metadata extension and use-handler presence. Item Actions API Add an action to an existing item context menu: exports.nord_inventory:RegisterItemAction('id_card', { id = 'verify_card', label = 'Verify Card', icon = 'fa-id-card', side = 'server', export = 'VerifyCard', close = false }) exports('VerifyCard', function(source, item, slot, definition, actionId) -- Server-side validation here. return true end) Remove only your own action: exports.nord_inventory:UnregisterItemAction('id_card', 'verify_card') Read public actions: local actions = exports.nord_inventory:GetItemActions('id_card') Metadata Schema API exports.nord_inventory:RegisterMetadataSchema('employee_card', { employeeName = { type = 'text', label = 'Employee' }, company = { type = 'text', label = 'Company' }, employeeId = { type = 'text', label = 'Employee ID' } }, { employeeName = true, company = true, employeeId = true }) The extension is merged into the item metadata presentation without rewriting the authoritative item definition. local schema = exports.nord_inventory:GetMetadataSchema('employee_card') exports.nord_inventory:UnregisterMetadataSchema('employee_card') Item Image Registration Trusted server resources can copy a PNG/WebP shipped inside their own resource: local ok, imageName = exports.nord_inventory:RegisterItemImage( 'install/nord_inventory/service_token.png', 'service_token.png' ) The API rejects traversal paths, unsupported formats, oversized images and target-name ownership conflicts. For RegisterIntegration, use imageSource directly inside an item to copy the asset and assign the resulting image name to the definition. Durability API local value, maximum = exports.nord_inventory:GetDurability(source, slot) exports.nord_inventory:SetDurability(source, slot, 50) exports.nord_inventory:AddDurability(source, slot, 20) exports.nord_inventory:RemoveDurability(source, slot, 10) exports.nord_inventory:RepairItem(source, slot) -- full repair exports.nord_inventory:RepairItem(source, slot, 25) -- add 25 All mutations run through the normal Nord inventory metadata path and sync the affected inventory. Containers exports.nord_inventory:OpenItemContainer(source, slot) local container = exports.nord_inventory:GetContainerInventory(source, slot) The slot must contain an item whose Nord definition has a container configuration. Hooks exports.nord_inventory:RegisterHook('itemUsed', function(payload) print(payload.source, payload.item and payload.item.name) end) Provider-owned hooks are removed on UnregisterIntegration() or resource stop. Hook names emitted by the current core include beforeUseItem, itemUsed, itemAdded, itemRemoved, itemMoved, metadataChanged, itemRepaired, itemBroken, itemAction, inventoryOpened and inventoryClosed. Health diagnostics local report = exports.nord_inventory:GetHealthReport() The report is also visible in Admin Studio and checks provider/resource state, dependencies, export descriptors, missing images, durability configuration, registration conflicts and orphan extensions. Metadata privacy from RegisterItem External resources can decide whether an item's metadata detail cards are visible to players directly when registering the item. Use the canonical option: exports['nord_inventory']:RegisterItem('nr_food', { label = 'Restaurant Food', weight = 250, stack = true, -- Player can still see metadata.label / metadata.image as presentation, -- but the remaining metadata values are hidden from the item-info modal. hideMetadataDetails = true }) Then an instance can still use normal presentation metadata: exports['nord_inventory']:AddItem(source, 'nr_food', 1, { label = 'Cute Cafe Burger', image = 'cute_cafe_burger.png', recipeId = 14, restaurant = 'cute_cafe', hunger = 25, basePrice = 20 }) The player sees Cute Cafe Burger and cute_cafe_burger.png, but does not see recipeId, restaurant, hunger, basePrice, or other metadata detail cards. The metadata is not deleted or filtered from server exports. Scripts still receive the complete metadata. For compatibility, these registration aliases are also accepted: hideMetadata = true metadataPrivate = true metadataPlayerVisible = false metadataVisibility = false metadataVisibility = 'hidden' Nord normalizes all of them internally to: hideMetadataDetails = true The same option works with RegisterItems and with each item inside RegisterIntegration. Metadata details are hidden by default All registered items now use a privacy-first default. This is enough: exports['nord_inventory']:RegisterItem('nr_food', { label = 'Restaurant Food', weight = 250 }) Metadata detail cards are hidden automatically. Instance presentation still works: exports['nord_inventory']:AddItem(source, 'nr_food', 1, { label = 'Cute Cafe Burger', image = 'cute_cafe_burger.png', recipeId = 14, restaurant = 'cute_cafe' }) The player sees Cute Cafe Burger and its metadata image, but does not see recipeId, restaurant, or other metadata cards. To deliberately show metadata details for one item: exports['nord_inventory']:RegisterItem('identity_card', { label = 'Identity Card', weight = 10, hideMetadataDetails = false }) The equivalent opt-in alias is: showMetadataDetails = true You can still use per-field metadataDisplay / schema show settings once the item has opted into visible metadata details. Register items together with their category For integrations such as mechanics, restaurants or jobs, you can register the category and all items in one call. Every item automatically receives the category; you do not need to repeat category = 'mechanic' on each definition. local ok, result = exports['nord_inventory']:RegisterCategoryItems({ name = 'mechanic_materials', label = 'Mechanic Materials', icon = 'fa-screwdriver-wrench', order = 80 }, { mech_sandpaper = { label = 'Sandpaper', weight = 150, stack = true }, mech_primer = { label = 'Paint Primer', weight = 500, stack = true }, mech_clearcoat = { label = 'Clear Coat', weight = 500, stack = true } }) The result includes the category state plus registered/failed items: { category = 'mechanic_materials', categoryState = 'created', -- or existing registered = { 'mech_sandpaper', 'mech_primer', 'mech_clearcoat' }, failed = {} } The equivalent alias is: exports['nord_inventory']:RegisterItemsWithCategory(category, items) A string category name is also supported with the category definition as the third argument: exports['nord_inventory']:RegisterCategoryItems( 'mechanic_materials', items, { label = 'Mechanic Materials', icon = 'fa-screwdriver-wrench' } ) Register a complete item catalog Use RegisterItemCatalog when one resource owns several categories: exports['nord_inventory']:RegisterItemCatalog({ mechanic_paint = { label = 'Paint Materials', icon = 'fa-spray-can-sparkles', order = 80, items = { mech_basecoat = { label = 'Base Coat', weight = 500 }, mech_clearcoat = { label = 'Clear Coat', weight = 500 } } }, mechanic_tools = { label = 'Mechanic Tools', icon = 'fa-screwdriver-wrench', order = 90, items = { mech_polisher = { label = 'Polisher', weight = 1800, stack = false }, mech_wrench = { label = 'Workshop Wrench', weight = 900, stack = false } } } }) Categories are created/reused first, then their items are registered. Runtime items still follow the normal provider ownership rules and should be registered again when the provider resource starts. Custom category folders are persistent. Dynamic category registration External resources can install their own item categories before registering items. Category registration is idempotent: if the category already exists, Nord Inventory reuses it instead of creating a duplicate. Register one category local ok, category, state = exports['nord_inventory']:RegisterCategory( 'restaurant_food', { label = 'Restaurant Food', icon = 'fa-utensils', order = 100 } ) state is created or existing. Register several categories exports['nord_inventory']:RegisterCategories({ restaurant_food = { label = 'Restaurant Food', icon = 'fa-utensils', order = 100 }, restaurant_drinks = { label = 'Restaurant Drinks', icon = 'fa-glass-water', order = 110 } }) Create a category directly from RegisterItem An item can carry an inline category definition: exports['nord_inventory']:RegisterItem('nr_burger', { label = 'Restaurant Burger', weight = 250, category = { name = 'restaurant_food', label = 'Restaurant Food', icon = 'fa-utensils', order = 100 } }) Nord creates/reuses restaurant_food first, then registers the item with: category = 'restaurant_food' RegisterIntegration categories This is the recommended form for complete script integrations: exports['nord_inventory']:RegisterIntegration({ name = 'Nord Restaurants', categories = { restaurant_food = { label = 'Restaurant Food', icon = 'fa-utensils', order = 100 }, restaurant_drinks = { label = 'Restaurant Drinks', icon = 'fa-glass-water', order = 110 } }, items = { nr_burger = { label = 'Burger', category = 'restaurant_food', weight = 250 }, nr_coffee = { label = 'Coffee', category = 'restaurant_drinks', weight = 300 } } }) Categories are registered before items in the same integration call. Existing categories If a category already exists, it is reused and is not overwritten by another resource. A resource that originally created a custom category may explicitly update it: exports['nord_inventory']:RegisterCategory('restaurant_food', { label = 'Restaurant Meals', icon = 'fa-utensils', order = 90, updateExisting = true }) Only the owning resource can use updateExisting = true. Read categories local category = exports['nord_inventory']:GetCategory('restaurant_food') local categories = exports['nord_inventory']:GetCategories() Remove an owned category local ok, reason = exports['nord_inventory']:UnregisterCategory('restaurant_food') For safety, a category can only be removed by the resource that created it and only while it contains no active items. UnregisterIntegration does not delete persistent category folders automatically. Categories & Runtime Catalogs Categories & Runtime Catalogs Register categories and grouped catalogs from provider resources. Applies to: Nord Inventory v2.0.0 Category exports: RegisterCategory RegisterCategories GetCategory GetCategories UnregisterCategory RegisterCategoryItems RegisterItemsWithCategory RegisterItemCatalog Grouped registration is preferred for resources such as restaurants/crafting where many related items share one category/provider identity. Integration Manifests & Provider Ownership Integration Manifests & Provider Ownership Register a resource as an explicit provider and expose diagnostics. Applies to: Nord Inventory v2.0.0 exports.nord_inventory:RegisterIntegration({ name = 'My Resource', version = '1.0.0', author = 'My Studio', description = 'Adds custom items and actions.' }) Unregister with: exports.nord_inventory:UnregisterIntegration() Provider ownership helps Admin Studio explain which resource owns a runtime definition/action/image and whether that provider is currently online. Item Actions, Metadata Schemas & Images Item Actions, Metadata Schemas & Images Presentation and action extension points. Applies to: Nord Inventory v2.0.0 RegisterItemAction(itemName, action) UnregisterItemAction(itemName, actionId) RegisterMetadataSchema(itemName, schema, display) UnregisterMetadataSchema(itemName) RegisterItemImage(sourcePath, targetName) GetItemActions(itemName) GetMetadataSchema(itemName) A schema describes expected/display metadata; it does not make client-provided metadata trustworthy. Validate business rules on the server. Durability & Container API Durability & Container API Lifecycle and nested-storage helpers for integrations. Applies to: Nord Inventory v2.0.0 Durability: GetDurability(target, slot) SetDurability(target, slot, value) AddDurability(target, slot, amount) RemoveDurability(target, slot, amount) RepairItem(target, slot, amount) Containers: OpenItemContainer(source, slot) GetContainerInventory(target, slot) Respect server-defined capacity/depth and item lifecycle rules rather than duplicating them in another resource. Hooks, Capabilities & Diagnostics Hooks, Capabilities & Diagnostics Feature detection and operational inspection. Applies to: Nord Inventory v2.0.0 RegisterHook(name, callback) registerHook(name, callback) HasFeature(name) GetCapabilities() GetRegisteredProvider(itemName) GetProviderRegistry() GetHealthReport() GetIntegrationInfo() DebugItem(itemName) Feature detection is safer than version-string branching when you only need to know whether a capability is present. Admin Access Exports Admin Access Exports Public server access bridge used by Nord Staff and trusted administration tools. Applies to: Nord Inventory v2.0.0 HasAdminAccess(target, maybeTarget) GiveAdminAccess(target, maybeTarget) RemoveAdminAccess(target, maybeTarget) Runtime grants can persist in nord_inventory_admin_access. They do not need to rewrite ACE or static license configuration. Player Interaction Exports Player Interaction Exports Open search/robbery sessions and integrate surrender state. Applies to: Nord Inventory v2.0.0 Server: OpenPlayerSearch(source, target) OpenPlayerRobbery(source, target) IsPlayerSurrendered(target) Client: SetHandsUpState(value) IsHandsUp() Use the server exports for authority-sensitive actions. Notify & Text UI Exports Notify & Text UI Exports Use Nord bridges without binding your integration to the NUI implementation. Applies to: Nord Inventory v2.0.0 Server notify: exports.nord_inventory:Notify(target, message, kind, duration, title) Server TextUI: ShowTextUI(target, text, options) HideTextUI(target) ShowTextUIEntry(target, id, data) HideTextUIEntry(target, id) Bridge provider selection is controlled in config/bridges.lua. OX / QB Migration Examples OX / QB Migration Examples Common compatibility patterns when moving an integration to Nord Inventory. Applies to: Nord Inventory v2.0.0 Count local count = exports.nord_inventory:GetItemCount(source, 'water') Add/remove if exports.nord_inventory:CanCarryItem(source, 'water', 2) then exports.nord_inventory:AddItem(source, 'water', 2) end exports.nord_inventory:RemoveItem(source, 'water', 1) Search a slot local slot = exports.nord_inventory:GetSlotWithItem(source, 'water') Canonicalize a legacy name local item = exports.nord_inventory:ResolveItemName(legacyName) Migrate behavior at the public export boundary. Avoid emulating another inventory's private events/database tables inside Nord. Complete Export Index Complete Export Index Generated from export declarations in this exact build. Applies to: Nord Inventory v2.0.0 Server · Inventory & SDK GetInventoryType() GetItemDefinition(name) GetItems() GetItemList() ResolveItemName(value) GetExternalItemDefinition(value) GetItemCatalog() GetItemImage(value, mode) GetItemImageData(value) RegisterCategory(name, data) RegisterCategories(definitions) GetCategory(name) GetCategories() UnregisterCategory(name) RegisterItem(name, definition, useHandler, side) RegisterItems(definitions) RegisterInventory(id, options) Items(itemName) ItemList(itemName) OpenInventory() openInventory() forceOpenInventory() RegisterStash(id, label, slots, maxWeight, owner, groups, coords) AddItem(target, itemName, amount, metadata, slot, cb) AddCash(target, amount, metadata) RemoveCash(target, amount) AddDirtyMoney(target, amount, metadata) RemoveDirtyMoney(target, amount) RemoveItem(target, itemName, amount, metadata, slot, ignoreTotal, strict) CanCarryItem(target, itemName, amount, metadata) CanCarryWeight(target, weight) CanCarryAmount(target, itemName) CanSwapItem(target, firstItem, firstItemCount, testItem, testItemCount) GetInventory(target, owner) GetInventories(invType, detailed) GetInventoryItems(target, owner) GetInventorySnapshot(target, owner) GetIntegrationInfo() GetSlot(target, slot) GetSlotWithItem(target, itemName, metadata, strict) GetSlotsWithItem(target, itemName, metadata, strict) GetSlotIdWithItem(target, itemName, metadata, strict) GetSlotIdsWithItem(target, itemName, metadata, strict) GetEmptySlot(target) GetSlotForItem(target, itemName, metadata) GetItemCount(target, itemName, metadata, strict) GetItemSlots(target, itemName, metadata) GetItem(target, itemName, metadata, returnsCount) SearchInventory(target, searchType, itemName, metadata) Search(target, searchType, itemName, metadata) SetMetadata(target, slot, metadata) GetMetadata(target, slot) UpdateMetadata(target, slot, metadata) RepairInventoryCapacity(target) SetMaxWeight(target, maxWeight) SetSlotCount(target, slots) ClearInventory(target, keep) RemoveInventory(target) RegisterUsableItem(itemName, handler, side) RegisterUseExport(itemName, resourceOrExport, exportNameOrSide, side) UnregisterUseHandler(itemName) RegisterHook(name, callback) registerHook(name, callback) HasFeature(name) GetCapabilities() GetRegisteredProvider(itemName) RegisterItemAction(itemName, action) UnregisterItemAction(itemName, actionId) RegisterItemImage(sourcePath, targetName) UnregisterItem(itemName) UnregisterItems(items) RegisterCategoryItems(category, items, categoryData) RegisterItemsWithCategory(category, items, categoryData) RegisterItemCatalog(catalog) RegisterIntegration(manifest) UnregisterIntegration() RegisterMetadataSchema(itemName, schema, display) UnregisterMetadataSchema(itemName) OpenItemContainer(source, slot) GetContainerInventory(target, slot) DebugItem(itemName) GetDurability(target, slot) SetDurability(target, slot, value) AddDurability(target, slot, amount) RemoveDurability(target, slot, amount) RepairItem(target, slot, amount) GetItemActions(itemName) GetMetadataSchema(itemName) GetProviderRegistry() GetHealthReport() Client · Read-only inventory Search(target, searchType, itemName, metadata) GetPlayerItems() GetPlayerWeight() GetPlayerMaxWeight() GetItemCount(target, itemName, metadata, strict) GetSlotWithItem(target, itemName, metadata, strict) GetSlotsWithItem(target, itemName, metadata, strict) GetSlotIdWithItem(target, itemName, metadata, strict) GetSlotIdsWithItem(target, itemName, metadata, strict) Client · Runtime OpenInventory() openInventory() Server · Notify Notify(target, message, kind, duration, title) Server · Text UI ShowTextUI(target, text, options) HideTextUI(target) ShowTextUIEntry(target, id, data) HideTextUIEntry(target, id) Server · Player interactions OpenPlayerSearch(source, target) OpenPlayerRobbery(source, target) IsPlayerSurrendered(target) Client · Player interactions SetHandsUpState(value) IsHandsUp() Server · Vehicle storage GetVehicleStorageCapacity(invType, modelHash, vehicleClass) GetVehicleTrunkWeight(modelHash, vehicleClass) GetVehicleTrunkSlots(modelHash, vehicleClass) GetVehicleGloveboxWeight(modelHash, vehicleClass) GetVehicleGloveboxSlots(modelHash, vehicleClass) Server · Admin access HasAdminAccess(target, maybeTarget) GiveAdminAccess(target, maybeTarget) RemoveAdminAccess(target, maybeTarget) Server · Operations / Forensics GetItemPolicy(itemName) CreateInventorySnapshot(invKey, reason) GetInventoryLedger(filters) FindItemInstances(filters) Operations API · v2.0.0 Operations API · v2.0.0 Applies to: Nord Inventory v2.0.0 Four server exports are added by the Operations module. They are intended for trusted server resources/tooling. GetItemPolicy local policy = exports.nord_inventory:GetItemPolicy('police_evidence') Returns the resolved movement-policy data for the canonical item name. CreateInventorySnapshot local ok, snapshotId, canonicalKey = exports.nord_inventory:CreateInventorySnapshot(invKey, 'manual_tool') Creates a snapshot using live runtime state when the target player is connected and persisted state when offline. The invoking resource is recorded as the creator. GetInventoryLedger local rows = exports.nord_inventory:GetInventoryLedger({ search = 'weapon_pistol', limit = 50 }) Returns bounded transaction/forensics results. Treat this as a read/query API, not a substitute for inventory mutations. FindItemInstances local rows = exports.nord_inventory:FindItemInstances({ item = 'weapon_pistol', serial = 'SERIAL-HERE' }) Searches persisted and live cached inventory state using the same overlay rules as Operations so connected inventories are not double-counted from stale SQL. Security Do not expose these exports 1:1 through unrestricted client net events. Snapshot creation and forensic data should remain server-side/trusted. Admin Studio actions still use the normal permission bridge. Weapons & Vehicle Storage Overview · Weapons & Vehicle Storage 5 · Weapons & Vehicle Storage Weapon magazine authority, throwables, lifecycle and secure trunk/glovebox storage. Weapon System Overview Weapon System Overview Weapons as inventory item instances with server-owned ammunition/lifecycle state. Applies to: Nord Inventory v2.0.0 Weapons are inventory items. The server owns item identity and metadata; the game weapon entity is a presentation/control surface synchronized to that inventory instance. Reserve ammunition remains inventory items until a reload transaction removes exactly the rounds that fit into the magazine. Magazine Ammunition · Server Authority Magazine Ammunition · Server Authority Current magazine model and reload transaction rules. Applies to: Nord Inventory v2.0.0 Weapon ammunition persistence Nord Inventory stores the rounds currently loaded in a firearm in the weapon instance metadata ( metadata.ammo). When a firearm is holstered through the inventory, the final magazine count is now sent to the server in the same CompleteUseItem transaction. This avoids an event-order race where the player could reload, holster, and re-equip the same weapon but receive an empty magazine. If holstering happens while the native reload animation/transaction is still active, Nord uses the server-approved loaded value already held in equippedWeapon.ammo instead of GTA's temporary clip staging value. The server never trusts this path to add ammunition. UpdateWeaponAmmo can only reduce the current server magazine count. Actual increases still require LoadWeaponAmmo, which removes matching ammunition items first. -- Nord Inventory - inventory limits, weapon ammo and runtime rules Config = Config or {} Config.DefaultPlayerSlots = 40 Config.DefaultPlayerWeight = 80000 -- grams Config.DefaultStashSlots = 60 Config.DefaultStashWeight = 150000 Config.TrunkSlots = 50 Config.TrunkWeight = 120000 Config.GloveboxSlots = 10 Config.GloveboxWeight = 15000 -- Weapon magazine handling. Nord keeps ONLY the currently loaded magazine on the -- weapon metadata; reserve ammunition always remains as inventory items until a -- reload transaction removes exactly the rounds that fit in the magazine. Config.WeaponAmmo = { Enabled = true, DefaultMagazineSize = 30, -- used only until a weapon instance has magazineSize metadata MaxMagazineSize = 999, DetectMagazineFromGame = true, -- first equip can seed metadata.magazineSize from GTA's native clip size -- Keep the weapon physically equipped when the magazine reaches 0. -- GTA may try to switch the ped to WEAPON_UNARMED when the last round is -- fired; Nord immediately restores the empty weapon. The weapon is only -- holstered when the player uses/clicks that same inventory item again. KeepEquippedWhenEmpty = true, -- Automatic mode is intentionally slower than pressing R manually. -- First Nord waits before requesting the reload, then it keeps the weapon -- empty for an additional preparation period before the native reload starts. AutoReloadDelay = 1400, -- ms after the magazine reaches zero before automatic reload is requested AutomaticReloadPrepareTime = 900, -- extra ms before the automatic reload animation / rounds enter the weapon ReloadCooldown = 650, -- protects against duplicate reload requests ManualReloadControl = 45, -- INPUT_RELOAD (R) } Config.InventorySessionSeconds = 300 Config.SaveIntervalSeconds = 30 Config.MaxTransferAmount = 100000 Config.MaxContainerDepth = 3 Config.EnableWeight = true Config.EnableVolume = false Config.EnableDurability = true Config.EnableItemHistory = true Config.TransactionLogRetentionDays = 14 Manual & Automatic Reload Modes Manual & Automatic Reload Modes R vs automatic reload timing in the current config. Applies to: Nord Inventory v2.0.0 Current defaults: AutoReloadDelay: 1400 ms AutomaticReloadPrepareTime: 900 ms ReloadCooldown: 650 ms ManualReloadControl: 45 (R) Automatic reload intentionally adds delay. Manual R remains the faster deliberate player action. Duplicate requests are protected by cooldown/server transaction rules. Empty Magazine & Equip Behavior Empty Magazine & Equip Behavior Keep the actual weapon equipped when the last round is fired. Applies to: Nord Inventory v2.0.0 KeepEquippedWhenEmpty = true prevents GTA's automatic unarmed switch from becoming the inventory authority. Nord restores the empty equipped weapon; clicking/using the same inventory item is what holsters it. Throwable Weapons Throwable Weapons Consume inventory only after a projectile is actually thrown. Applies to: Nord Inventory v2.0.0 Throwable weapons Throwable GTA weapons use one real native projectile when equipped. Definitions use: weapon = { name = 'WEAPON_GRENADE' }, unique = true, metadataDefaults = { throwable = true } The item is not consumed when merely equipped. Nord waits for GTA's ammo to transition from 1 to 0, which indicates that the projectile was actually released, and only then removes the exact inventory instance by UID. This applies to grenades, sticky bombs, pipe bombs, Molotovs, proximity mines, gas/smoke/tear gas, flares, snowballs and balls. Putting the throwable away before throwing keeps the item in the inventory. Throwables do not use firearm reload logic, magazine persistence, or the empty-firearm auto-restore behavior. Weapon Durability & Back Display Weapon Durability & Back Display Lifecycle remains authoritative while back props remain cosmetic. Applies to: Nord Inventory v2.0.0 Weapon durability uses the same server lifecycle system as supported items. Back weapon props do not prove ownership and are not used to calculate ammo, condition or permissions. Vehicle Storage Overview Vehicle Storage Overview Trunk/glovebox sessions with model/category capacity resolution. Applies to: Nord Inventory v2.0.0 Default fallback capacities: Trunk: 50 slots / 120000 g Glovebox: 10 slots / 15000 g The vehicle registry can override these by category/model. Framework vehicle catalogs and GTA model scans can feed Admin Studio. Vehicle Registry & Capacity Resolution Vehicle Registry & Capacity Resolution Category/model data, framework import and unlimited/custom capacity patterns. Applies to: Nord Inventory v2.0.0 The current vehicle registry is enabled, imports supported framework vehicles automatically and scans GTA models. Capacity resolution prefers model/category-specific rules before global defaults. Use Admin Studio to manage realistic capacities instead of editing runtime inventory rows. Trunk & Glovebox Interaction Trunk & Glovebox Interaction Access mode, distance checks and interior TAB behavior. Applies to: Nord Inventory v2.0.0 Current vehicle interaction behavior includes: TAB inside a vehicle opens the glovebox path; trunk access uses configured TextUI/Target bridge behavior; lock state is rechecked through the configured provider; session identity binds to the actual vehicle/net identity/plate data rather than a UI-only selection. Live Trunk Session Security Live Trunk Session Security Why an already-open trunk closes when access becomes invalid. Applies to: Nord Inventory v2.0.0 Vehicle Trunk Access & Live Session Guard Nord Inventory validates trunk access both before opening and while the inventory remains open. Locked vehicles A locked vehicle cannot open its trunk inventory. The client checks both the normal GTA lock status and per-player door locks. The server revalidates the lock state whenever the artifact exposes the native, and also receives the normal-client preflight status for compatibility. Live trunk session Once a trunk is open, Nord continuously validates the same live vehicle context. The inventory closes automatically when: the vehicle becomes locked; the vehicle moves away from its opening position; the vehicle starts moving above the configured threshold; the player is no longer close enough to the physical trunk/frunk interaction point; the vehicle despawns; the network id is recycled to another entity; the plate no longer matches the opened vehicle. This is especially important for ambient/NPC vehicles: an NPC cannot drive away while the player keeps the old trunk inventory open. Configuration Config.VehicleInteraction.Trunk.SessionGuard = { Enabled = true, ClientCheckInterval = 150, ServerCheckInterval = 750, DistanceTolerance = 1.60, VehicleMoveDistance = 1.00, VehicleMoveSpeed = 0.65, CloseWhenLocked = true, CloseWhenVehicleMoves = true, } The client guard is for immediate UX. The server guard protects the inventory session and rejects further inventory actions once the vehicle context becomes invalid. Player-owned vehicles and vehicle-key resources Player-owned/personal vehicles must obey the same trunk lock rule as every other vehicle. Nord Inventory now has a dedicated open lock bridge: client/bridge/vehiclelocks.lua server/bridge/vehiclelocks.lua With the default configuration: LockIntegration = { Provider = 'auto' } auto detects nord_vehiclekeys. When nord_vehiclekeys is running, Nord Inventory reads its synchronized: nordkeys:locked state on the client and validates the server state through: exports.nord_vehiclekeys:GetLockState(netId) A locked = true result always blocks the trunk, even if GTA's native GetVehicleDoorLockStatus is briefly stale/unlocked for the owner. The provider and native checks are intentionally combined: if either reliable source says the vehicle is locked, trunk access is denied. Other vehicle-key resources Use: LockIntegration = { Provider = 'custom' } and implement the resolver in the open bridge files, or set the provider to a resource exposing an IsVehicleLocked export. Front Trunks / Frunks Front Trunks / Frunks Front-compartment detection for vehicles whose storage is at the front. Applies to: Nord Inventory v2.0.0 Nord can infer front storage using model/engine/bone/flag data and vehicle overrides. Keep model-specific exceptions in the vehicle configuration/registry rather than special-casing an integration's UI. Addon Vehicle Trunk Placement Addon Vehicle Trunk Placement Placement assistance and model overrides for non-standard vehicles. Applies to: Nord Inventory v2.0.0 Addon vehicles can have unusual dimensions, trunk geometry or storage location. Use the placement/vehicle registry tools to define the correct access position and capacity instead of increasing global interaction distance. NPC Vehicle Trunk Loot NPC Vehicle Trunk Loot Optional randomized loot for eligible NPC vehicle trunks. Applies to: Nord Inventory v2.0.0 Current config permits NPC trunk robbery and enables randomized loot. Default rolls range from 1 to 4 with an empty chance of 15%. Weighted sample loot includes basic consumables/tools and configured items. Treat the server as the loot authority. Do not decide reward rolls only in the client. Vehicle Storage Exports Vehicle Storage Exports Capacity queries for other vehicle/garage resources. Applies to: Nord Inventory v2.0.0 GetVehicleStorageCapacity(invType, modelHash, vehicleClass) GetVehicleTrunkWeight(modelHash, vehicleClass) GetVehicleTrunkSlots(modelHash, vehicleClass) GetVehicleGloveboxWeight(modelHash, vehicleClass) GetVehicleGloveboxSlots(modelHash, vehicleClass) These exports let garages/dealerships/admin tools show the same capacities Nord Inventory will actually enforce. Database, Security & Operations Overview · Database, Security & Operations 6 · Database, Security & Operations Persistence, security boundaries, diagnostics, backup/restore, upgrades and production operations. v2.0.0 adds Operations & Forensics, live/offline Inventory Manager, snapshots, Anti-Dupe, persistent placements and movement policies. Database Schema Reference Database Schema Reference Persistent tables installed by the current SQL schema. Applies to: Nord Inventory v2.0.0 Current schema tables: nord_inventory_custom_categories nord_inventory_storage nord_inventory_custom_items nord_inventory_item_versions nord_inventory_disabled_reference_items nord_inventory_preferences nord_inventory_transactions nord_inventory_vehicle_categories nord_inventory_vehicle_models nord_inventory_audit_log nord_inventory_backups nord_inventory_admin_access Do not treat these tables as a replacement for the public SDK. External resources should use exports so Nord can preserve source precedence, audit/history and validation semantics. v2.0.0 Operations tables nord_inventory_snapshots Stores inventory key/type/owner, slot and weight limits, reason/creator, full item payload and creation timestamp for recovery workflows. nord_inventory_forensics_alerts Stores Anti-Dupe findings with severity, code, identity value, item, payload, open/resolved status and timestamps. nord_inventory_placed_items Maps a persistent world placement ID to its inventory key, owner identifier, coordinates, model and timestamps. The inventory contents themselves continue to use normal Nord Inventory storage. All three are created with CREATE TABLE IF NOT EXISTS; v2.0.0 does not drop or rewrite existing inventory tables during this migration. Database & Persistence Database & Persistence Persistent item/storage state and safe restart behavior. Applies to: Nord Inventory v2.0.0 Database item persistence Item-definition precedence is strict and restart-safe: If nord_inventory_custom_items contains a row for an item name, that row owns the definition. shared/items.lua / shared/weapons.lua are consulted only if no database row exists for that name. Resource startup is read-only for item definitions. It never seeds, updates, replaces, or deletes DB item rows. A disabled DB row remains authoritative and blocks file fallback. The only way to restore the reference definition is an explicit Revert action, which deletes the DB override row. This prevents edited base items from returning to file defaults after restart nord_inventory. Item Definition Precedence Item Definition Precedence Deterministic reference/database/provider ownership rules. Applies to: Nord Inventory v2.0.0 Item definition precedence Nord Inventory uses one deterministic rule: Database row exists for the item name → the database definition is authoritative. No database row exists → shared/items.lua / shared/weapons.lua is used as reference fallback. Editing a reference/base item from Admin Studio creates or updates its database row. The reference file is never mutated. Reverting a base override removes the database row; only then does the reference definition become active again. This prevents a base item from being simultaneously resolved from the file and the database. Restart behaviour Resource/server startup is read-only for item definitions. Existing rows in nord_inventory_custom_items are never replaced, disabled, deleted, or reseeded from the Lua reference files during boot. Disabled DB rows still own their names and block reference fallback. Security & Server Authority Security & Server Authority Trust boundaries for inventory, admin, robbery, links and integrations. Applies to: Nord Inventory v2.0.0 Core rules: never trust NUI/client item amounts, metadata or permissions without server validation; use ACE/server-only license data for administration; keep owner-only restore separate from routine admin permissions; validate player distance/session identity for remote inventory access; validate vehicle lock/movement/range continuously during trunk sessions; validate external recommended-script URLs as http/https on server and NUI sides; use provider ownership for runtime registrations; do not expose privileged exports through unrestricted net events. Transaction History & Retention Transaction History & Retention Item history and transaction-log retention defaults. Applies to: Nord Inventory v2.0.0 Config.EnableItemHistory = true and Config.TransactionLogRetentionDays = 14 in the current build. Transaction/audit data is operational evidence, not a substitute for full database backups. Adjust retention based on server volume and your own compliance/storage requirements. Backups & Restore Backups & Restore Operational backup flow and owner-only restore. Applies to: Nord Inventory v2.0.0 Admin Studio can create inventory backups. Restore is owner-gated by default because it can replace persistent state. Before a major migration: take a full database backup outside Nord; create a Nord backup where appropriate; test the migration on staging; stop conflicting inventory writers; migrate and verify counts/metadata; keep rollback data until the server has run cleanly through restart/reconnect cycles. Audit Log Audit Log Administrative traceability for sensitive operations. Applies to: Nord Inventory v2.0.0 The audit log records sensitive administrative activity in nord_inventory_audit_log. Use it to investigate who changed definitions or performed operational actions, but keep server/database logs as an additional source of evidence. Stability Notes Stability Notes Runtime guardrails and patterns for production servers. Applies to: Nord Inventory v2.0.0 Nord Inventory stability notes Large weapons on back Up to two long weapons can be displayed at once. Cosmetic weapon props are networked so nearby players can see them. The equipped weapon is excluded by unique item UID. Back props are hidden while dead or inside a vehicle and are restored automatically. Inventory synchronization uses the lightweight player snapshot, so it also works with the NUI closed. Position/rotation is configurable under Config.BackWeapons. Item-use props Hand prop convention corrected to bone 60309 and rotation order 0. Common consumable/utility models are normalized through Config.ItemPropAttachments. rotOrder is now preserved by server sanitization. Admin-created hand props use known model calibration when available. Static validation web/app.js passed Node syntax validation. EN/PT JSON parsed successfully. Every static Lua L('...') notification key exists in both EN and PT. No duplicate HTML IDs detected. Referenced manifest files validated. Native compatibility guards Nord Inventory no longer requires NetworkGetEntityIsNetworked or SetEntityCompletelyDisableCollision to exist as Lua globals. Vehicle control uses normal network-control natives directly. Attached props and back weapons use SetEntityCollision(false, false) as the compatible baseline, with complete collision disabling only when the current artifact exposes it. Network IDs are also read through guarded helpers because ambient NPC vehicles can disappear while an inventory or trunk session watchdog is running. v2.0.0 runtime hardening networked long-weapon back props are removed reliably after ownership migration; stale/legacy equipped weapon snapshots fall back to weapon-name matching so the back prop does not remain until relog; pending ground-model loads are invalidated when a drop leaves range or is removed, preventing ghost props; metadata-aware CanCarryItem avoids incorrect stack acceptance; stack = false requires one free slot per item and creates count-1 instances; legacy malformed unique stacks and missing UID/serial/container identities are repaired safely during load; server-owned identities cannot be erased/replaced by SetMetadata/ UpdateMetadata; failed robbery transfers no longer remove Fast Slot pins; same-slot moves are no-op operations; transient SQL save failures keep inventories dirty for a later autosave retry; player disconnect and resource-restart synchronization include fallback/resnapshot paths. Troubleshooting Playbook Troubleshooting Playbook Fast diagnosis by symptom. Applies to: Nord Inventory v2.0.0 Inventory does not open confirm nord_inventory is started and named correctly; check framework detection/config value; inspect NUI/client console errors; verify locale JSON is valid; verify no other resource owns the same key command unexpectedly. Items do not persist inspect oxmysql/database errors; confirm SQL schema is installed; ensure the target inventory ID/player identifier is stable; check that a third-party resource is not overwriting state directly. Runtime item registration returns false start the provider after Nord Inventory or implement retry; canonicalize the item name; inspect Provider Registry/System Health; verify source precedence/provider ownership. Trunk closes immediately check lock provider state; player/vehicle distance; vehicle movement threshold; network entity/plate identity; target vehicle despawn/replacement. Admin Studio opens but mutation fails UI visibility is not permission: check server role/ACE; confirm config/admin.lua and Nord Staff grant state; inspect audit/server logs for rejected action. Error Reference & Diagnostics Error Reference & Diagnostics Where to look before changing code. Applies to: Nord Inventory v2.0.0 Use these in order: FXServer console error and resource/line; client F8/NUI console if the issue is presentation/input; Admin Studio > System Health; Provider Registry for runtime registration ownership/failures; DebugItem(itemName) for definition/provider inspection; database table/schema existence and oxmysql query errors; current config value and locale JSON validity. Enable debug logging only while diagnosing; verbose integration logging is not intended as permanent production noise. Upgrade to v2.0.0 Upgrade to v2.0.0 Replace the resource with the complete v2.0.0 build while keeping the resource folder named nord_inventory. Keep your existing database. Auto-SQL remains backwards-compatible and creates any missing Operations tables without deleting existing inventory data. Review config/operations.lua before restart. Existing defaults remain backwards-compatible. If you customized Config.UI.specialSlots, merge your slot definitions into the v2.0.0 config/ui.lua. Category matching and explicit items allowlists remain supported. Restart nord_inventory (or the server) and open Admin Studio → Operations and Admin Studio → Integrations. Run one Anti-Dupe scan and verify the result before resolving historic alerts. Create a manual snapshot of a test player, perform a small Inventory Manager edit and restore the snapshot to validate database permissions. Place a disposable test item persistently, restart the resource and confirm the item returns at the same coordinates. Confirm long weapons disappear from the back immediately when equipped/used and that ground drops stream in/out cleanly. Confirm connected integration providers appear in the Integrations registry and that Recommended scripts / Refresh actions remain responsive. No destructive database migration is required for v2.0.0. Optional physical clothing Config.Operations.ClothingBridge.Enabled remains false after upgrade. Enable it only when the configured appearance resource exposes the matching client export. This keeps v2.0.0 backwards-compatible with existing clothing/appearance setups. Config merge checklist Do not copy an old config/ folder over v2.0.0. Explicitly review at least config/operations.lua, config/ui.lua, config/admin.lua, config/player_interactions.lua and any owner-customized bridge/vehicle/item settings. Post-upgrade verification After the resource starts, check for missing tables, provider failures and locale errors before allowing players in. Then perform the v2.0.0 Operations smoke tests from the Production Checklist. Performance & Production Tuning Performance & Production Tuning Practical tuning without weakening authority. Applies to: Nord Inventory v2.0.0 Keep SaveIntervalSeconds reasonable; the current default is 30 seconds. Avoid polling full inventory snapshots every frame in external resources. Cache static item definitions/catalogs where appropriate and refresh on provider changes. Use client read-only exports for display-only checks; use server exports for mutations. Keep ground prop draw/spawn distances bounded. Avoid oversized item images; ecosystem image registration has a 2 MiB default cap. Keep transaction/audit retention appropriate for server volume. Do not disable trunk session guards to solve a UI symptom; fix the underlying lock/network/distance integration. Operations & Forensics Center — v2.0.0 Operations & Forensics Center — v2.0.0 Nord Inventory v2.0.0 includes an admin-only Operations Center built around the existing server-authoritative inventory model. Included systems Ledger / Forensics — searches nord_inventory_transactions by transaction id, identifier, item, inventory, UID, weapon serial or container UID. Movement transactions now preserve identity fields in their payload. Anti-Dupe Center — on-demand bounded scan of persisted + live cached inventories. UID, weapon serial and container UID are checked independently. A unique identity with multiple copies in one stack is also flagged. Item Instance Explorer — locates item instances across player, stash, container, vehicle and ground inventories and exposes owner, slot, storage key and sanitized metadata. Inventory Manager — inspects both connected and offline player inventories. Connected players are read from the authoritative live InventoryCore state; offline players are read from nord_inventory_storage. Every admin edit creates a safety snapshot before mutation when enabled. Snapshots & Recovery — manual and automatic per-inventory snapshots with owner-level restore permission. A pre-restore snapshot is always created first. Persistent Placed Items — players can deliberately place an item in the world. The drop, inventory payload and coordinates survive resource/server restarts. Item Policies — per-item or per-category movement restrictions for giving, dropping, throwing, persistent placement and destinations such as trunk, glovebox, stash, container, player and ground. Dependency Graph — reads the Nord provider registry and shows active provider/resource relationships in Admin Studio. Equipment Slots 2.0 — special slots can now match item categories or explicit item-name allowlists. Existing servers retain the previous slot layout unless extra equipment slots are configured. Permissions The normal Nord Inventory permission bridge is used: forensics — Operations Center, ledger, instance explorer, anti-dupe and alert resolution. offline_inventory — Inventory Manager lookup, inspection, editing and manual snapshots. The permission name is kept for backwards compatibility. restore_snapshots — snapshot restore. Default minimum role is admin. offline_inventory — snapshot creation and deletion, alongside offline inventory management. Default minimum role is admin. Nord Staff/ACE/database access continues to flow through the existing permission bridge. Inventory Manager source of truth The manager deliberately uses different sources depending on player state: Online player: InventoryCore.GetPlayerInventory(source) / live runtime state is authoritative. The UI never silently falls back to stale SQL for a connected owner. Offline player: nord_inventory_storage is authoritative. Online players are listed first and stale persisted rows for the same owner are de-duplicated. Legacy persisted player keys are redirected to the current canonical live inventory key when that owner is connected. Manual and automatic snapshots of connected players serialize the current live item table. Snapshot restore refreshes the connected player's inventory session immediately. Admin edits persist immediately; if the SQL transaction fails, the runtime mutation is rolled back in memory. While the Inventory Manager tab is open, selected live inventories receive event-driven updates through the normal inventory watcher path. The subscription is removed when the tab/Studio closes and also expires automatically. Auto-SQL The runtime creates these tables with CREATE TABLE IF NOT EXISTS: nord_inventory_snapshots nord_inventory_forensics_alerts nord_inventory_placed_items The same schema is included in sql/nord_inventory.sql for manual installations. Existing inventory data is not deleted or rewritten by the Operations migration included with v2.0.0. Item policies Edit config/operations.lua. Missing properties mean allow, so updating from an older build does not block existing item movement. Config.Operations.ItemPolicies = { ByName = { police_evidence = { allowGive = false, allowDrop = false, allowThrow = false, allowTrunk = false, allowGlovebox = false, allowedJobs = { police = 0 } } }, ByCategory = { identity = { allowDrop = false, allowThrow = false } } } Supported policy fields: allowGive, allowDrop, allowThrow, allowPersistentPlace, allowTrunk, allowGlovebox, allowStash, allowContainer, allowPlayer, allowGround, allowedJobs. Persistent placement Config.Operations.PersistentPlacedItems controls the feature. Persistent items are intentionally different from ordinary drops: ordinary drops keep the configured lifetime; persistent placed items are database-backed; both sides are saved immediately when a persistent item is transferred to reduce crash-window duplication/loss; empty persistent placed inventories are removed from both the placed-item registry and inventory storage. Scan safety Forensics scans are on-demand and bounded by: MaxLedgerRows MaxInstanceRows MaxStorageScanRows MaxOfflinePlayers The scanner overlays live cached inventories on top of database rows. That prevents stale database state and live state from being counted twice. Equipment Slots 2.0 Existing category rules remain valid. An equipment slot may additionally use items = { ... }: { key = 'phone', slot = 8, items = { 'phone', 'nord_phone' }, label = 'Phone', icon = 'fa-mobile-screen' } Extra equipment slots are opt-in in config/ui.lua so an update does not unexpectedly reserve more player slots. Optional clothing bridge Config.Operations.ClothingBridge provides an opt-in hand-off for physical clothing items. It is disabled by default so existing servers keep their current appearance flow. When enabled, an item whose category matches Category is treated as usable through the configured client export, for example: ClothingBridge = { Enabled = true, Category = 'clothing', Resource = 'nord_appearance', ClientExport = 'UseInventoryClothingItem' } The target export receives (itemData, slot) and should return false to reject the equip action. Item-specific use.mode = 'export' definitions always take priority over this generic bridge. Exports Server exports added by the Operations module: exports.nord_inventory:GetItemPolicy(itemName) exports.nord_inventory:CreateInventorySnapshot(invKey, reason) exports.nord_inventory:GetInventoryLedger(filters) exports.nord_inventory:FindItemInstances(filters) Production notes The anti-dupe scan is diagnostic: it records alerts but never deletes items automatically. Snapshot restore requires an elevated permission and creates a safety snapshot first. Offline admin edits are audited through the existing Nord ecosystem audit system. Transaction Ledger & Anti-Dupe Transaction Ledger & Anti-Dupe Applies to: Nord Inventory v2.0.0 Ledger The Operations Ledger searches nord_inventory_transactions. Filters can target transaction ID, identifier, item, inventory, UID, weapon serial and container UID. Identity fields are preserved in transaction payloads to make investigations possible without mutating item state. Config.Operations.MaxLedgerRows bounds the result size. Clear records Admins with the forensics permission can clear the transaction ledger through the Operations toolbar. The action: requires confirmation in NUI; deletes transaction rows only; does not reset the table primary key; does not touch live/persisted inventories; writes an entry to the separate Admin Studio audit log containing the deleted-row count. New movements continue to be recorded immediately after cleanup. Anti-Dupe Center The scan is diagnostic and never deletes items automatically. It checks these identities independently: unique item UID; weapon serial; container UID. A supposedly unique identity appearing in a stack with count > 1 is also suspicious. The scanner overlays live cached inventories over persisted storage so the same online player is not counted twice from stale SQL + live runtime state. Alerts are persisted in nord_inventory_forensics_alerts until resolved. Resolving an alert changes its status; it does not modify the underlying item automatically. Safe use Run scans on demand rather than polling them continuously. Review the matching inventories and item identity before deciding whether an alert represents a real duplication, a legacy malformed item or a legitimate historic record. Inventory Manager & Snapshots Inventory Manager & Snapshots Applies to: Nord Inventory v2.0.0 Source of truth The v2.0.0 manager has one strict rule: online player: authoritative InventoryCore runtime state; offline player: nord_inventory_storage. A connected player is never silently edited from stale SQL. Legacy persisted keys for a connected owner are redirected to that owner's current live inventory key. Online players are listed first and duplicate stale storage rows are hidden. Live updates While an inventory is selected in Admin Studio, normal inventory watcher updates refresh the manager without destroying the visible snapshot list. Subscriptions are removed when the tab/Studio closes and automatically expire after Config.Operations.LiveManagerWatchSeconds. Admin edits Add/remove/clear operations create a safety snapshot first when AutoSnapshotBeforeAdminEdit = true. If persistence fails, the live mutation is rolled back in memory instead of leaving runtime and SQL inconsistent. Snapshots Snapshots store inventory key/type/owner, slot and weight limits, the item payload, reason, creator and timestamp. Connected-player snapshots serialize current live state. A restore: requires restore_snapshots; creates a pre-restore safety snapshot; restores the selected payload; targets the canonical live key when the owner is online; refreshes that player's inventory session immediately. Retention is controlled with Config.Operations.SnapshotRetentionDays. Persistent Placed Items & Movement Policies Persistent Placed Items & Movement Policies Applies to: Nord Inventory v2.0.0 Persistent placed items Persistent placement is deliberately separate from ordinary ground drops. Ordinary drops still use the configured lifetime; persistent placements are backed by nord_inventory_placed_items plus normal inventory storage and survive resource/server restarts. Config.Operations.PersistentPlacedItems = { Enabled = true, MaxPerPlayer = 30, MaxDistance = 8.0, DefaultModel = 'prop_cs_cardbox_01' } When an item is placed persistently, both inventory sides are persisted together through an atomic transaction where applicable. Empty persistent placed inventories are removed from the registry and storage. Arbitrary client-provided models are not trusted. Item movement policies Policies live in config/operations.lua. Missing fields mean allow. Config.Operations.ItemPolicies = { ByName = { police_evidence = { allowGive = false, allowDrop = false, allowThrow = false, allowTrunk = false, allowGlovebox = false, allowedJobs = { police = 0 } } }, ByCategory = { identity = { allowDrop = false, allowThrow = false } } } Supported fields: allowGive, allowDrop, allowThrow, allowPersistentPlace, allowTrunk, allowGlovebox, allowStash, allowContainer, allowPlayer, allowGround, allowedJobs. Use item-specific rules for exceptional items and category rules for broad groups. Item rules and server-side validation are authoritative; disabling a NUI action alone is not a security boundary. Operations Configuration & Limits Operations Configuration & Limits Applies to: Nord Inventory v2.0.0 config/operations.lua is shared configuration and is included in escrow_ignore for server owners. Config.Operations = { Enabled = true, MaxLedgerRows = 250, MaxInstanceRows = 1200, MaxStorageScanRows = 5000, MaxOfflinePlayers = 80, SnapshotRetentionDays = 30, AutoSnapshotBeforeAdminEdit = true, LiveManagerWatchSeconds = 300, PersistentPlacedItems = { Enabled = true, MaxPerPlayer = 30, MaxDistance = 8.0, DefaultModel = 'prop_cs_cardbox_01' }, ClothingBridge = { Enabled = false, Category = 'clothing', Resource = 'nord_appearance', ClientExport = 'UseInventoryClothingItem' }, ItemPolicies = { ByName = {}, ByCategory = {} } } Why the limits exist Forensics reads can touch many persisted inventories, so v2.0.0 bounds Ledger, instance, storage and offline-player result sets. Increase them only after measuring on your database. Do not turn Admin Studio scans into high-frequency polling. Clothing bridge The clothing bridge is disabled by default. When enabled, items in the configured category are handed to the specified client export as (itemData, slot). Returning false rejects the equip action. Explicit item use.mode = 'export' behavior has priority over the generic clothing bridge. Nord Ecosystem Overview · Nord Ecosystem 7 · Nord Ecosystem Native Nord integrations and the protected recommended-script catalog. Nord Staff Integration Nord Staff Integration Automatic admin-access bridge plus shared item/provider APIs. Applies to: Nord Inventory v2.0.0 Nord Staff Integration Admin access bridge Nord Inventory now exposes the exact access-export pattern detected automatically by current nord_staff builds: exports['nord_inventory']:HasAdminAccess(playerId) exports['nord_inventory']:GiveAdminAccess(playerId) exports['nord_inventory']:RemoveAdminAccess(playerId) No change is required in nord_staff. When Dar acesso is used, Nord Inventory grants the configured role and all server-side Admin Studio permission checks use it immediately. License-based grants are persisted automatically in nord_inventory_admin_access, so they survive resource/server restarts. Removing access removes only the Staff-managed grant; ACE and static license roles are never changed. Configure the bridge in config/admin.lua: Config.AdminAccess.NordStaffBridge = { Enabled = true, Role = 'admin', -- developer | admin | owner AllowedResources = { 'nord_staff' } } Nord Inventory exposes a canonical API intended for Nord Staff and other admin resources. The integration never uses a visible item label as the spawn ID. Canonical identity Every external item object follows: { name = 'ammo-rifle2', -- internal/spawn name id = 'ammo-rifle2', internalName = 'ammo-rifle2', label = 'Rifle Ammo Mk II', -- visible text only title = 'Rifle Ammo Mk II' } name is always the real Nord Inventory identifier. Recommended Nord Staff exports Integration information local info = exports['nord_inventory']:GetIntegrationInfo() Resolve any incoming item value local internal = exports['nord_inventory']:ResolveItemName('mg_ammo') -- ammo-rifle2 The resolver accepts canonical IDs, configured aliases, and unique labels. Aliases are owner-editable in: config/items.lua under Config.ExternalItemAliases. Item catalogue local items = exports['nord_inventory']:GetItemCatalog() Each entry includes canonical item identity plus image, imageUrl and imageFile. Item image local url = exports['nord_inventory']:GetItemImage('bandage') local file = exports['nord_inventory']:GetItemImage('bandage', 'file') local data = exports['nord_inventory']:GetItemImage('bandage', 'data') Local item URLs use: https://cfx-nui-nord_inventory/web/images/items/ Remote HTTP/HTTPS item images are returned unchanged. Inventory snapshot local snapshot = exports['nord_inventory']:GetInventorySnapshot(playerId) The snapshot is a slot-sorted array designed for Staff/Admin UIs. Every item uses the canonical internal name. Add / remove exports['nord_inventory']:AddItem(playerId, internalName, amount, metadata, slot) exports['nord_inventory']:RemoveItem(playerId, internalName, amount, metadata, slot) The Nord Staff bridge resolves the item through Nord before either operation. Why this fixes Staff spawn errors Older bridges commonly mixed: name = item.label id = item.name That makes a Staff UI send a display title instead of the spawn identifier. The new contract keeps visible text in label/ title and reserves name for the canonical Nord ID. Nord Inventory + Nord CarPlay Nord Inventory + Nord CarPlay Recommended integration pattern for device/item ownership. Applies to: Nord Inventory v2.0.0 Use canonical Nord item IDs and metadata to represent device identity where required. CarPlay should query/add/remove items through public exports and keep technical identifiers hidden from player-facing metadata details where appropriate. If the integration registers runtime items, register an integration manifest/provider so Admin Studio can identify ownership. Nord Inventory + Nord Crafting Nord Inventory + Nord Crafting Native crafting integration principles. Applies to: Nord Inventory v2.0.0 nord_crafting should use Nord Inventory as the material/output authority: resolve canonical item names; check counts/carry capacity server-side; remove ingredients only as part of a validated craft transaction; add outputs through AddItem; register custom categories/catalogs at runtime when useful; keep metadata/lifecycle/rarity in the resulting item instance. The current curated catalog lists nord_crafting as Verified / Native. Nord Inventory + Nord Restaurant Creator Nord Inventory + Nord Restaurant Creator Native restaurant item/stash/recipe integration. Applies to: Nord Inventory v2.0.0 The restaurant system can register food/ingredient catalogs, dynamic stashes and usable items through the SDK. Startup ordering should allow Nord Inventory to be ready before restaurant item registration, or the restaurant should retry registration safely. The current curated catalog lists nord_restaurants as Verified / Native. Nord Inventory + Nord Keys Nord Inventory + Nord Keys Vehicle lock state used by live trunk session security. Applies to: Nord Inventory v2.0.0 Config.VehicleInteraction.LockIntegration.Provider = 'auto' supports automatic lock-provider resolution. The current lock bridge recognizes nord_vehiclekeys and can also read the entity state key nordkeys:locked where available. A custom lock provider should expose a reliable server-side lock state. Trunk UI access alone must not bypass a subsequently locked vehicle. The curated catalog entry is named Nord Keys with resource nord_keys; the lock bridge can also detect the vehicle-key provider used by the server build. Recommended Scripts · Current Catalog Recommended Scripts · Current Catalog The protected Nord Lab curated catalog included in this build. Applies to: Nord Inventory v2.0.0 Script Resource Developer Status Integration Metal Detector metaldetector Renovax Scripts Verified Compatible Outfit Bag outfitbag Renovax Scripts Verified Compatible Outfit Bag V2 outfitbag_v2 Renovax Scripts Verified Compatible Drug Sell V2 drugsell_v2 Renovax Scripts Verified Compatible Sell Drugs selldrugs Renovax Scripts Verified Compatible Dustbin Search dustbin_search Renovax Scripts Verified Compatible Trucker Job trucker_job Renovax Scripts Verified Compatible Warehouse System warehouse_system Renovax Scripts Verified Compatible Delivery System delivery_system Renovax Scripts Verified Compatible Crafting System crafting_system Renovax Scripts Verified Compatible Nord Crafting nord_crafting Nord Lab Verified Native Nord Restaurant Creator nord_restaurants Nord Lab Verified Native Nord Keys nord_keys Nord Lab Verified Native Server owners can hide/show the modal with Config.Ecosystem.ShowRecommendedScripts; they cannot edit the protected catalog through Admin Studio. Current developer destinations Nord Lab — Store: https://nord-lab.tebex.io/ · Docs: https://documentation.lunarocketeer.com/books/ Renovax Scripts — Store: https://renovax-scripts.tebex.io/ · Docs: https://renovax-scripts.gitbook.io/renovax-scripts-docs In v2.0.0 these destinations are inherited from the developer-level link registry and appear automatically on all current recommendations from the same developer. Recommended Scripts · Tabs, Search & Links Recommended Scripts · Tabs, Search & Links How compatibility grouping and optional browser links work. Applies to: Nord Inventory v2.0.0 Automatic tabs The NUI derives tabs from unique integration values. This means adding a future curated value such as Bridge can automatically create a new tab without changing the HTML structure. Search Search covers script name, resource, developer, status, integration, notes and available link labels/URLs. One external link { name = 'Example', resource = 'example_resource', developer = 'Example Dev', status = 'Verified', integration = 'Compatible', notes = 'Example integration.', url = 'https://example.com' } Multiple links links = { { label = 'Store', url = 'https://example.com/store' }, { label = 'Documentation', url = 'https://example.com/docs' }, { label = 'Discord', url = 'https://example.com/community' } } Limits: http/https only, max URL length 1024, max label length 48, deduplicated URLs, maximum four links per entry. The browser action uses FiveM's native URL opener when available with a normal browser-window fallback. All visible labels/states must remain represented in both EN/PT locale JSON files. Current developer destinations Nord Lab — Store: https://nord-lab.tebex.io/ · Docs: https://documentation.lunarocketeer.com/books/ Renovax Scripts — Store: https://renovax-scripts.tebex.io/ · Docs: https://renovax-scripts.gitbook.io/renovax-scripts-docs In v2.0.0 these destinations are inherited from the developer-level link registry and appear automatically on all current recommendations from the same developer. Reference Files Overview · Reference Files 8 · Reference Files Quick-reference configuration, schema, file map and import attachments. Configuration Reference Configuration Reference Current owner-editable configuration files and defaults. Applies to: Nord Inventory v2.0.0 Configuration Nord Inventory keeps all owner-editable settings inside one config/ directory. The former root config.lua and server/config.lua files have been removed. Files File Purpose Loaded on config/core.lua Framework, locale, debug, ecosystem controls, inventory open command/key Client + Server config/commands.lua Admin Studio command and protected command aliases Client + Server config/inventory.lua Player/stash/vehicle base limits, weapon ammo, sessions, durability/history Client + Server config/operations.lua Operations/forensics, snapshots, persistent placement, policies, clothing bridge Client + Server config/player_interactions.lua Player search/robbery/hands-up rules Client + Server config/bridges.lua Notify, TextUI, Target and world interaction provider selection Client + Server config/vehicles.lua Vehicle registry, trunk/glovebox rules, NPC robbery/loot and placement Client + Server config/world.lua Ground/drop distances, capacities and world animations Client + Server config/items.lua Hand props, fallback props, back weapons and item-use animations Client + Server config/rarities.lua Rarity levels, colors and presentation Client + Server config/ui.lua Inventory UI, hotbar and received-item slot feedback Client + Server config/stashes.lua Static stash definitions Client + Server config/locales.lua Locale fallback/path and translation helpers Client + Server config/admin.lua ACE names, direct license fallback and Admin Studio roles Server only Load order The order in fxmanifest.lua is intentional. config/inventory.lua loads before config/vehicles.lua because the vehicle registry reuses the base trunk/glovebox limits. config/core.lua loads first and initializes Config. Do not move config/admin.lua into shared_scripts. It may contain FiveM license identifiers and is intentionally loaded only in server_scripts before server/bridge/permissions.lua. Recommended Scripts visibility Nord Lab owns the contents of the Recommended Scripts catalog in protected server source. Server owners can only control whether the read-only button is visible: -- config/core.lua Config.Ecosystem = { Debug = false, MaxImageBytes = 2 * 1024 * 1024, ShowRecommendedScripts = true } Set ShowRecommendedScripts = false to hide the button and prevent the catalog payload from being sent to the Admin Studio NUI. This does not expose or allow editing the Nord Lab catalog. Admin access Edit config/admin.lua for ACE and optional license fallback: Config.AdminAccess = { UseAce = true, Ace = 'nord_inventory.admin', LicenseFallback = true, Licenses = { -- 'license:0123456789abcdef0123456789abcdef01234567', } } The file remains owner-editable in Asset Escrow but is never shared with clients by the manifest. Bridge selection Edit config/bridges.lua: Config.Notify = 'nord_inventory' Config.TextUI = 'nord_inventory' Config.Target = 'auto' Changing one bridge does not change the others. Framework bridge Choose the framework in config/core.lua: Config.Framework = 'auto' Available values are auto, qb, qbox, esx, nord, standalone, and custom. The implementation is split under server/bridge/framework/; those files remain owner-editable in Asset Escrow. For an unsupported framework, set: Config.Framework = 'custom' and implement the small adapter contract in server/bridge/framework/custom.lua. Do not modify the inventory engine for framework compatibility. Received item feedback Edit config/ui.lua: Config.ItemNotifications = { Enabled = true, Receive = true, Duration = 1800, MaxVisible = 8 } Source item definitions Item, weapon, vehicle and category reference definitions remain in shared/ because they are data registries rather than runtime settings. They are still owner-editable through escrow_ignore. Complete PT / EN locale system Language is selected in config/locales.lua: Config.Locale = 'pt' -- pt | en Config.LocaleFallback = 'en' Both locales/en.json and locales/pt.json contain: notifications: shared client/server notifications; nui: Admin Studio and player NUI text; patterns: dynamic UI phrases with counters/names; server: integration-specific server messages. The loader checks both notifications and server for L('key'). The NUI also performs a localeReady handshake after loading, so the selected locale is resent even if the browser missed the first early NUI message. When adding a new visible UI string, add the English source string as a key in both nui tables. Keep EN/PT key parity. Empty weapon equip behavior By default, an equipped firearm stays in the player's hands when its magazine reaches zero. Config.WeaponAmmo.KeepEquippedWhenEmpty = true FiveM/GTA may automatically select WEAPON_UNARMED after the last shot. Nord Inventory immediately restores the same empty weapon and keeps its inventory equip state active. The weapon is only holstered when the player uses/clicks the same weapon item again. This preserves the normal inventory equip/unequip toggle. Set the option to false to restore the older automatic unarmed behavior. Default weapon reload mode The default reload mode for new/reset player preferences is Manual. R -> request a reload Automatic reload is still available in Personal Studio under the weapon reload setting. Existing players who already saved automatic keep that preference; this change only changes the default/fallback. Automatic reload timing Automatic reload is intentionally slower than manual reload. Config.WeaponAmmo.AutoReloadDelay = 1400 Config.WeaponAmmo.AutomaticReloadPrepareTime = 900 The automatic flow is: magazine reaches 0 → wait 1.4 s → server approves/removes compatible ammunition → keep weapon empty for another 0.9 s → play the native weapon reload → rounds become available Manual R reload and directly using an ammunition item do not use the extra automatic preparation delay. Default Personal Studio layout The default player inventory layout now matches the compact transparent preset used by the project reference layout: Accent: cyan (#59c7ff) Columns: 5 Panel opacity: 62% Header opacity: 68% Slot opacity: 54% Border opacity: 7% World shade: 12% Panel gap: 22 Slot gap: 6 Item scale: 61% These are the defaults for players without saved Personal Studio preferences and for reset/default states. Players with existing saved preferences keep their own layout until they reset/change it. Metadata label override Nord Inventory follows the OX-style per-instance label behavior. When an item instance contains: metadata = { label = 'teste' } the player sees teste as that item's name everywhere in the player inventory: inventory grid; Fast Slots / hotbar; Special Slots; drag preview; item information modal; context menu; receive/use/give item pulse; ground label for a single dropped item. The base item definition label is preserved internally as baseLabel, while name remains the canonical internal/spawn identifier. Example: name = nr_food baseLabel = Comida de Restaurante metadata.label = teste Visible player label = teste If metadata.label is missing or empty, Nord falls back to the normal item definition label. Hide metadata details from players Each item definition can hide all metadata information cards from the player: hideMetadataDetails = true This never deletes or changes the metadata itself. Scripts and integrations keep receiving the complete metadata normally. Presentation metadata is separate: metadata = { label = 'Fresh Burger', image = 'fresh_burger.png', recipeId = 'secret_481', restaurant = 'cute_cafe' } With hideMetadataDetails = true, the player still sees Fresh Burger and fresh_burger.png, but recipeId, restaurant and the remaining metadata are not shown in the item information modal. metadata.label and metadata.image are never rendered as metadata detail cards. The existing per-field Player Info switches still work whenever the master hide option is disabled. Metadata privacy default Metadata details are now hidden by default for all items. No definition is required to hide metadata: ['my_item'] = { label = 'My Item' } To make metadata detail cards visible for a specific item: ['my_item'] = { label = 'My Item', hideMetadataDetails = false } metadata.label and metadata.image are presentation metadata and keep working in both modes. Player capacity self-repair Player inventories cannot use a zero slot/weight capacity. If an old integration or database row contains slots <= 0 or max_weight <= 0, Nord automatically restores: Config.DefaultPlayerSlots Config.DefaultPlayerWeight For maintenance/debugging: local ok, result = exports['nord_inventory']:RepairInventoryCapacity(playerId) The export also cleans invisible invalid/zero-count runtime rows and immediately saves the repaired persistent inventory. Current correction: item feedback For {VERSION}, Config.ItemNotifications uses Duration and MaxVisible; older QueueGap/MaxQueue examples are obsolete. Operations / Forensics New in v2.0.0, config/operations.lua controls the Operations Center limits and behavior. Missing movement-policy fields mean allow. ClothingBridge.Enabled is false by default for backwards compatibility. See Database, Security & Operations → Operations Configuration & Limits for the complete current structure. Commands & Default Keybinds Commands & Default Keybinds Quick operational reference. Applies to: Nord Inventory v2.0.0 Purpose Default Open inventory TAB / /inventory Quick hotbar Z / /hotbar Fast Slots 1– 5 Hands up X / /handsup Search interaction E (default interaction) Rob interaction G Manual weapon reload R Admin Studio /norditems Admin command aliases are fully configurable in config/commands.lua. SQL Table Map SQL Table Map Fast lookup of persistent table responsibilities. Applies to: Nord Inventory v2.0.0 Table Main purpose nord_inventory_storage persisted inventories/storage nord_inventory_custom_items DB-authoritative item definitions nord_inventory_item_versions definition version/history support nord_inventory_disabled_reference_items disabled built-in/reference items nord_inventory_custom_categories custom categories nord_inventory_preferences player preferences nord_inventory_transactions transaction/history records nord_inventory_vehicle_categories vehicle category capacity overrides nord_inventory_vehicle_models model-specific vehicle overrides nord_inventory_audit_log administrative audit trail nord_inventory_backups Nord backup metadata/data nord_inventory_admin_access persisted runtime admin grants | nord_inventory_snapshots | Operations inventory snapshots and restore payloads | | nord_inventory_forensics_alerts | persisted Anti-Dupe/forensics alert history | | nord_inventory_placed_items | persistent world-placement registry/coordinates | Production File Map Production File Map Where to look for configuration, integrations and public reference material. Applies to: Nord Inventory v2.0.0 nord_inventory/ ├── config/ owner configuration ├── locales/ EN/PT locale JSON ├── shared/ public/shared registries and definitions ├── client/bridge/ client compatibility providers ├── server/bridge/ server compatibility/access providers ├── client/core/ client runtime ├── server/core/ authoritative server core ├── client/modules/ client public API modules ├── server/modules/ admin/commands/vehicles/public SDK ├── web/ player + Admin Studio NUI ├── docs/ source reference notes ├── sql/ schema ├── fxmanifest.lua └── server.cfg.example Recommended Script Entry Schema Recommended Script Entry Schema Developer-only schema for Nord Lab curated entries before publishing a build. Applies to: Nord Inventory v2.0.0 { name = 'Script Name', resource = 'resource_name', developer = 'Developer', status = 'Verified', integration = 'Native', -- or Compatible / future category notes = 'Short explanation.', url = 'https://example.com', -- optional shorthand links = { -- optional, max four safe links after sanitization { label = 'Store', url = 'https://example.com/store' }, { label = 'Documentation', url = 'https://example.com/docs' } } } The catalog is intentionally local to the protected server ecosystem module. It has no runtime write endpoint. Developer-level inherited links In v2.0.0 the protected ecosystem module also maintains a developer link registry. Current profiles: ['Nord Lab'] = { { label = 'Store', url = 'https://nord-lab.tebex.io/' }, { label = 'Documentation', url = 'https://documentation.lunarocketeer.com/books/' } } ['Renovax Scripts'] = { { label = 'Store', url = 'https://renovax-scripts.tebex.io/' }, { label = 'Documentation', url = 'https://renovax-scripts.gitbook.io/renovax-scripts-docs' } } A recommendation whose developer matches a profile inherits those destinations automatically. Entry-specific links remain optional and are sanitized/deduplicated together. Public API vs Internal Events Public API vs Internal Events What third-party integrations are expected to call. Applies to: Nord Inventory v2.0.0 Supported integration surface documented exports; configuration files intended for server owners; provider SDK registration functions; explicit bridge/custom provider points. Do not depend on NUI callback names; internal net events not documented as public; direct writes to Nord tables; internal module globals/functions; protected implementation details. This separation lets Nord change internals without forcing every integrated script to update. Downloadable Reference Files Downloadable Reference Files Files attached to this BookStack page after import. Applies to: Nord Inventory v2.0.0 This portable BookStack package includes these attachments: nord_inventory_v2.0.0_owner_reference.zip — open/owner-editable configuration, locales, shared registry, documentation references, manifest and release validation files. It intentionally excludes protected runtime client/server/web implementation. nord_inventory.sql — current database schema shipped with v2.0.0. server.cfg.example — ACE/startup example shipped with the resource. COMPLETE_EXPORT_INDEX.txt — generated export/reference index for the documented API surface. MANIFEST.json — documentation package manifest for v2.0.0. The reference ZIP intentionally does not contain the protected server runtime implementation.