> For the complete documentation index, see [llms.txt](https://mole-resource.gitbook.io/mole-resource-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mole-resource.gitbook.io/mole-resource-docs/scripts/4-in-line/installation.md).

# Installation

## 1. Drop the resources

Place both resources in your server:

```
resources/
├── mr_4inline        # the script
└── mr_4inline_3d     # the streamed models (board + discs)
```

## 2. Import the database

Import [`sql.sql`](broken://pages/bd60249356b3f5b9e31dcf14e0537bd150dbb6f6) into your database. It creates the `fourinline_boards` table:

```sql
CREATE TABLE IF NOT EXISTS `fourinline_boards` (
    `id`       INT(11)      NOT NULL AUTO_INCREMENT,
    `x`        FLOAT        NOT NULL,
    `y`        FLOAT        NOT NULL,
    `z`        FLOAT        NOT NULL,
    `rotation` FLOAT        NOT NULL DEFAULT 0,
    `grid`     CHAR(42)     NOT NULL DEFAULT '------------------------------------------',
    `turn`     CHAR(1)      NOT NULL DEFAULT 'X',
    `instance` VARCHAR(64)  DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```

`grid` holds one character per cell — 42 for the default 7×6 board. If you change `Config.Grid`, widen the column to match `Columns × Rows`.

## 3. Start order

The model resource must start **before** the script. In your `server.cfg`:

```cfg
ensure mr_4inline_3d
ensure mr_4inline
```

## 4. Add the inventory item

Add an item named `4line` (or whatever you set in `Config.ItemName`).

{% tabs %}
{% tab title="ox\_inventory" %}
In `ox_inventory/data/items.lua`:

```lua
['4line'] = {
    label = '4 in Line',
    weight = 500,
    stack = false,
    close = true,
    -- Required for ox: this is how the item triggers placement
    client = { event = 'mr_4inline:PlaceBoard' },
},
```

> ⚠️ Under **ox**, the script does **not** register a usable-item callback — placement is wired through the item's `client.event`. Without the line above, using the item does nothing.
> {% endtab %}

{% tab title="qb-core" %}
In `qb-core/shared/items.lua`:

```lua
['4line'] = {
    name = '4line', label = '4 in Line',
    weight = 500, type = 'item', image = '4line.png',
    unique = false, useable = true, shouldClose = true, description = 'Place a board'
},
```

The script registers the usable item automatically for qb.
{% endtab %}

{% tab title="es\_extended" %}
Register the item in your `items` table / database. The script registers it as usable automatically for esx.
{% endtab %}
{% endtabs %}

## 5. Configure the framework

Open [`config.lua`](broken://pages/33a45b177e41d5eb349f12e0989c8b4126e211f2) and set at minimum:

```lua
Config.Framework = "ox"        -- "ox" | "qb" | "esx"
Config.ItemName  = "4line"
Config.Target    = "ox_target" -- "none" | "ox_target" | "sleepless_interact"
Config.Notify    = "ox_lib"    -- "ESX" | "ox_lib" | "mythic_notify" | "QB-Core"
```

## 6. Set the model names

All model names live in [`config.lua`](broken://pages/33a45b177e41d5eb349f12e0989c8b4126e211f2):

```lua
Config.Base = "mr_4inline_board"

Config.Discs = {
    Black = "mr_4inline_diskb",
    White = "mr_4inline_diskw",
}
```

These **must match** the model names inside `mr_4inline_3d`.

The board model **must contain bones `point1` … `point42`**, numbered row-major from the top-left corner: `point1` is the top-left cell, `point7` the top-right, `point36` the bottom-left, `point42` the bottom-right. The script maps bone numbers straight onto grid cells, so the numbering has to follow that order.

Calibrate disc position with `/4inlinebones` and check bone coordinates with `/4inlinecoords` (both require `Config.Debug = true`) — see [Configuration](broken://pages/f850d5a1680d0412965446a0f6783a7b59631b18#gameplay--placement).

## 7. Add the drop sound

Drop an `.ogg` file at `html/place.ogg` — it's already listed in `fxmanifest.lua`'s `files{}`. Without this file present, dropping a disc won't play any sound (silently — check the client console for a `place.ogg` load error if you're unsure it's missing).

## 8. Restart

```
refresh
ensure mr_4inline_3d
ensure mr_4inline
```

Give a player the item, use it, and place your first board.

## Before going live

* Set `Config.Debug = false`.
* Replace the Discord webhook with your own (never publish the one shipped in the config).
* Remove `CLAUDE.md` and the `.claude/` folder from the resource if present.
* Confirm `html/place.ogg` exists — the resource ships no default sound file.
