> For the complete documentation index, see [llms.txt](https://docs.cuxial.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cuxial.com/scripts/leisure/cuxial-gym/configuration.md).

# Configuration

Every option of Cuxial Gym explained: shared/config.lua, the data files and what is edited in game.

Cuxial Gym is adjusted in three places: `shared/config.lua` for behaviour, the `data/` files for factory values, and the in-game editors for everything that lives in the database. Restart the resource after changing a file.

{% hint style="info" %}
Zones, equipment, points, balance, supplements and business rules are edited in game with `/gymcreator` and `/gymadmin`. What you save there is stored in the database and replaces the matching section of the `data/` files.
{% endhint %}

## General

| Option  | Type    | Default | What it does                                                                                          |
| ------- | ------- | ------- | ----------------------------------------------------------------------------------------------------- |
| `debug` | boolean | `false` | Prints traces and SQL errors in detail. Also enabled by setting the convar `cuxial_gym_debug` to `1`. |

## Modules · `modules`

Switches for whole parts of the script. `true` loads the module, `false` leaves it out.

| Option         | Type    | Default | What it does                                                                                     |
| -------------- | ------- | ------- | ------------------------------------------------------------------------------------------------ |
| `business`     | boolean | `true`  | Businesses. With `false` the shop, business points, spotters and `/gymadmin` do not load either. |
| `shop`         | boolean | `true`  | Public shop of each business.                                                                    |
| `helper`       | boolean | `true`  | Spotters: employees helping a player who is training.                                            |
| `creator`      | boolean | `true`  | Zone creator and the `/gymcreator` command.                                                      |
| `admin`        | boolean | `true`  | Business admin panel and the `/gymadmin` command.                                                |
| `globalModels` | boolean | `true`  | Map props that work as equipment outside any zone.                                               |

## Interface · `ui`

| Option            | Type         | Default      | What it does                                                           |
| ----------------- | ------------ | ------------ | ---------------------------------------------------------------------- |
| `accent`          | string (hex) | configurable | Accent colour of the panels.                                           |
| `currency.symbol` | string       | `'$'`        | Currency symbol shown next to amounts.                                 |
| `currency.locale` | string       | `'en-US'`    | Number format for amounts, as a locale code (`'en-US'`, `'es-ES'`...). |

## Interface sounds · `sounds`

Volumes from `0.0` to `1.0`.

| Option    | Type   | Default | What it does               |
| --------- | ------ | ------- | -------------------------- |
| `master`  | number | `1.0`   | Multiplies all the others. |
| `click`   | number | `0.35`  | Click sound.               |
| `start`   | number | `0.6`   | Start sound.               |
| `success` | number | `0.7`   | Success sound.             |
| `fail`    | number | `0.7`   | Failure sound.             |

## Exercise sounds · `audio`

Sounds played in the world while training. They come from `cuxial_gym_assets`.

| Option           | Type    | Default      | What it does                                                           |
| ---------------- | ------- | ------------ | ---------------------------------------------------------------------- |
| `enabled`        | boolean | `true`       | `false` mutes every exercise sound.                                    |
| `networked`      | boolean | `false`      | `true` lets nearby players hear the hits and breaths of the character. |
| `volume`         | number  | `1.0`        | Volume factor from `0.0` to `1.0`.                                     |
| `debugCommand`   | string  | `'gymaudio'` | Test command, only registered in debug mode.                           |
| `breath.every`   | number  | `3`          | The character breathes once every this many reps.                      |
| `breath.delayMs` | number  | `600`        | Milliseconds after the rep starts before the breath plays.             |

`banks`, `breath.male`, `breath.female`, `rep` and `loops` hold the names of the sounds shipped with the assets. Leave them as they are.

## Logs · `logs`

| Option   | Type   | Default                | What it does                                                                            |
| -------- | ------ | ---------------------- | --------------------------------------------------------------------------------------- |
| `convar` | string | `'cuxial_gym_webhook'` | Name of the convar that holds the Discord webhook. The URL itself goes in `server.cfg`. |

## Staff · `admin` and `commands`

| Option                  | Type            | Default                | What it does                                             |
| ----------------------- | --------------- | ---------------------- | -------------------------------------------------------- |
| `admin.ace`             | string          | `'cuxial_gym.admin'`   | ACE permission that opens the business admin panel.      |
| `admin.creatorAce`      | string          | `'cuxial_gym.creator'` | ACE permission that opens the zone creator.              |
| `admin.permission`      | string          | `'admin'`              | Framework permission that grants both.                   |
| `admin.auditDays`       | number          | `60`                   | Days the staff audit log is kept.                        |
| `commands.admin.name`   | string \| false | `'gymadmin'`           | Command of the business admin panel. `false` removes it. |
| `commands.creator.name` | string \| false | `'gymcreator'`         | Command of the zone creator. `false` removes it.         |

## Keys · `keys`

Default keys. Each player can rebind them in the GTA key settings.

| Option         | Default    | What it does                                       |
| -------------- | ---------- | -------------------------------------------------- |
| `cancel`       | `'X'`      | Leaves the set, or stops spotting.                 |
| `accept`       | `'Y'`      | Accepts an offer or a call.                        |
| `decline`      | `'N'`      | Declines it.                                       |
| `peek`         | `'RSHIFT'` | Returns to the creator after looking at the world. |
| `gizmoConfirm` | `'RETURN'` | Confirms a placement.                              |
| `gizmoCancel`  | `'BACK'`   | Cancels it.                                        |
| `gizmoGround`  | `'LMENU'`  | Snaps the object to the ground.                    |
| `gizmoCursor`  | `'G'`      | Toggles the cursor while placing.                  |

## Placement camera · `gizmo`

Optional camera used while placing an object with the gizmo.

| Option         | Type   | Default | What it does                        |
| -------------- | ------ | ------- | ----------------------------------- |
| `distance`     | number | `5.0`   | Metres from the object.             |
| `height`       | number | `2.0`   | Metres above the object.            |
| `fov`          | number | `50.0`  | Field of view, in degrees.          |
| `transitionMs` | number | `500`   | Camera transition, in milliseconds. |

## Items and models · `items`, `models`

| Option              | Type      | Default                                   | What it does                                            |
| ------------------- | --------- | ----------------------------------------- | ------------------------------------------------------- |
| `items.imageUrl`    | string    | `'nui://ox_inventory/web/images/%s.webp'` | Where item images are read from. `%s` is the item name. |
| `models.pointProps` | string\[] | the gym screen prop                       | Props staff can pick for an interaction point.          |
| `models.pointPeds`  | string\[] | one sample ped                            | Ped models staff can pick for an interaction point.     |

## World · `world`, `globalModels`, `pedClear`, `points`

| Option                       | Type      | Default    | What it does                                                      |
| ---------------------------- | --------- | ---------- | ----------------------------------------------------------------- |
| `world.spawnDistance`        | number    | `150.0`    | Metres at which the equipment of a zone appears.                  |
| `world.despawnDistance`      | number    | `200.0`    | Metres at which it is removed.                                    |
| `world.tickMs`               | number    | `1000`     | Milliseconds between distance checks.                             |
| `world.removedPropsMs`       | number    | `5000`     | Milliseconds between sweeps of the map props a zone removes.      |
| `world.removedPropsDistance` | number    | `100.0`    | Radius of that sweep, in metres.                                  |
| `world.blipColors`           | number\[] | 30 colours | Blip colours offered in the creator.                              |
| `globalModels.range`         | number    | `75.0`     | Radius, in metres, in which map props are looked up as equipment. |
| `globalModels.intervalMs`    | number    | `3000`     | Milliseconds between look-ups.                                    |
| `pedClear.intervalMs`        | number    | `5000`     | Milliseconds between sweeps of ambient peds inside the zones.     |
| `pedClear.edgeBuffer`        | number    | `5.0`      | Extra metres added to the radius of each clearing area.           |
| `points.spawnDistance`       | number    | `75.0`     | Metres at which the prop or ped of a point exists.                |
| `points.maxDistance`         | number    | `5.0`      | Maximum distance the server accepts for an action.                |
| `points.targetDistance`      | number    | `2.0`      | Interaction distance of a point that has no radius of its own.    |

## Gym panel · `panel` and `tablet`

| Option                      | Type      | Default                       | What it does                                                                                                                                                    |
| --------------------------- | --------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `panel.maxDistance`         | number    | `10.0`                        | Maximum metres from a gym menu point to open the panel or buy a pass.                                                                                           |
| `panel.leaderboardSize`     | number    | `10`                          | Rows of each leaderboard.                                                                                                                                       |
| `panel.leaderboardSeconds`  | number    | `60`                          | Seconds a leaderboard is cached.                                                                                                                                |
| `tablet.dui`                | boolean   | `true`                        | `true` draws the panel on the screen prop in the world. `false` always opens it as a full-screen interface.                                                     |
| `tablet.range`              | number    | `25.0`                        | Metres at which the screen shows its idle image. The idle image carries the brand of the locale key `UI_TABLET_BRAND`, `GYM` by default; edit it in `locales/`. |
| `tablet.prewarmDistance`    | number    | `6.0`                         | Metres at which the screen starts loading the panel.                                                                                                            |
| `tablet.maxDistance`        | number    | `3.0`                         | Maximum metres to open the screen and stay in it.                                                                                                               |
| `tablet.cursor.mode`        | string    | `'native'`                    | `'native'` projects the game cursor on the screen. `'virtual'` draws a pointer moved with the mouse.                                                            |
| `tablet.cursor.sensitivity` | number    | `1.0`                         | Speed of the virtual pointer.                                                                                                                                   |
| `tablet.wheelStep`          | number    | `120`                         | Scroll units per wheel notch. A negative value inverts it.                                                                                                      |
| `tablet.exitKeys`           | number\[] | Esc, Backspace and controller | Game controls that close the screen.                                                                                                                            |

{% hint style="warning" %}
`tablet.model`, `txd`, `texture`, `offset`, `yaw`, `pitch`, `width`, `height`, `idle`, `session` and `camera` match the screen prop shipped with the assets. Do not change them.
{% endhint %}

## Minigames · `minigame`

| Option        | Type   | Default              | What it does                                                                                                      |
| ------------- | ------ | -------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `ui.position` | string | `'bottom-right'`     | Corner where the minigame is drawn: `'bottom-right'`, `'bottom-left'`, `'top-right'`, `'top-left'` or `'center'`. |
| `ui.scale`    | number | `0.8`                | Size of the minigame. `1` is its natural size.                                                                    |
| `ui.offset`   | table  | `{ x = 24, y = 24 }` | Distance from the screen edge, in pixels.                                                                         |

## Memberships · `membership`

| Option                  | Type   | Default  | What it does                       |
| ----------------------- | ------ | -------- | ---------------------------------- |
| `account`               | string | `'cash'` | Account passes are charged to.     |
| `rewardCooldownSeconds` | number | `86400`  | Seconds between two daily rewards. |
| `maxPackages`           | number | `10`     | Maximum packages per zone.         |

## Exercise · `exercise`

| Option               | Type   | Default       | What it does                                                       |
| -------------------- | ------ | ------------- | ------------------------------------------------------------------ |
| `startDistance`      | number | `4.0`         | Maximum metres from the equipment to start.                        |
| `maxDistance`        | number | `6.0`         | Beyond this distance the set ends.                                 |
| `minRepMs`           | number | `750`         | Minimum milliseconds between two reps.                             |
| `minigameMinMs`      | number | `3000`        | Minimum duration the server accepts for a minigame.                |
| `autoPassMs`         | number | `500`         | Minimum duration of an auto-passed rep.                            |
| `toleranceMs`        | number | `250`         | Network tolerance applied to those minimums.                       |
| `idleTimeoutSeconds` | number | `120`         | Seconds without reps after which the server closes the set.        |
| `defaultMaxReps`     | number | `20`          | Rep count used to scale difficulty when the exercise has no limit. |
| `anchorModel`        | string | `'prop_tick'` | Internal prop used to sync the exercise. Leave it as it is.        |

## Stats, perks and supplements

| Option                  | Type    | Default          | What it does                                                                                                                                     |
| ----------------------- | ------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `stats.baseMaxHealth`   | number  | `200`            | Base maximum health of the character. The strength bonus is added on top.                                                                        |
| `stats.xpBonusToStats`  | boolean | `false`          | `true` applies the XP bonus of supplements and streak to strength and agility XP. `false` applies it only to perk XP.                            |
| `perks.enabled`         | boolean | `false`          | `true` turns on the perk tree: training earns perk points to spend on permanent bonuses. With `false` perks give nothing and cannot be unlocked. |
| `perks.xpPerPoint`      | number  | `500`            | XP needed for one perk point.                                                                                                                    |
| `supplements.useMs`     | number  | `4000`           | Milliseconds it takes to consume a supplement.                                                                                                   |
| `supplements.stackSame` | boolean | `true`           | `true` lets two doses of the same supplement add up. `false` makes a new dose replace the previous one.                                          |
| `supplements.anim`      | table   | eating animation | Animation played while consuming: `dict` and `clip`.                                                                                             |

## Spotters, tutorial and previews

| Option               | Type      | Default            | What it does                                                                     |
| -------------------- | --------- | ------------------ | -------------------------------------------------------------------------------- |
| `helper.maxDistance` | number    | `3.0`              | Maximum metres between the spotter and the player who trains.                    |
| `helper.animSwapMs`  | number\[] | `{ 10000, 15000 }` | Minimum and maximum milliseconds between changes of the spotter's animation.     |
| `tutorial.enabled`   | boolean   | `true`             | Factory value of the guided tour of the gym panel. Staff can change it in game.  |
| `previews.enabled`   | boolean   | `false`            | `true` shows a preview video of each exercise in the panel.                      |
| `previews.baseUrl`   | string    | `''`               | Base address of the videos. The final address is `baseUrl` + clip + `extension`. |
| `previews.extension` | string    | `'.mp4'`           | File extension of the videos.                                                    |
| `previews.clips`     | table     | `{}`               | Clip name per exercise.                                                          |

## Lockers and cloakroom

| Option               | Type   | Default      | What it does                                                                                                                                          |
| -------------------- | ------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locker.slots`       | number | `20`         | Slots of the personal locker of each zone.                                                                                                            |
| `locker.weight`      | number | `30000`      | Maximum weight, in grams.                                                                                                                             |
| `cloakroom.handlers` | table  | one wardrobe | Actions a cloakroom point can run. Each entry has a `label` (locale key) and either `export = { 'resource', 'function' }` or `event = 'clientEvent'`. |

To open your own clothing menu from a cloakroom point:

{% code title="shared/config.lua" %}

```lua
cloakroom = {
    handlers = {
        wardrobe = { label = 'cloak_wardrobe', event = 'my_clothing:client:openWardrobe' },
    },
},
```

{% endcode %}

## Businesses · `business` and `shop`

| Option                                | Type         | Default     | What it does                                               |
| ------------------------------------- | ------------ | ----------- | ---------------------------------------------------------- |
| `business.account`                    | string       | `'cash'`    | Account used for deposits, withdrawals and bonus payments. |
| `business.lowStock`                   | number       | `5`         | Stock level from which the panel warns of low stock.       |
| `business.offerDistance`              | number       | `10.0`      | Maximum metres to offer a contract or a transfer.          |
| `business.gradeColor`                 | string (hex) | `'#4299e1'` | Colour of a newly created grade.                           |
| `business.maxHourlyWage`              | number       | `5000`      | Highest hourly wage a grade can have.                      |
| `business.maxGrades`                  | number       | `12`        | Maximum number of grades.                                  |
| `business.historySize`                | number       | `100`       | Transactions kept in memory per business.                  |
| `business.historyDays`                | number       | `90`        | Days transactions are kept in the database.                |
| `business.offerSeconds`               | number       | `60`        | Seconds until an offer expires.                            |
| `business.stash.slots`                | number       | `50`        | Slots of the business stashes.                             |
| `business.stash.weight`               | number       | `100000`    | Maximum weight, in grams.                                  |
| `business.callWorker.cooldownSeconds` | number       | `600`       | Seconds between two calls to the staff of a business.      |
| `business.callWorker.seconds`         | number       | `15`        | Seconds staff have to accept a call.                       |
| `business.workers.restockAmount`      | number       | `5`         | Units the restock worker orders each time.                 |
| `business.workers.collectorSeconds`   | number       | `900`       | Seconds between passes of the collector worker.            |
| `business.workers.periodSeconds`      | number       | `86400`     | Length of the period automatic workers are charged for.    |
| `shop.account`                        | string       | `'cash'`    | Account shop purchases are charged to.                     |
| `shop.maxCartLines`                   | number       | `30`        | Maximum lines in a cart.                                   |
| `shop.maxAmount`                      | number       | `100`       | Maximum units per line.                                    |

## Limits · `limits`

Caps on what staff can save from the editors.

| Option                | Default | Limits                                  |
| --------------------- | ------- | --------------------------------------- |
| `equipmentPerZone`    | `300`   | Pieces of equipment per zone            |
| `removedPropsPerZone` | `500`   | Map props removed per zone              |
| `pointsPerOwner`      | `50`    | Interaction points per zone or business |
| `pedClearAreas`       | `10`    | Ped clearing areas per zone             |
| `presets`             | `50`    | Minigame presets                        |
| `supplements`         | `64`    | Supplements                             |
| `effects`             | `8`     | Effects per supplement                  |
| `warehouseItems`      | `200`   | Items in the warehouse catalogue        |
| `achievements`        | `200`   | Achievements                            |

`compat` maps skill names used by older resources to the two stats. See [Exports & events](/scripts/leisure/cuxial-gym/developers.md#compatibility-exports).

## Data files · `data/`

Factory values. Most are also editable in game; once a section is saved from an editor, the file is no longer read for that section. In the creator, *Reset to defaults* goes back to the file values.

| File                                            | Holds                                                                                                            | Editable in game                          |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
| `data/defaults.lua`                             | Fatigue limit, stat levels and bonuses, daily decay, streak bonuses                                              | Creator, Gym config                       |
| `data/bodyparts.lua`                            | Fatigue cap, recovery per minute and XP weights of the seven body parts                                          | Creator, Gym config                       |
| `data/achievements.lua`                         | The 45 achievements                                                                                              | Creator, Gym config                       |
| `data/supplements.lua`                          | Item, duration and effects of each supplement                                                                    | Creator, Supplements                      |
| `data/business.lua`                             | Default grades, colour palette, business settings, progression, warehouse catalogue, workers and shop categories | Business admin, except grades and palette |
| `data/perks.lua`                                | The perk tree                                                                                                    | No                                        |
| `data/minigames.lua`                            | Settings of each minigame per difficulty level                                                                   | No                                        |
| `data/exercises.lua` and `data/exercises/*.lua` | Exercise list and the definition of each one                                                                     | Per-rep values, in Gym config             |
| `data/helper.lua`                               | Animations of the spotter                                                                                        | No                                        |
| `data/names.lua`                                | Random supplier names shown on warehouse orders                                                                  | No                                        |
| `data/seed.lua`                                 | Sample zone and minigame presets inserted on first start                                                         | No                                        |

{% hint style="warning" %}
`data/seed.lua` is read once, when the zones table is empty. Editing it later changes nothing. The exercise files define animations and prop offsets that match the shipped assets: change the numbers at the top (`xpPerRep`, `fatiguePerRep`, `maxReps`, `repInterval`) and leave the rest.
{% endhint %}

## Common changes

### Charge memberships and the shop to the bank

{% code title="shared/config.lua" %}

```lua
membership = { account = 'bank', rewardCooldownSeconds = 86400, maxPackages = 10 },
shop = { account = 'bank', maxCartLines = 30, maxAmount = 100 },
```

{% endcode %}

### Run gyms without businesses

{% code title="shared/config.lua" %}

```lua
modules = { business = false, shop = false, helper = false, creator = true, admin = false, globalModels = true },
```

{% endcode %}

### Always open the panel as a full-screen interface

Set `dui = false` inside the `tablet` block and leave the other values untouched.

### Add a supplement

1. Add the item to your inventory.
2. Open `/gymcreator`, go to **Supplements**, add the item and set its duration and effects.

### Rename the commands

{% code title="shared/config.lua" %}

```lua
commands = { admin = { name = 'gymbiz' }, creator = { name = 'gymzones' } },
```

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.cuxial.com/scripts/leisure/cuxial-gym/configuration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
