Skip to content

twinded_lgw_society

A comprehensive society/company management system for RedM. Manage cash registers, employees, salaries, safes (armory inventories), boss offices, and permissions — all driven by database-stored jobs and grades.

Dependencies

ResourceRequiredNotes
vorp_coreYesFramework
vorp_inventoryYesInventory system
twinded_libsYesFree shared library
oxmysqlYesDatabase

Compatibility

VORP Framework only — this script uses VORP Core API and vorp_inventory directly.

Installation

bash
ensure twinded_libs
ensure twinded_lgw_society

Database

This script reads from existing job tables. The default table names are:

TableDescription
twinded_jobsJobs (name, label, balance, bosslocation, armorylocation, payCurrency, payInterval, ...)
twinded_jobs_gradesGrades (job_name, grade, grade_label, salary, permissions JSON)
twinded_jobs_salary_trackerSalary tracker (charidentifier, job_name, elapsed_minutes)

You can change these names in Config.Tables (see settings.lua).

Config Files

FileDescription
settings.luaDebug, database tables, prompt ranges, inventory, placement, salary, unemployment, markers, webhook
lang.luaAll translation strings (prompts, menus, notifications, webhook titles)
webhook.luaCustom webhook handler (when Config.Webhook.type = 'custom')

See the Configuration guide for how to override these files.

Configuration Reference

settings.lua

OptionTypeDefaultDescription
Config.DebugbooleanfalseEnable debug logging
Config.Tables.Jobsstring"twinded_jobs"Jobs database table
Config.Tables.Gradesstring"twinded_jobs_grades"Grades database table
Config.Tables.SalaryTrackerstring"twinded_jobs_salary_tracker"Salary tracker table
Config.BossPromptRangenumber2.0Distance (meters) to interact with boss office
Config.ArmoryPromptRangenumber2.0Distance (meters) to interact with safe/armory
Config.MarkerRangenumber10.0Distance (meters) at which markers become visible
Config.HireRangenumber5.0Distance (meters) to detect nearby players for hiring
Config.InventoryLimitnumber0Max slots in armory inventory (0 = unlimited)
Config.AcceptWeaponsbooleantrueAllow weapons in armory
Config.PositionTimerDaysnumber1Cooldown (days) between office/safe relocations
Config.PlacementTimeoutnumber60Timeout (seconds) for placement mode
Config.StaffGroupstable{"admin", "dev", "superadmin"}Groups that bypass placement cooldown
Config.SalaryTrackerSaveIntervalnumber2How often (minutes) salary progress is saved to DB
Config.UnemployedMoneynumber2Unemployment allowance amount
Config.UnemployedPayIntervalnumber60Unemployment payment interval (minutes)
Config.BossMarkertableBoss office marker color (default: gold)
Config.ArmoryMarkertableArmory marker color (default: blue)
Config.Webhook.typestring"discord"'discord' or 'custom'
Config.Webhook.urlstring""Discord webhook URL

Permission Fields (grades table JSON)

Each grade's permissions JSON column in the database:

PermissionTypeDescription
isBossbooleanFull management access
armoryAccessbooleanCan open the armory/safe
depositBalancebooleanCan deposit money to cash register
withDrawBalancebooleanCan withdraw money from cash register
storeDepositItemsbooleanCan deposit items in armory
storeWithdrawItemsbooleanCan withdraw items from armory

webhook.lua — Custom Data Fields

When using Config.Webhook.type = 'custom', the data._meta object contains:

FieldTypeDescription
actionstring"deposit", "withdraw", "hire", "fire", "grade_change", "salary", "unemployment"
jobstringJob name
amountnumberMoney amount (when applicable)
currencynumberCurrency type (0 = dollars, 1 = gold)
newBalancenumberCompany balance after operation
targetCharIdnumberTarget character identifier
newGradenumberNew grade number (for grade changes)
gradeLabelstringNew grade label
srcNamestringAction initiator name
targetNamestringAction target name

Features

  • Boss office — Proximity-based prompt to open management menu
  • Cash register — Deposit and withdraw money (permission-based)
  • Employee management — View, hire, promote, demote, fire
  • Safe (armory) — Shared inventory accessible by authorized employees
  • Salary system — Automatic payments at configurable intervals, persisted across reconnects
  • Unemployment allowance — Periodic payments to unemployed/offduty players
  • Office/safe relocation — Boss can move the office and safe (with cooldown)
  • Permission system — Grade-based permissions stored as JSON
  • Real-time sync — Markers and prompts update instantly when job or permissions change
  • Multi-job support — Full multijob integration
  • Hot restart support — Re-pushes all player data on resource restart
  • RCON sync events — External panel integration
  • Webhook logging — Discord or custom handler
  • Rate limiting — Per-source and per-job locking

Command

CommandDescription
/jobmenuOpen placement menu (boss only, no proximity required)

Server Exports

Money

lua
-- Get company balance
local balance = exports['twinded_lgw_society']:getSocietyMoney(jobName)

-- Add money (atomic SQL)
exports['twinded_lgw_society']:addSocietyMoney(jobName, amount)

-- Remove money (floor at 0)
exports['twinded_lgw_society']:removeSocietyMoney(jobName, amount)

Player Status

lua
local isBoss    = exports['twinded_lgw_society']:getPlayerBossStatus(src)
local hasArmory = exports['twinded_lgw_society']:getPlayerArmoryStatus(src)
local canDraw   = exports['twinded_lgw_society']:getPlayerWithDrawStatus(src)
local perms     = exports['twinded_lgw_society']:getPlayerStorePermissions(src)

Job Data

lua
local grades    = exports['twinded_lgw_society']:getJobGrades(jobName)
local jobData   = exports['twinded_lgw_society']:getJobData(jobName)
local allJobs   = exports['twinded_lgw_society']:getAllJobs()
local labels    = exports['twinded_lgw_society']:getGradesForClient(jobName)

-- Async
exports['twinded_lgw_society']:getJobEmployees(jobName, function(employees)
    -- ...
end)

Salary

lua
-- Delete salary tracker entry
exports['twinded_lgw_society']:deleteSalaryTrackerForJob(charId, jobName)

-- Get remaining time per job (async)
exports['twinded_lgw_society']:getSalaryInfoForJobs(charId, jobNames, function(info)
    -- ...
end)

Server Events

EventDescription
twinded_lgw_society:cacheReadyFired when the cache is fully loaded
twinded_lgw_society:employeeHireFired after a hire (src, jobName, charId)
twinded_lgw_society:employeeFireFired after a fire (src, jobName, charId)
twinded_lgw_society:rcon:syncJobRCON: reload a specific job (jobName)
twinded_lgw_society:rcon:syncAllJobsRCON: reload all jobs

Troubleshooting

ProblemSolution
Script doesn't startMake sure twinded_libs is started before
No markers/promptsCheck the job exists in DB with bosslocation/armorylocation set
Can't access officeVerify grade permissions in twinded_jobs_grades.permissions JSON
Salary not payingCheck payInterval in jobs table and salary in grades table
Safe not openingVerify armoryAccess or isBoss permission for the grade
Wrong table namesUpdate Config.Tables in settings.lua

Premium RedM Scripts — Multi-Framework