> 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/hanoi-tower/configuration-file.md).

# Configuration File

All options live in `config.lua`. The file is a **shared script** — both the server and the client read it, so keep it listed under `shared_scripts` in `fxmanifest.lua`.

{% hint style="warning" %}
After changing any option, restart the resource (`ensure mr_hanoitower`). Options are read once at startup.
{% endhint %}

## Framework & Item

```lua
Config.Framework = "ox"         -- "ox" | "qb" | "esx"
Config.ItemName  = "hanoitower" -- inventory item name
```

| Option             |        Default | Description                                                                                                                                                                                                                   |
| ------------------ | -------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Config.Framework` |         `"ox"` | Which inventory system handles the board item. `"ox"` = ox\_inventory, `"qb"` = QBCore inventory, `"esx"` = classic ESX inventory. For `qb` and `esx` the script also registers the item as useable automatically.            |
| `Config.ItemName`  | `"hanoitower"` | Name of the inventory item. Must match the item you added during [installation](https://mole-resource.gitbook.io/mole-resource-docs/scripts/hanoi-tower/pages/72ebaccd469ce0b29a37fc86c8d820bc58e1f6e5#4.-add-required-item). |

## Target / Interaction

```lua
Config.Target = "none" -- "none" | "ox_target" | "sleepless_interact"
```

| Value         | Behaviour                                                                                                                                                         |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"none"`      | Built-in proximity prompts — walk up to a board and press the [configured keys](broken://pages/9cc49cd1c8370af2457f3e3aa7f7b4a4fe8c6384#keys) to play or pick up. |
| `"ox_target"` | Boards become [ox\_target](https://github.com/CommunityOx/ox_target) entities with *Play* and *Pick up* options. Built-in prompts are disabled.                   |

{% hint style="info" %}
Option labels come from `Config.Locale` (`help-play`, `help-pickup`), so they translate together with the rest of the script. The options hide automatically while you are playing or placing a board.
{% endhint %}

## Keys

```lua
Config.Controls = {
    Enter  = 38, -- E
    Pickup = 47, -- G
}
```

| Option   |  Default | Description                                          |
| -------- | -------: | ---------------------------------------------------- |
| `Enter`  | `38` (E) | Key that starts the game when standing near a board. |
| `Pickup` | `47` (G) | Key that picks the board up.                         |

{% hint style="info" %}
Values are FiveM control IDs — see the [control list](https://docs.fivem.net/docs/game-references/controls/) for all available keys. These keys are used only when `Config.Target = "none"`.
{% endhint %}

## Synchronization

```lua
Config.SyncDelay = 20000 -- ms
Config.Live      = true
```

| Option             | Default | Description                                                                                                                                                                                                                                                                                                       |
| ------------------ | ------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Config.SyncDelay` | `20000` | Delay (in ms) after a player joins before boards are requested and built. Guarantees the game world is fully streamed first. Lower it on fast servers, raise it if players report missing boards after joining.                                                                                                   |
| `Config.Live`      |  `true` | <p><strong><code>true</code></strong>: spectators see every disk move in real time while someone plays.<br><strong><code>false</code></strong>: spectators see a frozen board; it updates when the player wins, resets, or leaves the game. Use <code>false</code> to reduce network traffic on busy servers.</p> |

## Debug

```lua
Config.Debug = false
```

| Option         | Default | Description                                                                                                                       |
| -------------- | ------: | --------------------------------------------------------------------------------------------------------------------------------- |
| `Config.Debug` | `false` | Enables the `/hanoiitem` command, which gives a free board item with **no permission check**. Keep `false` on production servers. |

## Models

```lua
Config.Base = "mr_hanoi_base"

Config.Disks = {
    [1] = "mr_hanoi_disk1", -- smallest
    [2] = "mr_hanoi_disk2",
    [3] = "mr_hanoi_disk3",
    [4] = "mr_hanoi_disk4",
    [5] = "mr_hanoi_disk5",
    [6] = "mr_hanoi_disk6",
    [7] = "mr_hanoi_disk7", -- largest
}
```

| Option         | Description                                                                                                            |
| -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `Config.Base`  | Prop model of the board. The model must contain bones `point1`, `point2`, `point3` marking the tops of the three pegs. |
| `Config.Disks` | Prop models of the disks, indexed by size (1 = smallest, 7 = largest). Do not change the order.                        |

{% hint style="info" %}
The default props are included in the resource. Only change these if you replace the models with your own.
{% endhint %}

## Gameplay Tuning

```lua
Config.DiskSpacing    = 0.03
Config.Rotation       = vector3(0.0, 0.0, 0.0)
Config.PegClickRadius = 0.10
Config.Distance       = 2.0   
```

| Option                  |   Default | Description                                                                                                                                      |
| ----------------------- | --------: | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Config.DiskSpacing`    |    `0.03` | Vertical distance (in meters) between stacked disks. Adjust only if you use custom disk models with a different height.                          |
| `Config.Rotation`       | `0, 0, 0` | Default rotation of the placement preview before the player rotates it.                                                                          |
| `Config.PegClickRadius` |    `0.10` | Screen-space radius for detecting which peg the cursor points at. Larger = easier to click pegs, but pegs may "overlap" when viewed at an angle. |
| `Config.Distance`       |     `2.0` | Distance to board for interaction                                                                                                                |

## Server-Owned Boards

Permanent public boards defined by the server owner — perfect for a furniture shop, arcade, or plaza. They exist as long as the resource runs, **cannot be picked up**, and reset to a fresh layout on every restart. They are never written to the database.

```lua
Config.Boards = {
    -- { x = -1465.30, y = -546.51, z = 72.65, rotation = 32.0, diskCount = 7 },
}
```

| Field       | Description                                                                                |
| ----------- | ------------------------------------------------------------------------------------------ |
| `x, y, z`   | World position of the board.                                                               |
| `rotation`  | Heading in degrees (0–360).                                                                |
| `diskCount` | Starting number of disks (3–7). Players can still change it in-game before the first move. |

{% hint style="info" %}
Leave the table empty (`Config.Boards = {}`) if you don't need permanent boards.
{% endhint %}

## Notifications

```lua
Config.Notify = "ox_lib" -- "ESX" | "ox_lib" | "mythic_notify" | QB-Core
```

| Value             | Requires                              |
| ----------------- | ------------------------------------- |
| `"ESX"`           | es\_extended (`ESX.ShowNotification`) |
| `"ox_lib"`        | ox\_lib resource                      |
| `"mythic_notify"` | mythic\_notify resource               |
| "`QB-Core`"       | qb-core (`QBCore.Functions.Notify)`   |

## Discord Logs

```lua
Config.Discord = {
    Webhook = "",              -- webhook URL; empty string = logging disabled
    Name    = "mr_hanoitower",
    Logs = {
        place  = true,         -- board placed
        pickup = true,         -- board picked up
        admin  = true,         -- hanoidelete used
    }
}
```

| Option        | Description                                                                                       |
| ------------- | ------------------------------------------------------------------------------------------------- |
| `Webhook`     | Discord webhook URL. Leave empty to disable all logging.                                          |
| `Name`        | Bot username and embed footer text.                                                               |
| `Logs.place`  | Log when a player places a board (player name, server ID, license, board ID, instance, position). |
| `Logs.pickup` | Log when a player picks a board up.                                                               |
| `Logs.admin`  | Log when `hanoidelete` is used from the console.                                                  |

{% hint style="info" %}
Logs are sent only after the database operation succeeds — failed attempts are never logged.
{% endhint %}

## Locale

Every text shown to players — notifications, instructional buttons, help prompts, target labels — lives in `Config.Locale`. Translate the values (right side) to your language; **never change the keys** (left side).

```lua
Config.Locale = {
    ["notify-title"]           = "Tower of Hanoi",
    ["win-message"]            = "You have completed the Tower of Hanoi puzzle! Congratulations!",

    ["no-item"]                = "You don't have a board in your inventory!",
    ["db-error"]               = "Database error!",
    ["board-gone"]             = "This board no longer exists!",
    ["board-static"]           = "This board cannot be picked up!",
    ["board-busy"]             = "Someone is currently playing on this board!",
    ["place-blocked-instance"] = "You can't place a board here (housing system integration required)!",

    ["btn-lock-camera"]        = "Lock camera",
    ["btn-unlock-camera"]      = "Unlock camera",
    ["btn-disks"]              = "Disks",
    ["btn-pick-disk"]          = "Pick up disk",
    ["btn-place-disk"]         = "Place disk",
    ["btn-exit"]               = "Exit",
    ["btn-hold-reset"]         = "Hold to reset",

    ["help-play"]              = "Play",
    ["help-pickup"]            = "Pick up",

    ["pickuplogs"]             = "📦 Picked up board",
    ["adminlogs"]              = "🗑️ Admin removed board",
    ["positionlogs"]           = "📍 Position",
    ["itemlogs"]               = "🎁 Item",
    ["placelogs"]              = "📦 Placed board",
    ['playerlogs']             = "🎮 Player:",
    ['boardlogs']              = "🧩 Board:",
    ['instancelogs']           = "🌐 Instance:",
    ['default-instance']       = "default instance"
}
```
