How Integrations Work#
Arm Wrestling talks to the rest of your server through one small, open file per framework, in custom/, which handles money and player names. The framework is detected when the resource starts; the optional resources are used whenever they are running.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Runs standalone: bets move no money, and names come from FiveM. |
Database |
| Required. |
Library |
| Required. Callbacks, the table menu and notifications. |
Notifications |
| ox_lib's notifications. |
3D prompt |
| The built-in 3D text on a dark backdrop. |
Every optional integration degrades silently. A missing resource makes its part fall back, never throw. The one to watch is the framework: if it starts after Arm Wrestling it is not found, and bets quietly take and pay nothing.
Frameworks#
The framework is picked from whichever of these is already started when Arm Wrestling starts:
Resource | Mode |
|---|---|
|
|
|
|
|
|
None of them |
|
Each mode has one file — custom/esx/server.lua, custom/qb/server.lua and custom/standalone/server.lua — and only the file for the detected mode is loaded. Every file fills in the same functions, all of them on the server:
Function | Decides |
|---|---|
| How much a player can bet. ESX reads the cash ( |
| Takes a bet when a challenge is accepted. |
| Pays the winner, or refunds a bet. |
| The name in the opponent list, on a challenge and in the messages. ESX uses the character's name, QBCore and Qbox the first and last name, standalone the FiveM name. |
| The player's identifier: the ESX |
Standalone says every player can afford any bet and takes nothing — fine for trying the script, not for a live economy.
Paying Bets From the Bank#
Bets come from cash by default. To use the bank account instead, change the three money functions in your framework's file:
-- custom/esx/server.lua
function framework:getMoney(source)
local xPlayer = self:getPlayerFromId(source)
if not xPlayer then return 0 end
return xPlayer.getAccount('bank').money
end
function framework:removeMoney(source, amount)
local xPlayer = self:getPlayerFromId(source)
if not xPlayer then return false end
xPlayer.removeAccountMoney('bank', amount)
return true
end
function framework:addMoney(source, amount)
local xPlayer = self:getPlayerFromId(source)
if not xPlayer then return false end
xPlayer.addAccountMoney('bank', amount)
return true
end-- custom/qb/server.lua
function framework:getMoney(source)
local player = self:getPlayerFromId(source)
if not player then return 0 end
return player.PlayerData.money.bank or 0
end
function framework:removeMoney(source, amount)
local player = self:getPlayerFromId(source)
if not player then return false end
return player.Functions.RemoveMoney('bank', amount, 'qs-armwrestling-bet')
end
function framework:addMoney(source, amount)
local player = self:getPlayerFromId(source)
if not player then return false end
return player.Functions.AddMoney('bank', amount, 'qs-armwrestling-win')
endRestart qs-armwrestling after saving. The interface keeps showing amounts with a $ sign.
A Custom Currency#
Bets can be paid in something other than money — casino chips, a VIP coin, tokens from your own script — by pointing the same three functions at it. With ox_inventory and a casino_chips item:
-- in the file of the framework you run: custom/esx, custom/qb or custom/standalone
function framework:getMoney(source)
return exports.ox_inventory:GetItemCount(source, 'casino_chips')
end
function framework:removeMoney(source, amount)
return exports.ox_inventory:RemoveItem(source, 'casino_chips', amount)
end
function framework:addMoney(source, amount)
return exports.ox_inventory:AddItem(source, 'casino_chips', amount)
endChange all three together.
addMoneyis how the winner is paid and how bets are refunded; leave it on money and a pot taken in chips is paid back in cash. Edit only the file of the framework you run — the others are never loaded.
Permissions#
Opening the creator, and every save, move and delete inside it, is checked on the server against one ace: Config.Creator.permission, command.armwrestlecreator unless you change it. Anything that grants that ace works:
# A group
add_ace group.admin command.armwrestlecreator allow
# Or one player directly
add_ace identifier.license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx command.armwrestlecreator allowA group that already has command allow covers it too. Restart the server after editing server.cfg, since aces are read when it is executed. Playing needs no permission at all.
Notifications and the Prompt#
Both are picked on their own — there is nothing to configure:
Part | With | Otherwise |
|---|---|---|
Notifications |
|
|
The table prompt |
| Drawn 3D text on a dark backdrop above the table. |
The table menu | ox_lib's context menu. | — |
Keys on screen | GTA V's own instructional buttons, during a match and while placing a table. | — |
For qs-textui, start it before qs-armwrestling in server.cfg.
Adding a Framework#
Supporting a framework that is not on the list takes one folder and one line.
Copy the closest bridge
Copy
custom/esx/orcustom/qb/to a folder named after your framework, for examplecustom/myframework/, keeping the file nameserver.lua.Change the calls inside
Fill in
getPlayerFromId,getIdentifier,getMoney,removeMoney,addMoneyandgetNamewith your framework's own functions. The file must end withreturn framework, as the originals do.Register it for detection
Add your framework's resource to the list at the top of
config.lua, pointing at the folder's name, and make sure it starts beforeqs-armwrestling.lua local frameworks = { -- resource name -> internal name ['es_extended'] = 'esx', ['qb-core'] = 'qb', ['qbx_core'] = 'qb', ['my_core'] = 'myframework', }
On the next start the console reports Server framework loaded: myframework. If the folder name does not match, an error is printed instead when the resource starts.
Languages#
41 translations ship in locales/: Arabic (ar), Bulgarian (bg), Bengali (bn), Catalan (ca), Czech (cs), Danish (da), German (de), Greek (el), English (en), Spanish (es), Estonian (et), Persian (fa), Finnish (fi), French (fr), Hebrew (he), Hindi (hi), Croatian (hr), Hungarian (hu), Indonesian (id), Italian (it), Japanese (ja), Korean (ko), Lithuanian (lt), Latvian (lv), Malay (ms), Dutch (nl), Norwegian (no), Polish (pl), Portuguese (pt), Romanian (ro), Russian (ru), Slovak (sk), Slovenian (sl), Swedish (sv), Swahili (sw), Thai (th), Turkish (tr), Ukrainian (uk), Urdu (ur), Vietnamese (vi) and Chinese (zh).
Config.Locale = 'es'One file translates the notifications and the whole interface, the creator included. To add a language, copy en.json to the new code, translate the values and set Config.Locale to it. Keep every key: a key missing from the file shows up in game as missing_<key>. A code with no file at all falls back to English.



