Nord Inventory v1.6.11 Official Nord Lab documentation for Nord Inventory v1.6.11, covering installation, secure admin access, Admin Studio, weapon magazine ammunition, vehicle storage, Nord Staff integration, developer API and production operations. Welcome · Nord Inventory v1.6.11 Nord Inventory is Nord Lab's production-ready, server-authoritative inventory system for FiveM. It combines a modern dual-inventory interface with a complete in-game administration workflow, persistent database-backed item definitions, vehicle storage management, universal metadata, weapon ammunition control and a broad integration API for other resources. Why Nord Inventory Complete slot inventory with configurable slots and weight limits. Server-authoritative movement, use, metadata, ammunition and persistence. Admin Studio for item creation, categories, lifecycle, imports/exports and Vehicle Storage. Personal Studio for player-side layout and reload preferences. Trunks and gloveboxes with category/model-specific capacity. Addon vehicle trunk detection, placement overrides and no-trunk protection. Ground drops with physical props, pickup, place and throw actions. Container items, stashes, metadata schemas, durability and expiration. Five Fast Slots plus a standalone no-focus hotbar. Weapon magazine ammunition stored per weapon instance. Automatic/manual Nord-managed reload modes. Runtime item prop fallback with calibrated hand attachments. Framework support for ESX, QBCore, Qbox, Nord Core and standalone. Nord Staff integration through the Nord Inventory bridge/API. 52 server exports and 11 client exports for third-party scripts. v1.6.11 headline The 1.6.11 release adds a secure server-only administrator license fallback. Admin access is resolved in this order: Server console. ACE permission. Configured FiveM license: identifier fallback. The license list lives only in server/config.lua, which is never loaded client-side. Resource identity Keep the resource directory named: nord_inventory The examples throughout this book assume that resource name. Quick Start This is the shortest path to a working Nord Inventory installation. 1. Requirements FiveM server with OneSync. MySQL or MariaDB. oxmysql. Optional framework: ESX, QBCore, Qbox or Nord Core. 2. Install and start Place the resource as nord_inventory and use a safe start order: ensure oxmysql # ensure qb-core # or es_extended / qbx_core / nord-core ensure nord_inventory # ensure nord_staff # when used 3. Configure admin access ACE is checked first: add_ace group.admin nord_inventory.admin allow If ACE is unavailable, add trusted FiveM licenses server-side only: -- nord_inventory/server/config.lua Config.AdminAccess.Licenses = { 'license:0123456789abcdef0123456789abcdef01234567', } You can also paste only the hash; Nord automatically adds the license: prefix. 4. Choose the framework and locale Config.Framework = 'auto' -- auto | esx | qb | qbox | nord | standalone Config.Locale = 'en' -- en | pt 5. Test in game Action Default Open inventory TAB or /inventory Show Fast Slots Z Use Fast Slots 1– 5 Admin Studio /norditems Trunk /trunkinv Glovebox /gloveboxinv 6. First production checks Add an item and reconnect to verify persistence. Open Admin Studio with ACE or license fallback. Open a trunk and glovebox on an unlocked vehicle. Equip a firearm and verify magazine metadata/reload behavior. Test a usable item with an explicit prop and one using prop fallback. If using nord_staff, start Nord Inventory first and verify its inventory bridge detects nord_inventory. What’s New · v1.6.11 This page summarizes the important changes since the v1.6.8 prop-fallback release. v1.6.11 · Admin license fallback Added a server-only administrator access configuration in server/config.lua. Admin access now resolves console → ACE → FiveM license fallback. Default ACE object is now correctly nord_inventory.admin. License entries accept the full license: identifier or just the hash. Admin license identifiers are never sent to or loaded by clients. v1.6.10 · Ammo and magazine visual behavior Ammo and magazine items no longer spawn hand props. Fallback/world-model props are also suppressed for ammunition semantics. Successful Nord magazine reloads restore the native equipped-weapon reload animation. Reload transactions remain server-authoritative and consume only the rounds required. v1.6.9 · Server-authoritative magazine ammunition metadata.ammo now means rounds currently loaded in the magazine, not total reserve ammunition. metadata.magazineSize is the authoritative magazine capacity for each weapon instance. Reserve ammunition always stays as normal inventory items until a reload consumes it. Reload removes exactly the rounds needed to fill the magazine. Client ammo synchronization is decrease-only on the server. Added Automatic and Manual reload modes to Personal Studio. Manual mode uses R; automatic mode requests a reload when the magazine reaches zero. GTA hidden reserve/autoreload behavior is suppressed while Nord controls the weapon. Pre-1.6.9 weapon metadata with excess reserve ammo is migrated back to inventory ammunition whenever possible. Weapon durability remains shot-based; reloads do not consume durability. Still included from v1.6.8 The runtime item prop fallback remains active. Priority is: Explicit use.prop. worldModel. Keyword rule. Category mapping. Generic fallback. Ammo and magazines are intentionally excluded from that visual fallback as of v1.6.10. 1 · Setup & Access Install Nord Inventory, choose a framework, configure administrator access and set the core runtime options. Requirements & Installation Requirements Requirement Status FiveM / OneSync Required MySQL or MariaDB Required oxmysql Required ESX / QBCore / Qbox / Nord Core Optional ox_lib Not required Target resource Optional Nord Inventory can use its own Text UI, so a target resource is not mandatory. Resource installation Copy nord_inventory to your resources folder. Make sure oxmysql is available and started first. Keep the resource folder named exactly nord_inventory. Add the ACE permission for admins. Ensure the resource in server.cfg. add_ace group.admin nord_inventory.admin allow ensure oxmysql ensure nord_inventory Database setup On startup, Nord Inventory creates/migrates its tables. You can also run the provided sql/nord_inventory.sql manually. The main tables are: nord_inventory_storage nord_inventory_custom_items nord_inventory_item_versions nord_inventory_custom_categories nord_inventory_preferences nord_inventory_transactions nord_inventory_vehicle_categories nord_inventory_vehicle_models Startup order A safe example: ensure oxmysql ensure qbx_core # or qb-core / es_extended / nord-core when used ensure nord_inventory Framework resources should normally be started before Nord Inventory so Config.Framework = 'auto' can detect them during initialization. First boot verification Check the server console for the framework bridge line: [nord_inventory] Framework bridge: qb The final value can be qb, esx, qbox, nord or standalone. Framework Detection Set the framework mode in config.lua: Config.Framework = 'auto' -- auto | esx | qb | qbox | nord | standalone Auto-detection order When set to auto, Nord checks resources in this order: qbx_core → Qbox qb-core → QBCore es_extended → ESX nord-core → Nord Core Nothing matched → standalone Player identifiers Nord uses a stable identifier appropriate to the active bridge: Framework Identifier basis QBCore citizenid ESX player identifier Qbox citizenid Nord Core citizenid/identifier when available Standalone fallback FiveM license: identifier, then first identifier Jobs and restricted storage Job access checks use the framework job name and numeric grade. Example: jobs = { police = 0, sheriff = 2 } A player must have a listed job and a grade greater than or equal to the configured minimum. Hunger and thirst QBCore: updates player metadata hunger/thirst. ESX: uses esx_status:add for hunger/thirst. Other modes: emits nord_inventory:server:consume so a custom framework can react. Health/armor effects are applied by Nord on the client after server validation. Forcing standalone mode If you use a custom framework and want Nord to avoid detecting a supported framework: Config.Framework = 'standalone' You can then integrate your own status/identity systems around Nord's public exports and events. Admin Access · ACE + License Fallback Nord Inventory v1.6.11 supports two administrator authorization methods without exposing license identifiers to the client. Access order The server resolves admin access in this order: Console — server console commands are trusted. ACE — checks the configured ACE object. License fallback — checks the player's FiveM license: identifier against the private allowlist. ACE configuration The default ACE object is: Config.AdminAce = 'nord_inventory.admin' Recommended server.cfg: add_ace group.admin nord_inventory.admin allow You can assign a license to a group through ACE if you prefer central permission management: add_principal identifier.license:YOUR_LICENSE group.admin Direct license fallback Edit only: nord_inventory/server/config.lua Example: Config.AdminAccess = { UseAce = true, Ace = Config.AdminAce or 'nord_inventory.admin', LicenseFallback = true, Licenses = { 'license:0123456789abcdef0123456789abcdef01234567', '89abcdef0123456789abcdef0123456789abcdef', -- hash-only is accepted } } Security notes server/config.lua is listed only under server_scripts. Admin license identifiers are never loaded client-side. Keep the license list out of shared config files and NUI JavaScript. ACE remains the preferred method when you already manage staff groups centrally. The fallback is useful when ACE is unavailable, misconfigured or intentionally not used. Admin Studio The default command is: /norditems Admin commands use the same access resolution, so ACE and license fallback apply consistently. Admin Commands All commands in Config.AdminCommands require Nord Inventory admin access. They can be renamed or have aliases removed in config.lua. Default command Purpose /giveitem / /nordgiveitem Give an item to a player /givecash / /nordgivecash Give cash currency item /givedirtymoney / /nordgivedirtymoney Give dirty-money currency item /removeitem / /nordremoveitem Remove an item by name /removeslot / /nordremoveslot Remove from a specific slot /clearinventory / /clearinv Clear all or one item type /openinventory / /openinv Open another player's inventory as admin /setmetadata / /setmeta Replace metadata on a slot /setdurability / /repairitem Set/repair durability /itemcount Count an item in a player's inventory /iteminfo Show item and metadata for a slot /saveinventory / /saveinv Force-save a player inventory /listitems Search the active item registry Example metadata command /setmetadata 12 4 {"quality":"premium","serial":"NORD-001"} Disable command set Config.AdminCommands.Enabled = false The Admin Studio can remain available even if you choose to disable these convenience commands. Core Configuration The complete configuration is in config.lua. The values below are the defaults shipped with v1.6.11. General Config.Framework = 'auto' Config.Locale = 'en' Config.Debug = false Config.OpenCommand = 'inventory' Config.OpenKey = 'TAB' Config.AdminCommand = 'norditems' Config.AdminAce = 'nord_inventory.admin' Inventory capacity defaults 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 Weights are stored in grams in the default configuration. Sessions and persistence 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 UI defaults Config.UI = { theme = 'dark', columns = 7, slotSize = 'medium', showWeight = true, animations = true, hotbarSlots = 5, hotbarKeybinds = true } Standalone hotbar Config.Hotbar = { Enabled = true, Command = 'hotbar', OpenKey = 'Z', Mode = 'timed', -- timed | toggle Duration = 3200, ShowOnSlotUse = false } Ground inventory Config.GroundOpenDistance = 3.0 Config.GroundDrawDistance = 15.0 Config.GroundPropDistance = 35.0 Config.GroundDefaultModel = 'prop_cs_cardbox_01' Config.GroundLifetimeSeconds = 1800 Config.GroundSlots = 30 Config.GroundWeight = 250000 Config.ThrowMaxDistance = 8.0 Config.ThrowMaxHeightDifference = 4.0 See the dedicated Vehicle Storage and Interaction pages for nested vehicle/target settings. Weapon magazine configuration added in v1.6.9+ Config.WeaponAmmo = { Enabled = true, DefaultMagazineSize = 30, MaxMagazineSize = 999, DetectMagazineFromGame = true, AutoReloadDelay = 260, ReloadCooldown = 650, ManualReloadControl = 45, } DefaultMagazineSize is only a bootstrap fallback until the weapon instance has authoritative metadata.magazineSize. Interaction Providers Nord can use its own Text UI or a target resource for ground items, configured stashes and vehicle trunks. Built-in Text UI Default configuration: Config.Interaction = { Mode = 'textui', TextUI = 'default', Target = 'auto', Key = 'E', Control = 38, OxLibPosition = 'right-center' } TextUI = 'default' uses Nord's built-in UI and has no ox_lib requirement. ox_lib TextUI Switch the Text UI provider without changing interaction mode: Config.Interaction.Mode = 'textui' Config.Interaction.TextUI = 'ox_lib' Target mode Config.Interaction.Mode = 'target' Config.Interaction.Target = 'auto' Supported target choices in the bridge are: auto ox_target qb-target nord_target If a selected/auto-detected target provider is unavailable, Nord can continue using its own interaction fallback where implemented. Custom Text UI bridge Config.Interaction.TextUI = 'custom' Config.Interaction.Custom = { Show = function(data) -- show your UI end, Hide = function() -- hide your UI end } The callbacks run client-side. Locales Nord Inventory v1.6.11 ships with: locales/en.json locales/pt.json (Portuguese, PT-PT) Select the active locale: Config.Locale = 'en' -- Config.Locale = 'pt' Fallback behavior: Config.LocaleFallback = 'en' Config.LocalePath = 'locales' What the locale system covers The dictionaries cover the player inventory, Admin Studio, Personal Studio, item management, vehicle storage, imports/exports, context menus, world interactions, use progress text, server notifications and command/admin feedback. Item-specific text is preserved Item labels, descriptions and runtime-created custom text are treated as item data, not as generic interface translation keys. Nord does not automatically rewrite an item label just because the UI locale changes. Missing keys English is used as a fallback when the selected locale does not contain a key. 2 · Player Experience Player inventory UI, hotbar, ground interactions, containers, metadata and Personal Studio. Inventory UI & Dual Inventory Nord uses a dual-inventory layout. Left: the player's own inventory. Right: the currently active contextual inventory. The right side can represent: Type Typical use Ground Nearby world drops stash General persistent storage chest / safe Resource-defined storage society Job/company storage evidence Police/evidence storage locker Restricted locker storage trunk Vehicle trunk/front trunk glovebox Vehicle glovebox container Backpack/bag contents custom External resource-defined inventory All of these use the same server-authoritative transfer engine. Opening behavior On foot, TAB/ /inventory opens the player inventory with Ground as the secondary context. Inside a vehicle, TAB opens the glovebox by default: Config.VehicleInteraction.TabInsideVehicle = 'glovebox' Possible values include glovebox, player or false. Player actions Depending on the item and context, the item action menu can provide actions such as: Use Give Put on ground Throw/place Split Pin to Fast Slot Unpin Open container View item information/metadata Server-side checks still decide whether the requested action is allowed. Fast Slots & Hotbar Nord reserves the first five inventory slots as Fast Slots when the default configuration is used. Config.UI.hotbarSlots = 5 Config.UI.hotbarKeybinds = true Pinning behavior Fast Slots are real player inventory slots. When an item is pinned there, Nord prevents normal dragging, splitting, transferring or swapping of that pinned item until the player explicitly unpins it. This avoids accidental movement of the item assigned to a keyboard shortcut. Keybinds 1 → Fast Slot 1 2 → Fast Slot 2 3 → Fast Slot 3 4 → Fast Slot 4 5 → Fast Slot 5 Internally, the registered commands are nordslot1 through nordslot5, so FiveM key mapping can be changed by the player/server keybind system. Standalone hotbar The separate hotbar does not take NUI focus, allowing the player to keep moving. Config.Hotbar = { Enabled = true, Command = 'hotbar', OpenKey = 'Z', Mode = 'timed', Duration = 3200, ShowOnSlotUse = false } Mode = 'toggle' keeps it visible until toggled again. Ground Items, Pickup & Throw Items moved to Ground become real server-synchronized ground drops with local world props. Default distances Config.GroundOpenDistance = 3.0 Config.GroundDrawDistance = 15.0 Config.GroundPropDistance = 35.0 Config.ThrowMaxDistance = 8.0 Config.ThrowMaxHeightDifference = 4.0 World model resolution An item can define its dropped prop using worldModel: worldModel = 'prop_cs_documents_01' If an item has no valid world model, Nord uses: Config.GroundDefaultModel = 'prop_cs_cardbox_01' Single-item pickup A simple ground drop containing one item can be picked up directly using the interaction key rather than requiring the full inventory to open. Multi-item ground inventory When a ground drop contains multiple items, Nord opens the ground inventory as the right-side inventory. Throw/place flow The throw action uses a local physics prop for the animation/flight, then the server stores the final validated landing position. This provides a natural world placement while keeping the actual inventory state server-authoritative. Default animations Config.GroundAnimations = { Pickup = { dict = 'pickup_object', clip = 'pickup_low', duration = 850 }, PutDown = { dict = 'pickup_object', clip = 'pickup_low', duration = 850 }, Throw = { dict = 'anim@mp_snowball', clip = 'throw_snowball', duration = 760, release = 360, settleTimeout = 2200, flag = 48 } } Container Items & Backpacks An item definition can itself provide storage. ['backpack'] = { label = 'Backpack', weight = 900, type = 'container', stack = false, unique = true, container = { slots = 20, maxWeight = 25000 } } Important behavior Container items are intended to be unique/non-stackable. The contained inventory is identified from the specific item instance. Nord prevents direct container cycles, such as placing a bag inside its own inventory. Config.MaxContainerDepth limits recursive nesting. Default: Config.MaxContainerDepth = 3 Opening a container from the client API For the local player's bag slot: exports.nord_inventory:openInventory('container', playerBagSlot) Server-side opening exports.nord_inventory:OpenInventory(source, 'container', playerBagSlot) The server-side form is preferred when access depends on trusted resource logic. Metadata, Durability & Expiration Nord stores arbitrary item metadata per item instance. Metadata defaults metadataDefaults = { battery = 100, ownerName = '', quality = 100 } Metadata can also be supplied when adding an item: exports.nord_inventory:AddItem(source, 'phone', 1, { number = '555-0102', battery = 84 }) Durability durability = { initial = 100, lossPerUse = 4 } Shorthand: durability = 4 -- lose 4% per successful use Durability makes the item unique/non-stackable. For normal items, wear is applied after a successful use. At zero durability, the item is destroyed unless destroyAtZero = false. Firearms For firearms, lossPerUse is treated as wear per fired round. Equipping, holstering and reloading do not consume firearm durability. Expiration expiry = { seconds = 48 * 60 * 60 } Shorthand: expiry = 86400 -- 24 hours New instances receive a server timestamp. Expired items are pruned when inventories are loaded/opened and during normal cleanup, including items that expired while the player was offline. Storage format Lifecycle state lives in the item's metadata JSON, so durability/expiry does not require a separate item-instance SQL table. Personal Studio Players can customize the presentation of their own inventory without changing Admin Studio or server item definitions. The customization UI includes areas such as: Appearance. Layout. Icon color. Border visibility. Fast Slots width. Lifecycle/condition bar visibility. Adaptive lifecycle colors. Validity/expiry response. Glow and opacity controls. Healthy, medium, low and critical colors. Persistence Player preferences are stored in: nord_inventory_preferences Preferences are keyed by the player's resolved identifier. Separation from item logic Personal Studio only changes how the inventory is presented for that player. It does not change: actual item durability; item expiration; weight; metadata; item definitions; Admin Studio styling. Weapon reload preference v1.6.9+ adds a player preference for firearm reload behavior: Manual — the player presses R to request a Nord magazine reload. Automatic — when the loaded magazine reaches zero, Nord requests a refill after the configured delay. The preference changes when the reload is requested; the server still decides how many rounds can be consumed and loaded. 3 · Admin Studio & Items Manage the item registry, categories, use actions, prop fallback, metadata, lifecycle and imports. Admin Studio Overview Open Admin Studio with: /norditems The request is checked server-side using the configured ACE permission. Workspaces Admin Studio v1.6.11 includes: Dashboard — registry totals and quick actions. Items — folder/category-first item registry and item management. Vehicle Storage — category/model capacities, trunk and glovebox settings, addon placement. Imports / Exports — migration tools for item definitions. Registry model Nord has three practical definition sources: Database-backed definitions in nord_inventory_custom_items. Reference definitions from shared/items.lua / shared/weapons.lua when no DB row exists. Transient runtime definitions registered by trusted resources. For a matching item name, a database row is authoritative. Base item editing Editing a reference/base item in Admin Studio creates a database override. Nord does not rewrite the Lua reference file. Reverting the item removes the DB override so the reference definition becomes active again. Item Registry & Categories The Items workspace uses a folder-style explorer. Built-in categories The package defines categories including: ID Label generic General food Food drink Drinks medical Medical weapon Weapons ammo Ammunition tool Tools document Documents evidence Evidence container Containers clothing Clothing key Keys Runtime categories Admins can create categories/folders from Admin Studio. Runtime categories are persisted in: nord_inventory_custom_categories A custom category can have: internal name; display label; Font Awesome icon; sort order. Custom categories can be renamed or deleted. When a custom category is deleted, custom items assigned to it are moved safely to generic. Built-in/base categories remain protected. Moving items between folders Custom/database-backed items can be moved between categories from the registry. Reference/base files themselves are not modified. Creating & Editing Items Admin Studio provides a Quick Create flow and a more detailed Item Management editor. Core fields A normal definition can include: name/internal ID; label; description; weight; volume; stack behavior; close-on-use behavior; category; image; schema; unique flag; metadata defaults/schema/display rules; container settings; consume effects; use settings; weapon settings; durability; expiration; world model. Simple item example ['repairkit'] = { label = 'Repair Kit', description = 'Basic vehicle repair tools', weight = 1800, image = 'repairkit.png', type = 'tool', stack = true, close = true, prop = 'prop_tool_box_04', use = { duration = 5000, allowMove = false, cancelable = true, remove = 0 } } type is a friendly input preset. Nord expands supported simple types into the internal category/schema/use defaults. Supported simple presets include food, drink, medical, weapon, container, ammo, tool, object and generic. Images Local item images are resolved relative to: web/images/items/ An item can also use an http:// or https:// image URL for display. Trusted events vs Admin-created items Database items created/edited from Admin Studio are sanitized so arbitrary clientEvent and serverEvent values are not stored. For custom resource logic, use RegisterUsableItem, hooks or trusted server-side integration code instead. Item Use & Prop Fallback Explicit use configuration use = { duration = 2500, allowMove = true, cancelable = true, remove = 1, actionText = 'Drinking {item}', animation = { dict = 'mp_player_intdrink', clip = 'loop_bottle', flag = 49 }, prop = { model = 'prop_ld_flow_bottle', bone = 60309, pos = { x = 0.03, y = 0.03, z = 0.02 }, rot = { x = 0.0, y = 0.0, z = -1.5 }, rotOrder = 0 } } Automatic hand-prop fallback v1.6.11 adds a fallback when a usable item has no explicit hand prop. Config.ItemPropAttachments.Fallback = { Enabled = true, PreferWorldModel = true, Generic = 'prop_cs_cardbox_01', Categories = { ... }, Keywords = { ... } } Resolution priority: Explicit item use.prop. Item worldModel when PreferWorldModel = true. First matching keyword rule. Category fallback. Generic fallback. Built-in keyword examples The default rules cover common names for: phones; radios/walkie-talkies; documents/paper/contracts; cards/licenses/badges; medical items; tools/repair items; jewellery; common bagged drug item naming. Important The fallback is computed at runtime and does not save the chosen prop into the item definition or database. Known model calibration Config.ItemPropAttachments.Models provides attachment calibration for known props so common items use stable hand offsets. v1.6.10 ammo/magazine exception Ammo and magazine items intentionally do not spawn a hand prop, including props that would otherwise be selected through worldModel or the runtime fallback system. Their visual feedback comes from the equipped weapon reload animation instead. The server remains authoritative for the ammunition transaction; the visual animation does not grant or consume rounds by itself. Metadata Editor Nord supports arbitrary metadata while still allowing the item definition to describe expected fields. Defaults metadataDefaults = { battery = 100, owner = '', activated = false } These values can be hydrated into new/reconciled item instances. Metadata schema Admin Studio can build a metadata schema so common fields have known input/display behavior. Typical field concepts include: field name; type; default value; whether the field should be visible to the player. Metadata display rules metadataDisplay controls visibility of metadata keys in the player-facing item information view. Nord protects internal keys. Integration exports also strip keys beginning with __nord from public metadata output. Updating metadata through exports exports.nord_inventory:SetMetadata(source, 4, { battery = 65, owner = 'Ricardo' }) Patch selected fields: exports.nord_inventory:UpdateMetadata(source, 4, { battery = 64 }) Read: local metadata = exports.nord_inventory:GetMetadata(source, 4) Lifecycle Editor The Item Management Lifecycle page controls durability and shelf life. Durability fields Enabled. Starting durability. Loss per successful use. Healthy bar color. Destroy at zero behavior in the normalized definition. Enabling durability automatically forces the item to unique/non-stackable behavior and prevents normal remove = 1 consumption from bypassing wear. Expiration fields Enabled. Duration value/unit in the Admin UI. Expiry color. Internally, expiration is stored as seconds and converted to an instance expiresAt timestamp. Base item overrides Lifecycle settings can be applied to a base/reference item through Admin Studio. Nord creates a DB-backed override and leaves the Lua reference untouched. Use Revert to base to remove the DB override and restore the file definition. Imports & Exports Admin Studio includes a migration workspace for item definitions. Import sources The client-side converter supports safe parsing/conversion flows for common formats including: Nord JSON. ox_inventory-style Lua item definitions. qb-inventory / QBCore-style Lua item definitions. Lua import is parsed as item data; the migration workflow is designed to avoid blindly executing imported Lua. Conflict handling The import flow analyzes items before creating them and supports conflict behavior such as skipping or overwriting existing runtime/custom definitions. Base-item protection and DB precedence remain in effect. Export scopes Exports can be generated for: runtime custom items only; the full active registry. Export formats The Admin tool can generate Nord registry output as JSON or Lua-compatible registry text for migration/backup workflows. Size guard The browser-side Admin import flow rejects an input file larger than 5 MB. This Admin Studio registry export is an item-definition migration feature. It is separate from database/server backups. DB-Authoritative Item Definitions Nord Inventory treats database-backed item definitions as authoritative by item name. Precedence A row in nord_inventory_custom_items wins for that item name. If no DB row exists, shared/items.lua and shared/weapons.lua act as reference/fallback definitions. A disabled DB row blocks fallback for that name. Startup behavior Current releases do not seed, rewrite or delete item definitions from the Lua reference files during normal startup. This prevents Admin Studio changes from turning into hybrid file/DB definitions after a restart. Saving from Admin Studio When an item is saved: the authoritative DB row is verified; runtime registry state is refreshed; connected player snapshots and open inventory sessions receive refreshed definitions; persisted item instances reconcile metadata defaults and lifecycle state where required. See the Downloadable Reference Files page for the bundled persistence and precedence notes when migrating or debugging. 4 · Weapons & Ammunition Server-authoritative magazine ammunition, reload modes, durability and weapon visuals. Weapon System Overview Nord Inventory stores weapons as normal inventory item instances with server-authoritative metadata. The inventory controls the equipped weapon lifecycle, ammunition transactions, durability and the cosmetic back-weapon system. Important weapon metadata Typical weapon instance metadata can include: { uid = '...', serial = '...', ammo = 12, magazineSize = 17, durability = 84.5, } Meaning of ammunition metadata From v1.6.9 onward: metadata.ammo = rounds currently loaded in the magazine. metadata.magazineSize = authoritative capacity of that weapon instance. reserve ammunition = separate inventory items. Nord does not keep a hidden reserve count inside the weapon metadata. Why this matters This prevents the common FiveM problem where the game engine and inventory both maintain separate reserve ammunition pools and repeatedly reload from stale state. Magazine Ammunition · Server Authority The v1.6.9 ammunition model treats the inventory as the authority for reserve rounds. Reload transaction When a reload is requested, the server calculates: needed = magazineSize - currentLoadedAmmo consumed = min(needed, reserveItemCount) newLoadedAmmo = currentLoadedAmmo + consumed Only consumed reserve rounds are removed from inventory. Example A pistol has: Magazine capacity: 17 Loaded rounds: 5 Reserve ammo item: 30 Nord removes 12 rounds from the ammo item and sets the weapon to 17 loaded rounds. The remaining 18 reserve rounds stay in the inventory. Client synchronization Client ammo reports are decrease-only from the server's point of view. A client cannot increase authoritative weapon ammo merely by reporting a larger GTA ammo value. First-use magazine detection If a weapon instance has no metadata.magazineSize, Nord can use the GTA native clip size as a first-use seed when: Config.WeaponAmmo.DetectMagazineFromGame = true Once stored, the metadata value is authoritative for that weapon instance. Manual & Automatic Reload Modes Reload mode is a player preference managed in Personal Studio. Manual The player presses R ( INPUT_RELOAD, control 45 by default). Nord requests a server reload transaction and only the required reserve rounds are consumed. Automatic When the loaded magazine reaches zero, Nord waits the configured delay and requests a refill automatically: Config.WeaponAmmo.AutoReloadDelay = 260 Duplicate protection Config.WeaponAmmo.ReloadCooldown = 650 The resource also uses reload locking, timeout recovery and shot/reload race protection to avoid duplicate consumption or repeated engine reload states. GTA reserve behavior While Nord controls an equipped firearm, hidden GTA reserve/autoreload behavior is suppressed so ammunition is not duplicated between the engine and inventory system. Ammo & Magazine Items · No Hand Props v1.6.10 intentionally removes hand-held props from ammunition and magazine use actions. Behavior No explicit hand prop is spawned for ammo/magazine use. worldModel does not force a hand prop for ammo semantics. Runtime prop fallback is bypassed for ammo/magazine semantics. After a successful Nord reload, the equipped weapon uses the native reload animation. This keeps the visual flow natural: the player reloads the weapon instead of briefly holding an unrelated ammunition prop. Server authority is unchanged Animation is cosmetic. The server still calculates magazine capacity, verifies reserve ammunition and removes only the rounds that fit. Weapon Durability & Back Display Durability per fired round For firearms, durability.lossPerUse is interpreted as durability loss per fired round. Equipping, holstering and reloading do not consume weapon durability. When a weapon reaches zero durability, Nord removes the broken item and immediately unequips it. Back weapon display Large weapons can be displayed cosmetically on the player's back: Config.BackWeapons = { Enabled = true, MaxVisible = 2, HideInVehicle = true, HideWhenDead = true, RefreshInterval = 750, ... } The back props are cosmetic only. Ammo, durability and ownership remain inventory state. Equipped weapon UIDs are excluded from the visible back set, and the display refreshes when equipping/holstering, entering vehicles or changing death state. 5 · Vehicle Storage Trunks, gloveboxes, Vehicle Storage Studio, addon placement, NPC loot and capacity exports. Vehicle Storage Overview Nord Inventory v1.6.11 manages trunk and glovebox capacity independently. Each vehicle/category can define: trunk max weight; trunk slots; glovebox max weight; glovebox slots. Capacity precedence For both weight and slots: Model-specific override. Vehicle category default. Nord fallback configuration. The effective values are re-resolved whenever the storage opens. Default fallback values Config.TrunkWeight = 120000 Config.TrunkSlots = 50 Config.GloveboxWeight = 15000 Config.GloveboxSlots = 10 Glovebox ideal weight Config.VehicleRegistry.GloveboxIdealWeight = Config.GloveboxWeight Admin Studio displays a warning when a glovebox is configured above this recommended value. The warning is informational and does not block saving. Safe slot reduction If capacity is reduced below the slots currently in use, Nord compacts items safely. When necessary, it retains enough effective slots to avoid hiding/deleting existing items. Vehicle Catalog & Capacity Registry Registry configuration Config.VehicleRegistry = { Enabled = true, AutoImportFramework = true, ScanGameVehicles = true, IncludeStreamedVehiclesWithFramework = false, AutoScanOnFirstAdminOpen = true, ... } Catalog sources Nord can populate its vehicle registry from: QBCore shared vehicles. Qbox vehicle exports. the common ESX vehicles table. an admin-side FiveM streamed/native vehicle scan. manually created model entries in Admin Studio. The native scan provides a framework-independent fallback and can discover streamed GTA/addon models. Storage tables Vehicle category settings are persisted in: nord_inventory_vehicle_categories Vehicle model settings/overrides are persisted in: nord_inventory_vehicle_models Capacity source Developer exports can report whether a value came from a model, category or fallback source. Trunk & Glovebox Behavior Direct commands /trunkinv /gloveboxinv Trunk interaction The default trunk interaction settings include: Config.VehicleInteraction.Trunk = { Enabled = true, Distance = 2.2, ScanDistance = 6.0, ServerDistance = 7.0, OpenDoor = true, CloseDoorOnInventoryClose = true, RearInventoryDelay = 80, FrontInventoryDelay = 420, ... } Locked vehicles Locked trunks are inaccessible. Nord hides the interaction and also revalidates access server-side when supported. Front vs rear storage Nord uses multiple automatic signals to decide whether a valid storage compartment is at the front or rear, including OX-style mappings/rules, vehicle flags, engine position and vehicle geometry. The physical hood/trunk animation is best-effort and does not become the authority for whether an inventory session can open. Vehicles with no trunk v1.6.7+ rejects vehicles classified as having no trunk before opening a trunk inventory. Admin placement also refuses to create a fake placement for a no-trunk vehicle unless an existing manual override is already authoritative for an addon model. Addon Trunk Placement Admin Studio can create a saved interaction placement for addon vehicles whose metadata/skeleton does not expose a reliable standard storage point. Placement assistant From the vehicle model editor, start Detect & place trunk. Nord attempts to: Resolve a valid physical trunk/bonnet side. Anchor the preview to the real boot/ bonnet panel when bones are available. Fall back to model dimensions for incomplete addon models. Show a green panel highlight plus a small editable interaction marker. Allow front/rear switching and X/Y/Z fine tuning. Save the placement to SQL. Default placement controls Config.VehicleRegistry.Placement = { Enabled = true, MaxDistance = 8.0, MoveStep = 0.012, FastMultiplier = 4.0, PanelWidthScale = 0.82, PanelHeightScale = 0.46, PanelDepthScale = 0.16, PanelFillAlpha = 48, PanelOutlineAlpha = 255, PanelMarkerScale = 0.11 } Stored data The model table can store: trunk_side_override; trunk_offset_x/y/z; trunk_door_override. A saved manual placement can make a valid addon trunk usable even when standard model metadata does not expose the expected panel. NPC Vehicle Trunk Loot Nord can optionally populate verified ambient/NPC vehicle trunks with one-time random loot. Enable/disable robbery Config.VehicleInteraction.NPC.AllowTrunkRobbery = true If disabled, NPC/ambient vehicle trunks cannot be opened. Default loot configuration RandomLoot = { Enabled = true, EmptyChance = 15, MinRolls = 1, MaxRolls = 4, Items = { { item = 'water', weight = 38, min = 1, max = 2 }, { item = 'burger', weight = 32, min = 1, max = 2 }, { item = 'bandage', weight = 18, min = 1, max = 2 }, { item = 'backpack', weight = 7, min = 1, max = 1 }, { item = 'weapon_pistol', weight = 1, min = 1, max = 1 } } } Safety rules Loot is generated once for the lifetime of that live network vehicle. Missing or disabled items are skipped. Ambient loot is ephemeral. It does not overwrite a persistent player-owned trunk. Locked trunks remain inaccessible and do not show the interaction. Vehicle Storage Exports Nord provides server exports for external resources that need to know the effective capacity of a vehicle. Full capacity result local capacity = exports.nord_inventory:GetVehicleStorageCapacity( 'trunk', GetHashKey('sultan'), 1 ) print(capacity.maxWeight) print(capacity.slots) print(capacity.weightSource) -- model | category | fallback print(capacity.slotsSource) -- model | category | fallback capacity includes: type maxWeight slots weightSource slotsSource vehicle category Dedicated exports local weight, source, vehicle = exports.nord_inventory:GetVehicleTrunkWeight(modelHash, vehicleClass) local slots, source, vehicle = exports.nord_inventory:GetVehicleTrunkSlots(modelHash, vehicleClass) local weight, source, vehicle = exports.nord_inventory:GetVehicleGloveboxWeight(modelHash, vehicleClass) local slots, source, vehicle = exports.nord_inventory:GetVehicleGloveboxSlots(modelHash, vehicleClass) 6 · Nord Staff & Developer API Nord Staff integration plus server/client exports, stashes, hooks and migration patterns. Nord Staff Integration Nord Inventory is designed to integrate with Nord Staff as part of the Nord Lab ecosystem. Integration model The integration is API/bridge based rather than a hard dependency inside nord_inventory. This means: Nord Inventory can run without Nord Staff. Nord Staff can use Nord Inventory for staff-side inventory operations when its inventory bridge is configured/detected as Nord. Inventory state changes remain server-authoritative inside Nord Inventory. No administrator license identifiers need to be exposed to Nord Staff or to the client. Recommended start order ensure oxmysql ensure nord_inventory ensure nord_staff If a framework is used, start it before Nord Inventory. Typical staff-side capabilities Through the Nord Inventory API, a staff system can perform operations such as: read a player's item count; give or remove items; check carry capacity; inspect slots and metadata; open inventory views through authorized server logic; update metadata or durability through trusted server actions. Example server-side operation: local canCarry = exports.nord_inventory:CanCarryItem(target, 'water', 2) if canCarry then exports.nord_inventory:AddItem(target, 'water', 2) end Permission separation Nord Staff permissions and Nord Inventory Admin Studio permissions are separate security layers. A user who is staff in another resource should only receive direct /norditems access when they also pass Nord Inventory's ACE/license rules. This separation prevents a client-side staff state from becoming inventory administrator authority. Integration API Overview Nord Inventory exposes a Nord-native API with familiar slot-inventory contracts so other FiveM resources need minimal inventory-specific code. Server vs client Use server exports for anything that changes inventory state or requires trusted access checks. Use client exports only for read-only access to the local player's lightweight inventory snapshot. Inventory identifiers Server exports accept several target forms: Player server ID ( source) as a number. Registered inventory ID such as mechanic_storage. Full Nord keys such as: stash:police_armory trunk:ABC123 glovebox:ABC123 In some internal/integration cases, a resolved inventory object/table. Metadata matching Metadata can be a table or a primitive value. Primitive values are normalized to: { type = value } Read/search helpers normally perform partial metadata matching. Helpers with a strict argument can require the complete metadata object to match exactly. Recommended integration rule Do not expose unrestricted client events that directly mutate inventories. Validate permissions/business logic in your server resource, then call Nord server exports. API size in v1.6.11 52 server exports including the five vehicle-capacity helpers. 11 client exports including the two OpenInventory aliases and nine read-only snapshot/search helpers. Use server exports for all authoritative mutations. Client exports should be treated as convenience/read-only snapshot helpers except for requesting the inventory UI to open. Server Exports · Catalog & Opening Inventory/catalog exports Export Purpose GetInventoryType() Returns nord_inventory GetItemDefinition(name) Get one definition GetItems() Public item registry list GetItemList() Alias-style public registry list Items(itemName?) Registry keyed by name or single definition ItemList(itemName?) Same familiar keyed shape RegisterItem(name, definition) Register a trusted transient runtime definition RegisterInventory(id, options) Register a runtime storage definition Opening inventories exports.nord_inventory:OpenInventory(source, inventoryType, id, options) Aliases: exports.nord_inventory:openInventory(...) exports.nord_inventory:forceOpenInventory(...) Supported opening types include: player container drop / ground stash society evidence locker custom chest safe Register on open exports.nord_inventory:OpenInventory(source, 'society', 'mechanic_society', { label = 'Mechanic Society', slots = 100, maxWeight = 300000, jobs = { mechanic = 0 } }) When options are supplied and that ID is not already registered, Nord can register it with the requested type before opening. Nearby player exports.nord_inventory:OpenInventory(source, 'player', targetServerId) Opening another player's inventory uses Nord's nearby-player access path rather than giving arbitrary remote access. Server Exports · Add, Remove & Carry AddItem local ok, result = exports.nord_inventory:AddItem( source, 'water', 2, { quality = 100 }, nil ) Signature: AddItem(target, itemName, amount, metadata?, slot?, callback?) On success, the returned result is public slot data. Common failure strings include invalid_inventory, invalid_item and inventory_full. RemoveItem local ok, reason = exports.nord_inventory:RemoveItem( source, 'water', 1, { quality = 100 }, nil, false, false ) Signature: RemoveItem(target, itemName, amount, metadata?, slot?, ignoreTotal?, strict?) Currency helpers Nord treats the default currency items as inventory items: exports.nord_inventory:AddCash(source, 500) exports.nord_inventory:RemoveCash(source, 250) exports.nord_inventory:AddDirtyMoney(source, 100) exports.nord_inventory:RemoveDirtyMoney(source, 50) These use the item names money and black_money. Carry checks local canCarry = exports.nord_inventory:CanCarryItem(source, 'water', 5) local fits, freeWeight = exports.nord_inventory:CanCarryWeight(source, 5000) local maxAmount = exports.nord_inventory:CanCarryAmount(source, 'water') local canSwap = exports.nord_inventory:CanSwapItem(source, 'water', 2, 'repairkit', 1) Server Exports · Read & Search Inventory data local inv = exports.nord_inventory:GetInventory(source) Public inventory data includes: { id = 'player:...', key = 'player:...', label = 'Inventory', type = 'player', slots = 40, weight = 12500, maxWeight = 80000, owner = false, owned = false, items = { [1] = { ... }, [2] = { ... } } } Read helpers exports.nord_inventory:GetInventories(type?, detailed?) exports.nord_inventory:GetInventoryItems(target, owner?) exports.nord_inventory:GetSlot(target, slot) exports.nord_inventory:GetEmptySlot(target) exports.nord_inventory:GetSlotForItem(target, itemName, metadata?) Item lookup helpers exports.nord_inventory:GetSlotWithItem(target, itemName, metadata?, strict?) exports.nord_inventory:GetSlotsWithItem(target, itemName, metadata?, strict?) exports.nord_inventory:GetSlotIdWithItem(target, itemName, metadata?, strict?) exports.nord_inventory:GetSlotIdsWithItem(target, itemName, metadata?, strict?) exports.nord_inventory:GetItemCount(target, itemName, metadata?, strict?) exports.nord_inventory:GetItemSlots(target, itemName, metadata?) exports.nord_inventory:GetItem(target, itemName, metadata?, returnsCount?) Search local count = exports.nord_inventory:Search(source, 'count', 'water') local slots = exports.nord_inventory:Search(source, 'slots', 'water') Alias: exports.nord_inventory:SearchInventory(...) Multiple item names can be passed as a table. The result then becomes a table keyed by item name. Server Exports · Metadata & Inventory Management Metadata exports.nord_inventory:SetMetadata(target, slot, metadata) exports.nord_inventory:GetMetadata(target, slot) exports.nord_inventory:UpdateMetadata(target, slot, patch) SetMetadata replaces the slot metadata with the supplied object after normalization/sanitization. UpdateMetadata patches fields. Inventory capacity local ok = exports.nord_inventory:SetMaxWeight(target, 200000) local ok, reason = exports.nord_inventory:SetSlotCount(target, 80) SetSlotCount refuses to shrink below a currently occupied slot and can return inventory_full. Clearing exports.nord_inventory:ClearInventory(target) Keep one or more item names: exports.nord_inventory:ClearInventory(target, { 'radio', 'phone' }) Remove from runtime cache exports.nord_inventory:RemoveInventory(target) Persistent inventories are saved before being removed from the runtime cache. Client Read-Only Exports Nord maintains a lightweight local player-inventory snapshot so common read-only exports work even when the NUI is closed. Available exports exports.nord_inventory:Search(searchType, item, metadata?) exports.nord_inventory:GetPlayerItems() exports.nord_inventory:GetPlayerWeight() exports.nord_inventory:GetPlayerMaxWeight() exports.nord_inventory:GetItemCount(itemName, metadata?, strict?) exports.nord_inventory:GetSlotWithItem(itemName, metadata?, strict?) exports.nord_inventory:GetSlotsWithItem(itemName, metadata?, strict?) exports.nord_inventory:GetSlotIdWithItem(itemName, metadata?, strict?) exports.nord_inventory:GetSlotIdsWithItem(itemName, metadata?, strict?) Example local count = exports.nord_inventory:Search('count', 'water') if count > 0 then print(('Player has %d water'):format(count)) end Important limitation These are read-only snapshot helpers for the local player. Inventory mutations should be done through trusted server-side code. Client inventory opening exports The client runtime also exposes: exports.nord_inventory:OpenInventory(...) exports.nord_inventory:openInventory(...) Use server-side permission logic before exposing sensitive/private inventories to a client. Registering Stashes & Custom Inventories RegisterInventory exports.nord_inventory:RegisterInventory('mechanic_storage', { label = 'Mechanic Storage', type = 'stash', slots = 80, maxWeight = 200000, jobs = { mechanic = 0 }, coords = vector3(-347.1, -133.3, 39.0) }) Supported registration options are normalized to: id label type slots (1–500) maxWeight coords jobs or groups owner public RegisterStash compatibility helper exports.nord_inventory:RegisterStash( 'burgershot_freezer', 'Burger Shot Freezer', 60, 200000, false, { burgershot = 0 }, vector3(-1195.4, -893.8, 14.0) ) Signature: RegisterStash(id, label, slots, maxWeight, owner?, groups?, coords?) Per-player owner storage When owner = true, Nord namespaces the storage to the player identifier when opened through the compatible owner path. Security recommendation For private inventories without world coordinates, validate the player's access in the server resource and open the storage server-side. Do not rely on an arbitrary client event to decide who can access a private stash. Usable Items & Hooks RegisterUsableItem Use a trusted server resource to attach behavior to an item: exports.nord_inventory:RegisterUsableItem('repairkit', function(source, item, definition) -- validate your own resource state here -- return false to block the use return true end) The handler receives: player source; a copy of the item instance; a copy of the item definition. Returning false blocks completion of the use. Hooks Register a hook: exports.nord_inventory:RegisterHook('beforeMoveItem', function(payload) if payload.to.type == 'evidence' and not IsAllowed(payload.source) then return false end end) Lowercase alias: exports.nord_inventory:registerHook(...) Hook names used by the core beforeMoveItem Payload includes: { source = source, from = fromInventory, to = toInventory, item = item, amount = amount, fromSlot = fromSlot, toSlot = toSlot, txid = transactionId } Returning false blocks the move. afterMoveItem Receives the same move payload after a successful move. beforeUseItem { source = source, inventory = inventory, item = item, definition = definition } Returning false blocks use. afterUseItem Receives the use payload after successful item handling. Runtime Item Registration Nord Inventory allows trusted server resources to register complete item definitions at runtime without editing shared/items.lua. This is designed for third-party resources that want to ship their own Nord Inventory integration and automatically register their required items when the resource starts. Runtime items can also define an external client or server export that Nord Inventory executes when the player uses the item. This allows the external resource to keep all of its gameplay logic inside its own resource. Basic Item Registration Use the RegisterItem export from a trusted server resource. 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 } }) The export returns two values: local ok, result = exports.nord_inventory:RegisterItem(...) Return values ok = true — Item registered successfully. ok = false — Registration failed. result — Registered definition or failure reason. Example: local ok, result = exports.nord_inventory:RegisterItem('service_token', { label = 'Service Token', weight = 5 }) if not ok then print(('Failed to register service_token: %s'):format(tostring(result))) return end print('service_token registered successfully') External Use Exports Runtime item definitions can include their own external use handler. Nord Inventory supports both: Client exports Server exports This makes it possible for another resource to completely control what happens when its item is used. Client Export Register the item from your server-side code: 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 }, client = { export = 'UseServiceToken', remove = 0 } }) Then create the export inside the client-side code of the same resource: exports('UseServiceToken', function(item, slot) print('Service Token used') print(json.encode(item)) print('Slot:', slot) return true end) Automatic Resource Detection When the export is registered like this: client = { export = 'UseServiceToken', remove = 0 } you do not need to include the resource name. Nord Inventory automatically associates the export with the resource that originally called: exports.nord_inventory:RegisterItem(...) For example, if the resource: medical_system registers: client = { export = 'UseMedicalScanner' } Nord Inventory knows that UseMedicalScanner belongs to medical_system. This allows third-party integrations to remain portable even if their resource structure changes. Server Export The item can also execute a server-side export instead. 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 }, server = { export = 'UseServiceToken', remove = 1 } }) Create the server export: exports('UseServiceToken', function(source, item, slot, definition) print(('Player %s used Service Token'):format(source)) print(json.encode(item)) print('Slot:', slot) return true end) Server Export Parameters The server export receives: source item slot definition source Player server ID. print(source) item Current item or slot information. print(json.encode(item)) slot Inventory slot containing the item. print(slot) definition The Nord Inventory item definition. print(json.encode(definition)) Item Removal The remove option controls how many items Nord Inventory should remove after a successful use. Example: client = { export = 'UseServiceToken', remove = 1 } The same option is available for server exports: server = { export = 'UseServiceToken', remove = 1 } Do Not Remove remove = 0 The item remains in the player's inventory after use. Recommended for reusable items such as: Tablets Phones Scanners Cards Documents Tools Devices Remove One remove = 1 One item is removed after successful use. Recommended for: Consumables Tickets Tokens Repair kits Medical supplies Remove Multiple remove = 2 Two items are removed after successful use. The value represents the amount Nord Inventory should consume. Export Return Value External exports should return whether the item use succeeded. Successful use: return true Failed use: return false Example: exports('UseServiceToken', function(item, slot) local allowed = CanUseServiceToken() if not allowed then return false end OpenServiceMenu() return true end) This becomes especially important when: remove = 1 is enabled. The external resource can validate whether the action succeeded before allowing the item to be consumed. Complete Client Example server.lua CreateThread(function() local ok, result = 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 }, client = { export = 'UseServiceToken', remove = 0 } }) if not ok then print(('[my_resource] Failed to register service_token: %s') :format(tostring(result))) return end print('[my_resource] service_token registered successfully') end) client.lua exports('UseServiceToken', function(item, slot) print('Using Service Token') print('Slot:', slot) -- Add your own logic here. OpenServiceMenu() return true end) Complete Server Example server.lua CreateThread(function() local ok, result = exports.nord_inventory:RegisterItem('repair_device', { label = 'Repair Device', description = 'External repair device', weight = 750, stack = true, close = true, category = 'tool', schema = 'generic', image = 'repair_device.png', metadataDefaults = { quality = 100 }, server = { export = 'UseRepairDevice', remove = 1 } }) if not ok then print(('[my_resource] Failed to register repair_device: %s') :format(tostring(result))) return end print('[my_resource] repair_device registered successfully') end) exports('UseRepairDevice', function(source, item, slot, definition) if not source then return false end print(('Player %s used repair_device'):format(source)) -- Add your validation and server-side logic here. return true end) Metadata Defaults Runtime items support default metadata. Example: metadataDefaults = { issuer = '', issuedAt = 0, serial = '', quality = 100 } You can use metadata for information that belongs to a specific item instance. Examples: Serial numbers Owner information Employee names Company information Issue dates Quality Durability Custom IDs Document data Example: local ok, def = exports.nord_inventory:RegisterItem('employee_card', { label = 'Employee Card', description = 'Company employee identification card', weight = 5, stack = false, close = false, category = 'document', schema = 'generic', image = 'employee_card.png', metadataDefaults = { employeeName = '', company = '', employeeId = '', issuedAt = 0 }, client = { export = 'UseEmployeeCard', remove = 0 } }) Recommended Integration Pattern External scripts should register their Nord Inventory items when their resource starts. Example: CreateThread(function() local ok, reason = exports.nord_inventory:RegisterItem('my_item', { label = 'My Item', description = 'Item provided by my resource', weight = 100, stack = true, close = true, client = { export = 'UseMyItem', remove = 0 } }) if not ok then print(('Failed to register my_item: %s'):format(tostring(reason))) end end) Then implement the item behavior inside the same resource: exports('UseMyItem', function(item, slot) -- External resource logic here. return true end) This keeps the integration completely self-contained. Server owners do not need to manually edit Nord Inventory files. Important Precedence Rule A runtime item cannot overwrite an authoritative database item with the same name. Example: local ok, reason = exports.nord_inventory:RegisterItem('service_token', { label = 'Service Token', weight = 5 }) If service_token already exists as an authoritative database-backed item, registration can fail with: database_authoritative Example: local ok, result = exports.nord_inventory:RegisterItem('service_token', { label = 'Service Token', weight = 5 }) if not ok then if result == 'database_authoritative' then print('service_token is already controlled by Nord Inventory') return end print(('Unable to register service_token: %s'):format(tostring(result))) end This protects definitions created through Admin Studio or the database-backed item registry from being silently replaced by third-party resources after a server restart. Item Definition Priority Database-backed items remain authoritative. The general priority is: Nord Inventory Database / Admin Studio ↓ Authoritative Item ↓ Runtime Registration An external resource cannot silently replace an authoritative Nord Inventory database definition through RegisterItem. Runtime Lifetime Items created through: exports.nord_inventory:RegisterItem(...) are runtime registrations. They are transient and must be registered again when the resource or server starts. Example: CreateThread(function() exports.nord_inventory:RegisterItem('service_token', { label = 'Service Token', weight = 5, client = { export = 'UseServiceToken', remove = 0 } }) end) This is intentional. It allows the external resource that owns the item to also own its definition and behavior. When to Use Runtime Registration Runtime registration is recommended for integrations such as: Crafting systems Job scripts Police scripts EMS scripts Mechanic resources Business systems Quest systems Minigames Document systems Custom usable items External gameplay resources Third-party integrations For example, a police script can automatically register its own: evidence_bag police_tablet breathalyzer evidence_camera without requiring the server owner to edit Nord Inventory. Permanent Items If an item should be permanently owned and managed by Nord Inventory, create or import it into the database-backed registry or Admin Studio. Permanent items can also be maintained through the appropriate Nord Inventory reference item files. Use: Runtime Registration when the external resource owns the item. Use: Nord Inventory Database / Admin Studio when Nord Inventory should own the item. Full Third-Party Integration Example Imagine an external medical resource named: my_medical The resource can register its own medical scanner. my_medical/server.lua CreateThread(function() local ok, reason = exports.nord_inventory:RegisterItem('medical_scanner', { label = 'Medical Scanner', description = 'Portable medical diagnostic scanner', weight = 1200, stack = false, close = true, category = 'medical', schema = 'generic', image = 'medical_scanner.png', metadataDefaults = { serial = '', owner = '' }, client = { export = 'UseMedicalScanner', remove = 0 } }) if not ok then print(('[my_medical] Unable to register medical_scanner: %s') :format(tostring(reason))) return end print('[my_medical] medical_scanner registered with Nord Inventory') end) my_medical/client.lua exports('UseMedicalScanner', function(item, slot) StartMedicalScanner() return true end) The server configuration only needs: ensure nord_inventory ensure my_medical No manual modification of: shared/items.lua is required. Integration Flow The complete integration flow is: External Resource Starts ↓ RegisterItem ↓ Nord Inventory registers the runtime item ↓ Player receives the item ↓ Player uses the item ↓ Nord Inventory detects external use behavior ↓ Client or Server Export ↓ External resource executes its own logic ↓ Export returns true / false ↓ Nord Inventory handles item removal Summary The RegisterItem API allows third-party resources to: Register their own Nord Inventory items. Avoid editing shared/items.lua. Define labels and descriptions. Define item weight. Configure stacking. Configure inventory closing behavior. Define categories and schemas. Define custom item images. Define metadata defaults. Attach external client exports. Attach external server exports. Automatically resolve the registering resource. Control item consumption with remove. Validate successful usage through export return values. Keep item logic inside the resource that owns the item. Re-register items automatically on resource start. Protect Admin Studio and database definitions from runtime overrides. The result is a plug-and-play integration system where developers can ship complete Nord Inventory support directly inside their own resources without requiring manual item configuration from the server owner. OX / QB Migration Examples Nord intentionally exposes familiar helpers so resource integration can be small. Item count OX-style concept: local count = exports.ox_inventory:Search(source, 'count', 'water') Nord: local count = exports.nord_inventory:Search(source, 'count', 'water') Add item local ok, result = exports.nord_inventory:AddItem(source, 'water', 2, { quality = 100 }) Remove item local ok, reason = exports.nord_inventory:RemoveItem(source, 'water', 1) Find a slot local slot = exports.nord_inventory:GetSlotWithItem(source, 'water', { type = 'clean' }) Register a stash exports.nord_inventory:RegisterStash( 'police_evidence', 'Police Evidence', 100, 300000, false, { police = 0 }, vector3(474.6, -996.8, 26.27) ) Open registered storage exports.nord_inventory:OpenInventory(source, 'stash', 'police_evidence') The main integration difference to preserve is security: keep access decisions server-side and let Nord validate the resulting inventory action/session. Complete Export Index · v1.6.11 Server · Core and registry GetInventoryType, GetItemDefinition, GetItems, GetItemList, Items, ItemList, RegisterItem, RegisterInventory, RegisterStash. Server · Opening OpenInventory, openInventory, forceOpenInventory. Server · Mutation and currencies AddItem, RemoveItem, AddCash, RemoveCash, AddDirtyMoney, RemoveDirtyMoney, ClearInventory, RemoveInventory, SetMaxWeight, SetSlotCount. Server · Carry validation CanCarryItem, CanCarryWeight, CanCarryAmount, CanSwapItem. Server · Read/search GetInventory, GetInventories, GetInventoryItems, GetSlot, GetSlotWithItem, GetSlotsWithItem, GetSlotIdWithItem, GetSlotIdsWithItem, GetEmptySlot, GetSlotForItem, GetItemCount, GetItemSlots, GetItem, SearchInventory, Search. Server · Metadata/use/hooks SetMetadata, GetMetadata, UpdateMetadata, RegisterUsableItem, RegisterHook, registerHook. Server · Vehicle capacity GetVehicleStorageCapacity, GetVehicleTrunkWeight, GetVehicleTrunkSlots, GetVehicleGloveboxWeight, GetVehicleGloveboxSlots. Client OpenInventory, openInventory, Search, GetPlayerItems, GetPlayerWeight, GetPlayerMaxWeight, GetItemCount, GetSlotWithItem, GetSlotsWithItem, GetSlotIdWithItem, GetSlotIdsWithItem. For signatures, return contracts and examples, use the integration pages in this chapter and the bundled INTEGRATION.md on Downloadable Reference Files. 7 · Database, Security & Operations Persistence, security model, troubleshooting, upgrades and production validation. Item Definition Reference The normalized definition supports these core fields: Field Purpose label Player-facing item name description Item description weight Weight per unit volume Optional volume value stack Allow stacking when metadata matches close Close inventory on use category Registry/UI category image Local filename/path or HTTP(S) URL schema Item schema name unique Force separate instances metadataDefaults Default metadata object metadataSchema Metadata field definitions metadataDisplay Player metadata visibility container Container storage definition consume hunger/thirst/health/armor effects use duration, movement, animation, prop, removal weapon GTA weapon name worldModel Ground/world prop model durability Per-instance durability rules expiry Per-instance shelf life clientEvent Trusted file/runtime definition event serverEvent Trusted file/runtime definition event Use block limits Normalized use configuration supports: use = { duration = 0, -- 0..30000 ms allowMove = true, cancelable = true, remove = 0, -- 0..100 actionText = 'Using {item}', animation = { dict = '...', clip = '...', flag = 49 -- normalized 0..51 }, prop = { model = 'prop_name', bone = 60309, pos = { x=0, y=0, z=0 }, rot = { x=0, y=0, z=0 }, rotOrder = 0 -- 0..5 } } Container limits container = { slots = 20, -- normalized 1..200 maxWeight = 25000 -- normalized 1000..2000000 } Weapon format weapon = { name = 'WEAPON_PISTOL' } The name must match the WEAPON_* format. Configuration Reference This page lists the main configurable groups in v1.6.11. Config Default / purpose Config.Framework auto Config.Locale en Config.Debug false Config.OpenCommand inventory Config.OpenKey TAB Config.AdminCommand norditems Config.AdminAce admin Config.AdminCommands ACE-protected command aliases Config.DefaultPlayerSlots 40 Config.DefaultPlayerWeight 80000 Config.DefaultStashSlots 60 Config.DefaultStashWeight 150000 Config.TrunkSlots 50 Config.TrunkWeight 120000 Config.GloveboxSlots 10 Config.GloveboxWeight 15000 Config.VehicleRegistry Vehicle capacity/catalog/placement configuration Config.Interaction Text UI / target provider configuration Config.VehicleInteraction TAB, NPC and trunk behavior Config.VehicleOpenDistance 4.0 Config.GroundOpenDistance 3.0 Config.GroundDrawDistance 15.0 Config.GroundPropDistance 35.0 Config.GroundDefaultModel prop_cs_cardbox_01 Config.GroundLifetimeSeconds 1800 Config.GroundSlots 30 Config.GroundWeight 250000 Config.ThrowMaxDistance 8.0 Config.ThrowMaxHeightDifference 4.0 Config.GroundAnimations pickup/put-down/throw animations Config.ItemPropAttachments hand attachment calibration + v1.6.11 fallback Config.BackWeapons cosmetic long-weapon back props Config.ItemUseAnimations pocket and weapon transitions 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 Config.UI inventory layout/hotbar defaults Config.Hotbar standalone hotbar settings Config.Stashes static configured stashes Config.LocaleFallback en Config.LocalePath locales Use the attached config.lua as the canonical shipped reference for nested values. Server-only administrator access The license fallback is intentionally not in config.lua. Configure it in: server/config.lua Do not move the license list into the shared configuration. Database & Persistence Item definition precedence Nord uses one deterministic rule: If a row exists in nord_inventory_custom_items for an item name, that DB row owns the definition. Only when no DB row exists does Nord fall back to shared/items.lua / shared/weapons.lua. A disabled DB row is still authoritative and blocks file fallback. Restart behavior Resource/server startup is read-only for item definitions. It does not seed/replace/delete DB item definitions from the Lua reference registry. This prevents an Admin Studio edit from disappearing after: restart nord_inventory Main storage table nord_inventory_storage stores inventory content keyed by inv_key, with type, owner, slots, max weight and serialized item data. Version history nord_inventory_item_versions stores item definition versions for custom/database changes. Transaction history nord_inventory_transactions stores inventory/admin transaction records using unique transaction IDs. Player preferences nord_inventory_preferences persists Personal Studio settings. Vehicle registry nord_inventory_vehicle_categories nord_inventory_vehicle_models These store category defaults, model overrides, glovebox settings and addon trunk placement data. Security & Server Authority Nord Inventory is intentionally designed so the UI/client does not become the authority for inventory state. Server-controlled operations The server validates or controls: item movement and transfer; weight/slot capacity; item use completion; authoritative metadata changes; firearm magazine ammunition; reserve ammo consumption; durability state; inventory sessions and persistence; admin authorization; vehicle storage capacity. Admin identifiers FiveM license fallback identifiers live only in server/config.lua and are not loaded on clients. Integration rule Third-party resources, including staff/admin systems, should use Nord Inventory server exports for mutations. Client snapshot exports are for UI/read convenience and must not be trusted as proof that an authoritative action is valid. Private storage Always check job/group/ownership permissions in trusted server code before opening a sensitive stash or custom inventory. Troubleshooting Admin Studio says access denied Confirm the ACE exists and the group is assigned to the player: add_ace group.admin nord_inventory.admin allow Also confirm: Config.AdminAce = 'nord_inventory.admin' Inventory does not start Confirm oxmysql is installed. Start oxmysql before nord_inventory. Check MySQL/MariaDB connectivity. Check the server console for a Lua/SQL error before the inventory bootstrap completes. Framework bridge is wrong Set it explicitly instead of auto: Config.Framework = 'qb' -- esx | qbox | nord | standalone Then restart the resource. Custom item changes revert after restart In v1.6.11, a valid DB row is authoritative and should persist. Check: that nord_inventory_custom_items contains the item row; database write errors in the console; whether you intentionally used Revert to base, which deletes the override row. Trunk does not open Check: vehicle is unlocked; the vehicle is not classified as no-trunk; you are within the configured distance; trunk interaction is enabled; an addon vehicle with incomplete metadata may need a saved Admin placement. Glovebox/trunk capacity looks wrong Capacity precedence is: model override > category > fallback Review the model and category in Admin Studio. Historical stored inventory capacity does not override the current vehicle registry settings when storage opens. Item has no hand prop For usable items, v1.6.11 should try the prop fallback. Check: Config.ItemPropAttachments.Enabled = true Config.ItemPropAttachments.Fallback.Enabled = true Then verify the item has a valid worldModel, matching name/category rule, or allow the generic fallback. Ground item uses a box instead of its intended prop Set a valid worldModel on the item. Otherwise Nord falls back to: Config.GroundDefaultModel = 'prop_cs_cardbox_01' A third-party script cannot access a private stash Open it from trusted server code after checking the player's job/permission. Do not depend on unrestricted client-side access for private storage. Admin Studio says access denied Check in order: The command is being executed in-game, not from an invalid context. add_ace group.admin nord_inventory.admin allow exists when using ACE. The user is actually assigned to that ACE group/principal. If using direct fallback, Config.AdminAccess.LicenseFallback = true. The player's FiveM license is present in server/config.lua. The license may be written with or without the license: prefix. Restart the resource after changing the server-only config. Weapon reload does not consume correctly Verify the ammo item name matches the weapon's configured ammunition type. Confirm metadata.magazineSize is valid or allow GTA clip-size detection for first use. Remember that reserve ammo must remain as inventory items. Do not add another script that writes hidden GTA reserve ammo while Nord controls the weapon. Ammo item shows a hand prop In v1.6.10+ ammo/magazine semantics bypass the hand-prop fallback. If a custom script manually attaches a prop outside Nord's use action, remove that external attachment logic. Update Guide · v1.6.8 → v1.6.11 Use this page when updating from the previous prop-fallback build. 1. Replace resource files Back up your existing resource and database, then update the code while preserving intentional server-specific configuration changes. 2. Review the new server-only config v1.6.11 adds: server/config.lua Configure Config.AdminAccess there. Do not put license identifiers in shared config.lua. 3. Confirm ACE object Use: add_ace group.admin nord_inventory.admin allow The corrected default ACE object is nord_inventory.admin. 4. Review weapon ammo behavior The largest behavior change is v1.6.9: old weapon reserve values must no longer be treated as metadata.ammo; metadata.ammo is loaded-magazine rounds only; metadata.magazineSize stores the capacity; reserve ammo stays in inventory items. Nord includes migration logic for older weapon metadata with excess reserve ammunition whenever it can identify the matching ammo item. 5. Review Personal Studio Players can choose Automatic or Manual reload behavior. Test both modes with your common weapon/ammo definitions. 6. Review ammo props v1.6.10 intentionally suppresses hand props for ammo/magazine use. Do not re-add those props unless you also accept the visual conflict with the equipped weapon reload flow. 7. Verify integrations Test scripts that call AddItem, RemoveItem, search/metadata exports, and your nord_staff inventory bridge after updating. 8. Production test Test persistence, a full reload cycle, manual/auto reload, weapon durability, Admin Studio access, vehicle storage and server restart before deployment. Production Checklist Before releasing Nord Inventory on a live server, verify the following. Server oxmysql starts before Nord Inventory. Database connection is stable. nord_inventory resource folder name has not been changed. Framework mode is correct or auto-detection reports the expected bridge. Admin ACE and/or server-only license fallback is limited to trusted staff. Config.Debug is disabled unless actively troubleshooting. Inventory Player inventory persists through disconnect/reconnect. Player inventory persists through resource/server restart. Add/remove/move/split operations behave correctly. Fast Slots 1–5 work and pinned items cannot be moved until unpinned. Ground pickup/drop/throw works at intended distances. Container nesting rules match your server design. Items Important item images exist or use valid remote URLs. Consumable effects and remove amounts are correct. Metadata visibility does not expose sensitive/internal fields. Durability/expiry values are balanced for production. Usable item hand props are calibrated or use safe fallback props. Vehicles Trunk interaction works on common front- and rear-storage vehicles. No-trunk vehicles are rejected. Glovebox/trunk capacities match your economy. Addon vehicles with poor metadata have manual placement where required. NPC trunk loot is disabled or balanced intentionally. Integrations Third-party resources call Nord from the server for state changes. Private stashes validate access server-side. Runtime item names do not conflict with DB-authoritative item definitions. Hooks that can block moves/use have been tested for false positives. v1.6.11-specific checks server/config.lua is present and remains server-only. ACE object matches nord_inventory.admin. License fallback works only for intended identifiers. metadata.ammo never contains reserve ammunition. Manual and Automatic reload modes consume only required rounds. Ammo/magazine item use does not spawn hand props. nord_staff integration is tested after Nord Inventory starts. Downloadable Reference Files The following original v1.6.11 resource files are attached to this BookStack import for quick reference: Main config.lua. Server-only server/config.lua. server.cfg.example. sql/nord_inventory.sql. README.md. Full CHANGELOG.md. docs/INTEGRATION.md. DB item persistence notes. Item definition precedence notes. Resource structure notes. These attachments are reference copies from the supplied v1.6.11 package. Edit the actual files in your FiveM resource, not the BookStack attachments.