XS-CriminalTablet
Gang tablet for Qbox and QBCore. Turf you hold by influence, raids and gang war, graffiti, a shared garage, contracts, and a staff console that builds the whole thing in game.
Requirements
Required
- Framework: QBox (
qbx_core) or QBCore (qb-core) — the bridge auto-detects. ox_liboxmysqlox_inventory— the vault, armory and the device item all depend on it.
Optional
ox_target— proper target interactions on the vault, benches and dealer ped. Without it everything falls back to an[E]proximity prompt.
Current release is v0.1.
Installation
- Drop the
XS-CriminalTabletfolder into yourresourcesdirectory. - Import
sql/XS-CriminalTablet.sqlinto your database. - Add an item named
XS-CriminalTablet_tabletto your ox_inventory items, or pointConfig.DeviceItemat a name you already have. - Add the start line to
server.cfg— it must come after ox_lib, oxmysql, your framework and ox_inventory. - Grant yourself the admin ACE (next section), then work through
config.lua.
ensure XS-CriminalTablet
Give yourself a tablet from your inventory admin tools, or run /gangops.
Admin access
Staff manage everything in-game through the admin tablet rather than by editing config or the database by hand. Access is an ACE permission:
add_ace group.admin XS-CriminalTablet.admin allow add_principal identifier.fivem:1234 group.admin
Then run /admintablet. Six tabs:
- Dashboard — gang count, zones assigned, total gang bank, vehicles, tags up, live wars, chat counts, dealer cooldown state.
- New Crew — a six-step wizard: name and colour, boss, size and treasury, their first block drawn on the map, their property dropped on it, review. Nothing is written until the last button.
- Gangs — create, rename, set boss, disband, kick, promote, adjust rep, force-set the bank balance, edit the rank ladder live.
- Turf — a full map editor. Draw a zone as a real polygon by clicking the satellite view, or walk the corners in world. Shows every zone, placement and blip on one map.
- Pricing — every unlock and upgrade level priced live. config.lua only sets defaults.
- Blips — crew map markers: label, sprite, colour, scale, and crew-only or visible to everyone.
- Dealer Setup — his stock pool, every spot he can appear at, and all the timings. Stored in the database, overriding config.
- Zones — create a zone at your current position, move or rename it, assign or clear its holder.
- Blackmarket — read recent world chat with delete buttons, and resolve a handle to a citizenid when moderation needs it.
- Dealer — view rotating stock, force a reroll, clear the global cooldown.
Every action re-checks the ACE permission server-side rather than just hiding buttons, and writes to the Discord admin webhook. Config.Gangs only seeds gangs on first boot — after that the database is the source of truth.
Gangs and progression
Membership
Gangs are admin-defined. Create, disband and boss changes happen on the admin tablet; invite, accept, kick, promote and demote happen in-game. Ranks and permissions are config-driven with per-gang ranks stored in the database.
Rep
Each member has personal rep, which feeds a gang-wide rep total with five tiers. There is no idle decay — rep only drops through the friendly-fire penalty (Config.Rep.friendlyFirePenalty, killing your own gang member), losing a war, or an admin adjustment.
Levels and perks
Config.GangLevels layers a more granular level and title (Crew through Untouchable) on the same rep value. Crossing a level threshold awards perk points, spent in Config.GangPerks across three branches — Vault (slots and weight), Recruitment (max members) and Workshop (craft time, bonus output, early recipe unlocks). Tier N in a branch requires tier N-1. Boss-only, via manage_perks.
Territory
Zones are assigned entirely through the admin tablet. There is no in-world capture and no passive income — holding a zone is prestige only. The blip radius grows with the holder's tier (Config.ZoneRadiusGrowthPerTier), which is purely visual.
Vault, benches and crafting
The vault is a physical placed container backed by a per-gang ox_inventory stash, not a remote button. Place it and the benches from the tablet's Unlocks tab once your tier allows: hit Place, scroll to set distance, Q/E to rotate, Enter to confirm.
There is one bench. Recipes in Config.Recipes each carry a tier requirement, so higher tiers unlock more recipes at that same bench. Inputs and outputs are validated server-side against the player's real inventory.
Treasury
No forced dues. Any member can deposit; withdrawing is gated behind manage_bank so one person cannot drain it. Transactions go to a dedicated ledger (XS-CriminalTablet_gang_bank_log) separate from the activity log.
The apps
The device is a shell that hosts apps. Register new ones in shared/apps.lua — the shell needs no changes.
Gang Ops
Overview, roster, territory map, tasks, unlocks, treasury, perks and activity log. Tasks are solo jobs, fully server-validated:
type = 'delivery'— target the pickup, then a delivery ped at the dropoff. Each step re-checks the player's real position server-side.type = 'kill'— the server picks a spawn point, the client spawns an armed hostile and reports the kill. The report is only trusted afterminKillSeconds.
Dealer and drug selling
The dealer is on-demand from the Tasks tab. One call at a time server-wide on Config.Dealer.cooldownHours — a global cooldown, not per player. Stock rotates on rotateMinutes with randomized pricing. Config.Dealer.pool ships empty, so add entries or the dealer has nothing to sell.
Drug selling works anywhere, not just in territory: target any nearby NPC with ox_target, or /selldrug to grab the nearest one. The server validates the real item count and a per-player cooldown before paying.
Blackmarket
Anonymous world chat plus handle-addressed DMs. Requires gang membership — the app does not appear in the rail otherwise, and that is enforced server-side too. Every character gets a persistent, renameable handle (e.g. ShadowFox-A1B2) that is never tied to their gang. Only the server can resolve a handle to a citizenid.
Turf
Zones belong to a crew and nothing a player does moves one. Staff draw a zone for a gang and it stays theirs. What players change is influence: stand on a block and your crew's share climbs, and every zone shows the split — "Ballas 68% · Vagos 22%" — on the map, the turf card and an in-world bar.
A rival tops out at Config.Territory.rivalInfluenceCap (60% by default), so working a block is pressure and prestige, not a takeover. A zone with no crew assigned is invisible to players entirely.
War and raids
Raid a rival HQ for a cut of their treasury, or declare a full war fought on kills. Win a war and the loser's safe is exposed for fifteen minutes — compass arrow, blip, live distance, and you take real cash and real items out of their vault.
Graffiti
42 fonts, a text composer with outline thickness, letter spacing, slant, tilt, case and glow, plus freehand drawing. Staff issue custom images per crew from the admin tablet; members can never introduce a remote image URL themselves, because that URL loads inside every nearby player's game.
Discord logging
All optional. Set any of these to a webhook URL to get live embeds; leave one blank to disable that category.
Config.Discord.adminWebhook -- every /admintablet action (the audit trail) Config.Discord.gangWebhook -- founded, disbanded, boss changed Config.Discord.economyWebhook -- deposits, withdrawals, dealer purchases
Get a URL from Discord: channel settings → Integrations → Webhooks → New Webhook → Copy URL.
Exports
Other resources can read and feed the gang system:
exports['XS-CriminalTablet']:AddRep(gangId, amount, reason) exports['XS-CriminalTablet']:GetPlayerGang(src) exports['XS-CriminalTablet']:HasGangPermission(src, perm) exports['XS-CriminalTablet']:GetGangTerritories(gangId)
AddNotoriety still works as an alias.
Before going live
Config.Dealer.poolis empty by default — add entries or the dealer sells nothing.- Drug selling defaults to a few common item names. Rename them to match your
ox_inventoryitems.lua. - Nothing ships pre-made — no gangs, no zones, no graffiti. Build them from the admin tablet before players open it.
Config.Medic.station.coordsneeds a vector, or nobody can revive.- The money API assumes both frameworks expose
Player.Functions.AddMoneyandRemoveMoney. Verify against your build and adjust the bridge if needed. - Verify any model name before putting it in config — use
/testmodel <name> [ped]. Guessed model names fail silently or with confusing errors.
Known trust boundaries
Stated plainly so you can decide if they matter for your server: placement validates the final spot is within 6m of the placing player server-side, but otherwise trusts the client-reported ghost position. That is fine for a Boss-only permissioned action and is not meant to resist a malicious client. The kill task type trusts the client's kill report after minKillSeconds.
Troubleshooting
The tablet does nothing when used
The item name in your inventory does not match Config.DeviceItem (default XS-CriminalTablet_tablet).
/admintablet says no permission
The XS-CriminalTablet.admin ACE is not granted to a principal you belong to. Both the add_ace and add_principal lines are needed.
The Blackmarket app is missing from the rail
Working as intended — it requires gang membership, enforced server-side.
Calling the dealer produces nothing
Config.Dealer.pool is empty. Also note the cooldown is server-wide, so another player may have used the call.
Vault or bench will not open
Without ox_target you need to stand close enough for the [E] prompt. Check the placement actually saved — placement is Boss-gated via place_objects.
A model spawns invisible or errors
Run /testmodel <name> before trusting any model name in config.
Updating
- Back up the database. Gangs, rep, territory, vaults, treasury and graffiti all live there.
- Keep a copy of your edited
config.lua— it holds your ranks, zones, recipes and perks. - Check recent commits for SQL changes before replacing files.
- Replace the resource folder, merge your config back, restart.
Support
Include your framework (QBox or QBCore), whether ox_target is running, the full console error and the steps that caused it.