Skip to main content

Runtime Item Registration

TrustedNord Inventory allows trusted server resources canto register ancomplete item definitiondefinitions 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.

        Tablets Phones Scanners Cards Documents Tools Devices

        Remove One

        remove = 1
        

        One item is removed after successful use.

          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 precedencePrecedence ruleRule

            A runtime item cannot overwrite an authoritative database rowitem with the same name.name.

            Example:

            local ok, reason = exports.nord_inventory:RegisterItem('service_token', {
                label = 'Service Token',
                weight = 5
            })
            

            If RegisterItemservice_token returnsalready a failure suchexists as an authoritative database-backed item, registration can fail with:

            database_authoritative
            
            in

            Example:

            that
            local case.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/databaseStudio definitionsor the database-backed item registry from being silently replaced by a third-party resourceresources onafter a server restart.

            Item Definition Priority

            Database-backed items remain authoritative.

            The general priority is:

            Nord Inventory Database / Admin Studio
                            ↓
                   Authoritative Item
                            ↓
                   Runtime lifetimeRegistration
            

            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 transient.intentional.

            If

            It youallows needthe 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 definitionpolice 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/create or import it into the database-backed registry or maintainAdmin itStudio.

              in

              Permanent items can also be maintained through the appropriate Nord Inventory reference Luaitem 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.