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

# Installation

Install the Multiplayer Diving Job, or update an older version to 3.0.

{% hint style="warning" %}
**Updating from 1.x?** Skip to [Updating from 1.x](#updating-from-1-x). Do **not** delete your old folder.
{% endhint %}

***

## Prerequisites

| Requirement      | Description                                                    |
| ---------------- | -------------------------------------------------------------- |
| **tw-lib**       | Free Tworst library, version 1.0.0 or newer                    |
| **oxmysql**      | Database                                                       |
| **FiveM Server** | A recent server build (OneSync on, as txAdmin sets by default) |

***

## Step 1: Download

### From Cfx.re Portal

1. Go to [portal.cfx.re](https://portal.cfx.re) → **Granted Assets**
2. Download **tw-diving** and **tw-lib**

{% hint style="info" %}
**tw-lib** is free and comes with every Tworst job. You can also download it from [GitHub Releases](https://github.com/Tworst-Shop/tw-lib/releases/latest). Download the `tw-lib-x.x.x.zip` file there, not "Code → Download ZIP" (that folder is named `tw-lib-main` and the jobs will not find it).
{% endhint %}

***

## Step 2: Extract Files

Put these two folders into your `resources` directory:

```
resources/
├── tw-lib/                     ← Tworst library (REQUIRED)
└── tw-diving/                  ← The job
    ├── defaults/
    │   ├── config.lua          # Settings, dive sites, market, loot
    │   └── locales/            # Texts (7 languages)
    ├── hooks/                  # Your own functions (survive updates)
    ├── client/  server/  shared/  html/
    ├── stream/                 # Lift bag prop
    ├── ITEM-IMG/               # Item images
    ├── qb-item.txt  ox-item.txt
    └── fxmanifest.lua
```

{% hint style="danger" %}
The folder names must stay exactly `tw-lib` and `tw-diving`.
{% endhint %}

***

## Step 3: Database

{% hint style="success" %}
**Nothing to import.** On first start the job creates `tw_diving` (player levels, daily missions, history) and tw-lib creates its own tables (`tw_lib_settings`, `tw_lib_players`, `tw_lib_ledger`, `tw_lib_ledger_daily`, `tw_lib_job_history`).
{% endhint %}

***

## Step 4: Add Items

### QBCore / QBox

Add to `qb-core/shared/items.lua` (also in `qb-item.txt`):

```lua
["scuba_tube_l1"] = { name = "scuba_tube_l1", label = "Scuba Tube 1", weight = 1000, type = "item", image = "diving-tube-level1.png", unique = true, useable = true, shouldClose = true, description = "An oxygen tube and a rebreather" },
["scuba_tube_l2"] = { name = "scuba_tube_l2", label = "Scuba Tube 2", weight = 2000, type = "item", image = "diving-tube-level2.png", unique = true, useable = true, shouldClose = true, description = "An oxygen tube and a rebreather" },
["scuba_tube_l3"] = { name = "scuba_tube_l3", label = "Scuba Tube 3", weight = 3000, type = "item", image = "diving-tube-level3.png", unique = true, useable = true, shouldClose = true, description = "An oxygen tube and a rebreather" },
["scuba_gear"] = { name = "scuba_gear", label = "Scuba Gear", weight = 500, type = "item", image = "scuba_gear.png", unique = true, useable = true, shouldClose = true, description = "An oxygen tank and a rebreather" },
["liftbag"] = { name = "liftbag", label = "Lift Bag", weight = 1000, type = "item", image = "liftbag.png", unique = true, useable = true, shouldClose = true, description = "A lift bag to lift heavy objects" },
["dendrogyra_coral"] = { name = "dendrogyra_coral", label = "Dendrogyra", weight = 1000, type = "item", image = "dendrogyra_coral.png", unique = false, useable = false, shouldClose = true, description = "Also known as pillar coral" },
["antipatharia_coral"] = { name = "antipatharia_coral", label = "Antipatharia", weight = 1000, type = "item", image = "antipatharia_coral.png", unique = false, useable = false, shouldClose = true, description = "Also known as black or thorn corals" },
```

### ox\_inventory

Add to `ox_inventory/data/items.lua` (also in `ox-item.txt`):

```lua
["scuba_tube_l1"] = { label = "Scuba Tube 1", weight = 1000, stack = false, close = true, description = "An oxygen tube and a rebreather", client = { image = "diving-tube-level1.png" } },
["scuba_tube_l2"] = { label = "Scuba Tube 2", weight = 2000, stack = false, close = true, description = "An oxygen tube and a rebreather", client = { image = "diving-tube-level2.png" } },
["scuba_tube_l3"] = { label = "Scuba Tube 3", weight = 3000, stack = false, close = true, description = "An oxygen tube and a rebreather", client = { image = "diving-tube-level3.png" } },
["scuba_gear"] = { label = "Scuba Gear", weight = 500, stack = false, close = true, description = "An oxygen tank and a rebreather", client = { image = "scuba_gear.png" } },
["liftbag"] = { label = "Lift Bag", weight = 1000, stack = true, close = true, description = "A lift bag to lift heavy objects", client = { image = "liftbag.png" } },
["dendrogyra_coral"] = { label = "Dendrogyra", weight = 1000, stack = true, close = true, description = "Also known as pillar coral", client = { image = "dendrogyra_coral.png" } },
["antipatharia_coral"] = { label = "Antipatharia", weight = 1000, stack = true, close = true, description = "Also known as black or thorn corals", client = { image = "antipatharia_coral.png" } },
```

### Other inventories

Add the same seven items the way your inventory expects.

### Loot and market items

The suitcases and boxes give `rolex`, `diamond_ring` and `goldbar`, and the market sells `weapon_knife` (the knife that opens suitcases). They are not part of the job's item files. Check that they exist in your inventory; if one is missing, that loot or purchase is not given.

### Item Images

Copy the images from `tw-diving/ITEM-IMG/` into your inventory's image folder (for example `qb-inventory/html/images/` or `ox_inventory/web/images/`).

***

## Step 5: server.cfg

```cfg
ensure oxmysql
ensure qb-core              # your framework, if any
# ... your inventory, keys, fuel, clothing, target scripts

ensure tw-lib               # before every Tworst job
ensure tw-diving
```

{% hint style="warning" %}
**Start order matters:** `tw-lib` must start **before** `tw-diving`. If the job starts first, tw-lib restarts it once by itself and prints a warning. Fix the order anyway.
{% endhint %}

***

## Step 6: Start & Check

Start the server and look at the console:

```
[tw-lib] server loaded
[tw-lib] 1.0.0 | framework=qb | inventory=qb-inventory | keys=qs-vehiclekeys | fuel=LegacyFuel | clothing=qb-clothing
[tw-lib] up to date: tw-lib 1.0.0, tw-diving 3.0.0
```

* The second line shows what tw-lib detected. If something is wrong there, see [Troubleshooting](#troubleshooting).
* The last line appears a few seconds later. If a new version exists it says `update available` instead.

Then in game: go to the diving NPC (default: Paleto Bay), open a lobby and start.

***

## Admin Menu Permission

`/twlib` opens the Tworst admin menu for players with the `tw-lib.admin` ace. QBCore / QBox admins (`god`, `admin`) and ESX admins (`admin`, `superadmin`) are allowed automatically. For anyone else, add to `server.cfg`:

```cfg
add_ace group.admin tw-lib.admin allow
```

You can also list players by identifier in `tw-lib/config.lua`, and set the menu language there. See [tw-lib → Admin Menu](/tw-lib/tw-lib/admin-menu.md) for what each page of the menu does.

***

## Updating from 1.x

1. Stop the server (or the resource).
2. Download the new `tw-diving` **and** `tw-lib`.
3. **Copy the new `tw-diving` over your old folder.** Do not delete the old folder first: tw-lib reads your old `config/config.lua` and `config/locales.lua` once and keeps every value you had changed (money, XP, language, texts, coordinates).
4. Add `ensure tw-lib` before `ensure tw-diving` in `server.cfg`.
5. Start the server. The console lists what was imported. Your players' levels and history in `tw_diving` are kept.

{% hint style="info" %}
From 3.0 on, updates are simple: copy the new folder over the old one. Your settings are stored in the database (`tw_lib_settings`), so nothing you changed is lost.
{% endhint %}

{% hint style="warning" %}
Options that are functions (`Config.EndJob`, `Config.Notification`, `Config.ProgressBar`) are not imported. Move your code into `hooks/my-hooks.lua` (see [Configuration → Hooks](/scripts/diving-job/configuration.md#hooks)).
{% endhint %}

{% hint style="info" %}
The lift bag prop now ships inside `tw-diving`, so the separate `Liftbag-model` resource from 1.x is no longer needed. Remove its `ensure Liftbag-model` line from `server.cfg`.
{% endhint %}

***

## Troubleshooting

### `Could not find dependency tw-lib for resource tw-diving`

tw-lib is not installed or not started. Install it (Step 1) and `ensure tw-lib` before the job.

### `tw-diving needs tw-lib X or newer`

Your tw-lib is older than the job needs. Download the latest from [GitHub](https://github.com/Tworst-Shop/tw-lib/releases/latest) or the Cfx.re portal and replace the `tw-lib` folder.

### Wrong framework / inventory / keys / fuel / clothing detected

Look at the `[tw-lib] 1.0.0 | framework=...` line. If a script you use is not there, check that it is started, and that its folder name is the original one. To force a choice: `twlib set tw-lib bridge.inventory ox_inventory` in the server console (same for `framework`, `keys`, `fuel`, `clothing`), then restart tw-lib.

### Suitcases do not open

The player needs a knife (`WEAPON_KNIFE` by default, sold in the market). The weapon is set with `Config.OpenSuitCaseWeapon`.

### Items are not given

The items are missing from your inventory. See Step 4. Item names are case-sensitive.

***

## Need Help?

{% hint style="info" %}
Open a ticket on our [Discord](https://discord.gg/tworst) with the `[tw-lib] ...` status line from your console and any red error lines.
{% endhint %}
