> For the complete documentation index, see [llms.txt](https://rtx-dev.gitbook.io/rtxdev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://rtx-dev.gitbook.io/rtxdev/rtx-realistic-gym-system/installation.md).

# Installation

{% hint style="info" %}
**Before you start.** Make sure your server artifacts are up to date, and that you have access to your database.
{% endhint %}

## Required database dependency

The gym stores gyms, passes and player stats, so it needs one of these.

✅ **Recommended:** [`oxmysql`](https://github.com/overextended/oxmysql)

⚠️ **Alternative:** [`mysql-async`](https://github.com/brouznouf/fivem-mysql-async) — if you use this one, open `fxmanifest.lua` and swap the two commented lines in `server_scripts`.

## Resource setup

{% stepper %}
{% step %}

### Download

Download the asset from the CFX Asset Portal.
{% endstep %}

{% step %}

### Place the resources

| Resource                    | What it is           |
| --------------------------- | -------------------- |
| `rtx_realistic_gym`         | The script           |
| `rtx_realistic_gym_objects` | The models and props |
| `rtx_realistic_gym_mlos`    | The two custom gyms  |

All three are part of the product. Put them in your resources folder.
{% endstep %}

{% step %}

### Add them to server.cfg

```cfg
ensure rtx_realistic_gym_objects
ensure rtx_realistic_gym_mlos
ensure rtx_realistic_gym
```

{% hint style="warning" %}
**Order matters.** The objects and the MLOs have to start **before** the script. Two of the gyms that ship with the resource are built inside those MLOs, and a gym whose map is not installed is never created — the console says which one it skipped and what it was waiting for.
{% endhint %}
{% endstep %}

{% step %}

### Optional: a target system

The gym works on its own with the key prompt. If your server uses `ox_target`, `qb-target` or `qtarget`, see [Configuration → config.lua](/rtxdev/rtx-realistic-gym-system/configuration-files/config.lua.md).
{% endstep %}
{% endstepper %}

## Framework selection

Open `config.lua`, **section 1**, and select the framework mode:

```lua
Config.Framework = "standalone"   -- esx / qbcore / standalone
```

The block of the same name in `Config.Frameworks` below it is the **only one that is read**. If you run QBCore, nothing in the `esx` block matters and you can leave it exactly as it is.

### ESX

Select `esx` if your server uses **ESX / es\_extended**.

```lua
esx = {
    resource = "es_extended",
    playerloaded = "esx:playerLoaded",
    newversion = true,
    getsharedobject = "esx:getSharedObject"
}
```

{% hint style="info" %}
`newversion` stays **true** on any current ESX. Set it to `false` only for an ESX old enough to hand the shared object out through an event instead of an export — and only then does `getsharedobject` matter.

Turning it off is what *causes* the old SharedObject errors, not what fixes them.
{% endhint %}

### QBCore

Select `qbcore` if your server uses **QBCore**.

```lua
qbcore = {
    resource = "qb-core",
    playerloaded = "QBCore:Client:OnPlayerLoaded"
}
```

Change `resource` only if your core folder is not called `qb-core`.

### Qbox

**Qbox is fully supported.** Select `qbcore` and change nothing else.

```lua
Config.Framework = "qbcore"
```

Qbox ships a QB-Core compatibility bridge that is **enabled by default**, so `qb-core` exports and `QBCore:Client:OnPlayerLoaded` both work exactly as they do on QBCore.

{% hint style="success" %}
Qbox uses **ox\_inventory**, so set `Config.Inventory.system = "ox"` and use `[Items]/OX-ITEMS.lua`.
{% endhint %}

### Standalone

Select `standalone` if your server uses no framework, or one that is not on this list.

```lua
standalone = {
    playerloaded = "playerLoaded"
}
```

{% hint style="warning" %}
**Nothing fires `playerLoaded` on its own.** Trigger it from whatever your server uses to say a player is in, or the gym waits for him forever.

You also write the money and inventory logic yourself, in `server/other.lua`. It is open source, and the ESX and QBCore branches already in it are your examples — every function has one of each.
{% endhint %}

## Inventory

In the same section:

```lua
Config.Inventory = {
    system = "ox",        -- ox / framework
    qbnewversion = false
}
```

{% tabs %}
{% tab title="ox\_inventory" %}

```lua
Config.Inventory.system = "ox"
```

Use `[Items]/OX-ITEMS.lua`. This is also the right setting on **Qbox**.
{% endtab %}

{% tab title="qb-inventory" %}

```lua
Config.Inventory.system = "framework"
Config.Inventory.qbnewversion = true    -- newer qb-inventory
Config.Inventory.qbnewversion = false   -- older qb-inventory
```

{% hint style="danger" %}
The two versions take their item arguments differently and getting it wrong is **silent** — the item simply never arrives. If supplements are not turning up, this is the first line to check.
{% endhint %}
{% endtab %}

{% tab title="ESX inventory" %}

```lua
Config.Inventory.system = "framework"
```

Import `[Items]/ESX-ITEMS.sql`.
{% endtab %}

{% tab title="Anything else" %}
These two lines only pick between the inventories `server/other.lua` already knows.

**What actually moves an item** is that file. It is open source, and adding your own inventory is three functions: `AddItemRTX`, `RemoveItemRTX`, `GetItemCountRTX`.
{% endtab %}
{% endtabs %}

## Database

**No import is required.** The resource creates its tables the first time it starts.

If you would rather set the database up by hand, import `install.sql`.

<details>

<summary>Tables it uses</summary>

| Table            | What is in it                                                               |
| ---------------- | --------------------------------------------------------------------------- |
| `rtx_gyms`       | Every gym: name, address, mode, price, owner, balance, and its whole layout |
| `rtx_gym_passes` | Who has a pass to which gym and when it runs out                            |
| `rtx_gym_stats`  | Every player's stats, energy and totals                                     |
| `rtx_gym_log`    | Entries and earnings per gym per day, for the management panel              |

</details>

## Items setup

Go to the `[Items]` folder and install the items for your inventory.

{% tabs %}
{% tab title="ox\_inventory" %}
Copy `OX-ITEMS.lua` into `ox_inventory/data/items.lua`.

{% hint style="danger" %}
ox\_inventory has no `RegisterUsableItem`, so every one of these items points at this resource's own export:

```lua
server = {export = "rtx_realistic_gym.UseGymItem"},
```

That line is what makes the item do anything. Without it the item exists and using it is silent.
{% endhint %}
{% endtab %}

{% tab title="QBCore" %}
Copy `QBCORE-ITEMS.lua` into `qb-core/shared/items.lua`.
{% endtab %}

{% tab title="ESX" %}
Import `ESX-ITEMS.sql` into your database.
{% endtab %}
{% endtabs %}

**Items:** `gympass`, `water`, `energydrink`, `proteinshake`, `proteinbar`, `creatine`, `preworkout`, `bcaa`, `vitamins`, `testosterone`

Icons go in your inventory's own image folder.

{% hint style="info" %}
`testosterone` is deliberately not sold in any gym store. Where it comes from is up to you — a dealer, a heist, an admin command:

```lua
exports.rtx_realistic_gym:GiveGymSupplement(source, "testosterone", 1)
```

{% endhint %}

## Who may build gyms

Out of the box the creator belongs to whoever your `server.cfg` gives `gymcreator.use` to:

```cfg
add_ace group.admin gymcreator.use allow
add_principal identifier.license:YOURLICENSE group.admin
```

You can also open it to a job, or to named people by licence, steam or discord id — `config.lua`, **section 5**.

{% hint style="success" %}
If the creator refuses you, the **server console** prints exactly which check said no, and your own identifiers, ready to paste.
{% endhint %}

## That is it

Type `/gymcreator` in game and build one. See [Building your first gym](broken://pages/a2e94542d5b555d14eb91f639892085796afcc48).
