How Integrations Work#
Nothing inside the protected core of Chess knows which framework you run. Money, permissions and character names go through server/custom/framework/ — one small file per framework — and notifications, the HUD and the table prompt go through client/custom/framework.lua. Both are unencrypted, so anything on this page can be changed to fit your server.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Standalone: tables are free, stakes are not collected, players show their FiveM name. |
Money | Your framework's cash and bank, or your own currency. | Nothing is charged. |
Notifications |
|
|
HUD |
| Only the game's HUD and minimap are hidden. |
Table prompt |
| A built-in floating text over the board. |
Database |
| Required. |
Every optional integration degrades silently. A missing resource makes that part fall back to the built-in version; nothing errors and nothing needs switching off.
Frameworks#
The framework is detected when the resource starts. Each table charges in money (cash) or bank, and the bridge turns that into your framework's own accounts:
money is the player's cash (getMoney, removeMoney, addMoney); bank is the bank account. Names come from xPlayer.getName(). File: server/custom/framework/esx.lua.
money is the cash money type, bank the bank one. Names are the character's first and last name from charinfo. File: server/custom/framework/qb.lua.
Detected through qbx_core and run through the QBCore bridge, using the QBCore compatibility that Qbox ships with. Money and names behave exactly as on QBCore.
With no framework running, every player can afford everything and no money moves: tables are free and bets are for show. Define the three functions under A Custom Currency below and a standalone server charges real fees and real stakes in whatever you keep money in.
A Custom Currency#
Entry fees and bets only ever ask three things: can this player afford it, take it, give it. Define the answers in config/config.lua and they replace the framework's — on ESX, QBCore, Qbox and standalone alike. This example plays every table and every bet for casino chips held in ox_inventory:
-- config/config.lua
-- method is what is being paid: the table's payment method for an entry fee
-- ('money' or 'bank'), or Config.Betting.paymentMethod for a stake.
Config.CanAfford = function(source, amount, method)
return exports.ox_inventory:GetItemCount(source, 'casino_chips') >= amount
end
Config.RemoveMoney = function(source, amount, method)
exports.ox_inventory:RemoveItem(source, 'casino_chips', amount)
end
Config.AddMoney = function(source, amount, method)
exports.ox_inventory:AddItem(source, 'casino_chips', amount)
endBecause method is passed in, one set of functions can treat fees and stakes differently: set Config.Betting.paymentMethod = 'chips' and check for 'chips' to take bets in chips while entry fees keep coming from cash or the bank.
Define all three together. A bet takes from both players before the game and pays out or refunds after it, so a
CanAffordin chips with the framework still taking cash charges one currency and checks another.
Notifications, the HUD and the Prompt#
client/custom/framework.lua holds three functions. Replace the body of any of them to use your own resources:
Function | Called |
|---|---|
| For every message — challenges, check, results, payments. |
| With |
| Every frame while a player stands at a free table, for the |
-- client/custom/framework.lua
function Notification(msg, kind)
local types = { inform = 'info', success = 'success', error = 'error' }
exports['okokNotify']:Alert('Chess', msg, 3000, types[kind] or 'info')
end
function ToggleGameHud(visible)
DisplayHud(visible)
DisplayRadar(visible)
-- hide or show your own HUD resource here
endPermissions#
Who may use the creator and the calibration tools is one function, HasPermission(src), in each server bridge. By default it checks the ACE in Config.Creator.permission. The server asks it before every save, move and delete, and the client asks the server before opening anything, so changing it here changes it everywhere:
-- server/custom/framework/esx.lua
function HasPermission(src)
local xPlayer = ESX.GetPlayerFromId(src)
if not xPlayer then return false end
local group = xPlayer.getGroup()
return group == 'admin' or group == 'superadmin'
end-- server/custom/framework/qb.lua
function HasPermission(src)
return QBCore.Functions.HasPermission(src, 'admin')
endNext to it, GetCharacterName(src) decides the name shown in the opponent list and on a challenge. Return nil and the player's FiveM name is used.
Map Tables#
Chess streams its own models — table_chess, chess_chair and the 32 pieces — and registers them with the game, so any map editor can place the table and chairs in a YMAP or an MLO. qs-chess has to be running for those props to load.
With Config.AutoDetect = true, every player looks for a table_chess within 45 m every few seconds. The first one to find a table registers it, and from then on it is playable for everybody — no config line, no database row. Chess adds the pieces to it; it does not spawn a second table on top.
A map table needs its two chairs in the map too. Chess only spawns chairs for the tables it spawns itself. Place two
chess_chairprops on the table's forward axis, one on each side, about 0.96 m from its centre — players are seated on any chess chair found within 0.75 m of that spot. Without them, they sit on thin air.
To stop map tables from becoming playable, set Config.AutoDetect = false. Tables from the creator and from Config.Tables are not affected.
Languages#
Forty-one complete translations ship in locales/, and one setting picks the language of both the notifications and the interface:
-- 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, zh
Config.Locale = 'es'Any text can be reworded in locales/<code>.json — the same file feeds the game and the interface — followed by a restart. A key missing from your language is read from English, and an unknown code falls back to English entirely, with [qs-chess] Locale "xx" not found, falling back to "en". in the F8 console.



