How Integrations Work#
The core of Trading Cards never talks to a framework or an inventory by name. Every call goes through a small bridge — one file per framework and one per inventory — and only the bridge that matches your server runs. The bridges are plain, unencrypted Lua in client/custom/ and server/custom/, so they can be read and adapted.
Layer | Supported | Without it |
|---|---|---|
Framework |
| The standalone bridge: identifiers from the player's licence, money from a |
Inventory |
| Required. The resource stops with |
Target |
| NPCs use an |
Notifications and progress bar |
| ox_lib's notifications and progress circle. |
3D prompt |
| A drawn label above the NPC. |
Quests |
| No quests; nothing else changes. |
Database |
| Required. |
Frameworks#
ESX, QBCore and Qbox#
Detected automatically. qbx_core uses the same bridge as qb-core. The framework provides the player, the identifier, the money accounts (cash / bank, which is money / bank on ESX), usable items and the admin group the creator checks.
Standalone#
With no framework running, server/custom/framework/standalone.lua takes over and needs no edits to work:
What | How standalone handles it |
|---|---|
Player identifier | The first of |
Money | An inventory item called |
Creator groups |
|
Usable items | Registered with qs-inventory, or caught from ox_inventory's use event. Either way the server checks the player holds the item, and a use that arrives twice is only acted on once. |
Standalone is built for ox_inventory and qs-inventory. Any other inventory is reached through a generic GetInventory / AddItem / RemoveItem bridge, and the console says so on start — if items are not added or removed, that is the function to adapt.
To use a banking resource instead of the money item, replace GetMoney and RemoveMoney in the same file.
Inventories#
Detection takes the first inventory it finds running. Each one has a bridge on both sides:
File | What it does |
|---|---|
| Writes item metadata (how an album gets its id and a card its PSA rating) and makes the album item usable. |
| Opens the inventory from the pack reveal's Open Inventory button. |
The inventory must support item metadata: every card is the same item with different data, and an inventory without metadata (the old esx_inventory) cannot tell them apart.
Targets#
Set Config.UseTarget = true to put a third-eye option on every shop, grader and trader instead of the [E] prompt. The first of ox_target, qtarget and qb-target that is running is used, from 2.5 metres. If none is running the console prints a warning and the [E] prompt stays.
Overriding Detection#
Both lists live at the top of shared/config.lua. Replace the detection with a fixed value to force one — useful when a resource has been renamed on your server:
-- Auto, the default
Config.Framework = dependencyCheck(frameworks) or 'standalone'
-- Forced
Config.Framework = 'esx' -- 'esx', 'qb' or 'standalone'
Config.Inventory = 'ox' -- 'ox', 'qs', 'qb', 'core', 'origen', 'codem', 'tgiann'Detection only sees resources that are already started, so anything you want found must sit above ensure qs-tradingcards in server.cfg.
Adding an Inventory#
Copy the closest bridge
Copy
server/custom/inventory/qs.luaandclient/custom/inventory/qs.luaand rename both after your inventory.Change the calls inside
Change the guard at the top to your new short name, and fill in your inventory's exports:
lua if Config.Inventory ~= 'myinv' then return end function SetItemMetaData(src, slot, meta) exports['my-inventory']:SetItemMetadata(src, slot, meta) end RegisterUsableItem('tradingcard_stash', function(source, item) local meta = item.info and item.info or item.metadata TriggerClientEvent('tradingcards:client:OpenAlbum', source, meta) end)On the client,
OpenInventory()opens your inventory.Register it for detection
Add
['my-inventory'] = 'myinv'to theinventoriestable inshared/config.lua.
Discord Logs#
Everything that matters can be posted to Discord as an embed, with the player's name, server id and identifier, in your server's language. Logs are off until you switch them on in server/webhook.lua:
local Logs = {
enabled = true,
default = '', -- used by any category left empty
webhooks = {
admin = 'https://discord.com/api/webhooks/...',
economy = 'https://discord.com/api/webhooks/...',
items = '',
denied = '',
},
name = 'Trading Cards',
avatar = '',
}Category | What goes there |
|---|---|
| Cards, rarities, themes and NPCs created, edited or deleted, and cards given out from the creator. |
| Shop purchases and grading fees, with the amount and account. |
| Every pack opened with the cards pulled, and every trade with the trader. |
| Refusals: a creator action without permission, a shop, grader or trader request from too far away, a second request fired before the first finished. |
Logs are queued and sent in batches of up to ten embeds a second per webhook, so they never slow the server. If Discord rejects a webhook, the console says so once.
Languages#
41 translations ship in locales/: ar, bg, bn, ca, cs, da, de, el, en, es, et, fa, fi, fr, he, hi, hr, hu, id, it, ja, ko, lt, lv, ms, nl, no, pl, pt, ro, ru, sk, sl, sv, sw, th, tr, uk, ur, vi and zh. They cover the interface, notifications, NPC dialogue and Discord logs.
The language comes from the shared Quasar convar, so one line in server.cfg sets it for every Quasar resource:
setr qs:locale "en"To add another language, copy en.json to the new code, translate it and set the convar to that code. Anything left untranslated falls back to English.



