🪪 Identity Card
Documentation relating to the spooni_identitycard.
1. Installation
spooni_identitycard needs spooni_libs (it works alongside your framework through its bridge).
To install spooni_identitycard:
- Download the resource
- Ensure that all requirements are installed
- Drag and drop the resource into your resources folder
spooni_identitycard
- Add this ensure in your server.cfg (after spooni_libs and jo_libs)bash
ensure oxmysql ensure spooni_libs ensure jo_libs ensure spooni_identitycard - The items are created in your inventory automatically on first start — restart the server once afterwards so your inventory loads them. Copy the item images from the
extra/folder into your inventory's item images.- Certificates:
identitycard(the real certificate),fakeidentitycard(the forged one). - Licenses:
mininglicense,forestlicense,hunterlicense,horsetrainerlicense,bountylicense,gunsmithlicense,fishinglicense,merchantlicense,doctorlicense.
- Certificates:
- Now you can configure and translate the script as you like
config.lualanguage.lua
- At the end, restart the server
TIP
The certificate and license tables are created automatically on first start — no SQL import needed. For the office clerks to spawn, set Config.PedManager = true in spooni_libs; the offices still work through their blips and prompts without it.
If you have any problems, you can always open a ticket in the Spooni Discord.
2. Usage
Players visit a registration office in any major town, fill in a period-styled Certificate of Identity straight on the paper (surname and given name, date of birth, nationality, eye and hair colour, height, an optional photo link) and sign it to receive the certificate as a real inventory item. Each region prints its own state background, the certificate is valid for a set number of real days (shown in the VALID UNTIL box on the back) and is renewed at the office when it expires; details can be updated and copies bought at any time.
Using the certificate holds it up in your hands. With nobody around you simply read it; with players nearby a selector lets you choose who sees it — and with require_accept on, the other player first gets an Accept / Decline request with a countdown.
The same office sells nine work licenses (mining, forest, hunter, horse trainer, bounty hunter, gunsmith, fishing, merchant and doctor) rented by the day, renewable before they lapse and printed with the owner's name and expiry. A hidden office issues forged certificates under a different item, with any state background, every detail rewritable later. With spooni_archives running, the offices also open a fines & taxes desk.
3. For developers
Server exports
Check a player's certificate and licenses from your own scripts. charid is the character id.
-- certificate still in date (true / false)
local ok = exports.spooni_identitycard:IsIdentityValid(charid)
local ok = exports.spooni_identitycard:IsIdentityValidSource(source)
-- "dd-mm-yyyy", or false when there is no certificate
local untilDate = exports.spooni_identitycard:GetIdentityExpiry(charid)
-- license still in date (true / false)
local ok = exports.spooni_identitycard:HasLicense(charid, "mining")
local ok = exports.spooni_identitycard:HasLicenseSource(source, "mining")
-- the full row while valid, false once it lapsed
local row = exports.spooni_identitycard:GETLICENSE("mining", charid)
-- every license the character ever bought
-- { mining = { name = "Mining License", valid = true, expires = {year=, month=, day=} } }
local all = exports.spooni_identitycard:GetLicenses(charid)
-- "dd-mm-yyyy", or false when there is no valid license
local untilDate = exports.spooni_identitycard:GetLicenseExpiry(charid, "mining")
-- revoke a license
exports.spooni_identitycard:RemoveLicense(charid, "mining")
-- re-read every certificate from the database (optionally refresh one record's owner)
exports.spooni_identitycard:RefreshIdentityCache(recordid)Client exports
Read the local player's own certificates.
-- the real certificate, or false
local card = exports.spooni_identitycard:GetIdentityCard()
-- the forged certificate, or false
local fake = exports.spooni_identitycard:GetIdentityFakeCard()Where paid fines go
When a player settles a fine, the money is handed to the deposit_fine function at the bottom of config.lua. By default it adds the amount to the paying city's bank account when Config.bank = true; edit the body to send it anywhere else (a treasury account, another resource's export, a webhook, ...).
function deposit_fine(source, city, amount, penal)
-- source = player who paid, city = the fine's city
-- amount = money actually paid, penal = the offense's penal type
endDate of birth format
The empty Date of Birth line shows the order players should type, taken from write_dob in language.lua (default DD-MM-YYYY). The typed date is read in that same order, so the hint and the reading always agree — set MM-DD-YYYY or YYYY-MM-DD per language if your players expect it. The separator may be -, ., / or a space.
Licenses & backgrounds
Each license draws its paper from a streamed .ytd named by its texture field in Config.licenses; to add a license, drop its .ytd into stream/ and point a new entry at it. Each office in Config.national_registration has its own certificate background (texture), and the forged-certificate states are listed in Config.fake_states. The background is saved with the certificate, so it always opens the way it was issued.
