How Integrations Work#
Gym Creator reaches every third-party resource through a small open file — a bridge — and picks the right one at boot by looking at what is already running. The bridges are not encrypted, so anything the script does with your framework or target can be read and changed.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Required. The resource stops at boot without one. |
Database |
| Required. |
Library |
| Required. |
Target |
| A built-in |
HUD |
| The minimap is still hidden while the creator is open. |
Inventory quests |
| Nothing — the quests are opt-in. |
Discord logs | Any Discord webhook | No logs are sent. |
Start order matters. Detection only sees resources that are already running, so every resource on this page must be
ensured above Gym Creator inserver.cfg.
Frameworks#
Framework | Bridge | Character id | Admins |
|---|---|---|---|
ESX ( |
|
| Groups |
QBCore ( |
|
| Permissions |
Qbox ( |
|
| Same as QBCore. |
Payments use the framework's own accounts: Cash is money on ESX and cash on QBCore / Qbox, Bank is bank on both.
A renamed or custom framework#
If your core runs under another name, add it to the list at the top of config/main.lua, pointing to the bridge it is compatible with:
local frameworks = {
['es_extended'] = 'esx',
['qb-core'] = 'qb',
['qbx_core'] = 'qb',
['my-core'] = 'qb', -- a QBCore fork under another name
}For a framework that is compatible with neither, copy custom/qb/ to custom/<name>/, change the calls inside — player, identifier, job, money, admin — and map your resource to <name> in the same list.
Who counts as an admin#
playerIsAdmin in custom/esx/server.lua and custom/qb/server.lua decides who may open the creator besides the jobs in Config.CreatorJobs. To let ESX moderators in too:
function framework:playerIsAdmin(source)
local group = self:getPlayerFromId(source).getGroup()
return group == 'admin' or group == 'superadmin' or group == 'mod'
endTarget Systems#
The receptionist and every station are registered with the first of these that is running:
Priority | Resource | How it looks |
|---|---|---|
1 |
| An eye option on the receptionist, and a box zone of 1.5 m on each station. |
2 |
| The same, through the qtarget API. |
3 |
| The same, through the qb-target API. |
4 |
| A floating |
5 | Built-in | The same |
Config.TargetDistance (2.0 by default) sets how close a player must be in every mode. The options use the fa-solid fa-dumbbell icon.
To support another target resource, add a branch to client/custom/target/main.lua. It only needs to fill in five functions — addLocalEntity, removeLocalEntity, addBoxZone, removeZone and destroyAll — and add its name to detect() at the top of the file.
Notifications and the HUD#
Messages such as "Membership purchased." or "Workout cancelled." are shown by the script's own toasts, styled like its windows, so no notification resource is needed. To send them through your own system instead, replace Notification in custom/client.lua:
function Notification(msg, type)
exports['okokNotify']:Alert('Gym', msg, 5000, type)
endWhile the creator is open the minimap is hidden, and so is the qs-interface HUD when it is running. That happens in ToggleHud in the same file, if you want to hide your own HUD too.
Inventory Quests#
With qs-inventory and its quest system, set Config.UseInventoryQuests = true and every finished set reports progress to these quests:
Quest | Progresses when |
|---|---|
| Any set is finished. |
| A set of that exercise is finished — |
| Strength is at 50 or 100 after a set. |
| Stamina is at 50 or 100 after a set. |
The quests themselves are defined in qs-inventory; Gym Creator only reports to the ones that exist.
Discord Logs#
Creator actions and membership purchases can be posted to Discord as embeds with the player's name, server id and identifiers (Steam, Discord, license, FiveM…). The URLs go in server/webhooks.lua:
Config.ShowWebhookIP = false -- true adds the player's IP to every log
_G['webhook'] = {
creator = 'https://discord.com/api/webhooks/...', -- gyms created, updated and deleted
membership = 'https://discord.com/api/webhooks/...', -- memberships bought, with the gym and the price
exercise = '',
}Channel | What goes there |
|---|---|
| Gym created, Gym updated and Gym removed — the admin who did it and the gym's id. |
| Membership purchased — the player, the gym and the price paid. |
Leave a URL empty and that log is not sent. Logs are queued and sent at Discord's pace, so a burst of activity never stalls the server.
Languages#
28 translations ship in locales/: Arabic (ar), Bulgarian (bg), Catalan (ca), Czech (cs), Danish (da), German (de), Greek (el), English (en), Spanish (es), Persian (fa), French (fr), Hindi (hi), Hungarian (hu), Italian (it), Japanese (ja), Korean (ko), Dutch (nl), Norwegian (no), Polish (pl), Portuguese (pt), Romanian (ro), Russian (ru), Slovenian (sl), Swedish (sv), Thai (th), Turkish (tr), Simplified Chinese (zh-CN) and Traditional Chinese (zh-TW).
Set the language in config/main.lua:
Config.Locale = 'es'To add another, copy en.json to the new code, translate it and set Config.Locale to that code. Anything left untranslated falls back to English, and the console says which keys are missing.



