# Configuration

The settings on this page are in `config.lua`. Modify fields in the existing tables and restart the resource to apply changes.

## Initial values and saved settings

The shops and progression rules in the file serve as initial configuration. Once saved through the admin panel, their effective values persist across restarts. Changing them in the file does not automatically replace saved values: use the panel to update shops, rules, and system options that have already been initialized.

The language, providers, bridges, camera, and preview clothing are configured in the file. Sources and tattoos are described in [catalog and packs](https://docs.cxgstudios.com/docs/en/01-cxg-tattoos/04-catalogo.md).

## Global language

```lua
Config.Locale = 'es'
Config.LocaleFallback = 'en'
```

`Locale` sets the interface and message language for all players. Restart the resource after changing it; players cannot change it from the NUI. `LocaleFallback` is the fallback language.

Included languages: `en`, `es`, `pt-BR`, `fr`, `de`, `it`, `pl`, `ru`, `tr`, `th`, and `ar`. The Arabic interface uses right-to-left reading direction.

## Identity system

`Config.Identity` configures integration with the server's identity system. It defines how to obtain the character or account identifier that the resource uses to save and retrieve tattoos, XP, and blueprints.

```lua
Config.Identity.mode = 'auto'
Config.Identity.qbxResource = 'qbx_core'
```

| Mode | Purpose |
| --- | --- |
| `auto` | On Qbox, uses the active character identifier (`citizenid`). On other servers, uses the stable FiveM identifier. |
| `qbx_character` | Explicitly uses the Qbox character identifier (`citizenid`). |
| `license` | Uses the FiveM license as the account identifier. Characters on that account share tattoos, XP, and blueprints. |

Choose the mode before opening the resource to players. Changing it later changes the identity used to look up data; data is not automatically moved between modes. Do not select `license` if you want tattoos to be separate between characters on an account.

## Interaction prompt

```lua
Config.HelpText.enabled = true
Config.HelpText.provider = 'auto'
Config.HelpText.position = 'left-center'
```

| Field | Values or effect |
| --- | --- |
| `enabled` | Shows or hides the interaction prompt for shops that use a marker. |
| `provider` | `auto`, `ox_lib`, or `native`. `auto` uses TextUI if available and the native prompt otherwise. |
| `position` | `left-center`, `right-center`, `top-center`, or `bottom-center`, for TextUI. |
| `style` | TextUI colors, border, shadow, typography, and padding. |

Style example:

```lua
Config.HelpText.style.backgroundColor = '#172328'
Config.HelpText.style.color = '#eef3f3'
Config.HelpText.style.fontSize = '15px'
```

## Initial shops

`Config.Shops` includes six locations. To change an initial entry, preserve its structure:

```lua
{
    label = 'Tattoo Studio',
    coords = vector3(322.62, 180.34, 103.59),
    heading = 156.2,
    drawDistance = 10.0,
    interactDistance = 1.5,
    shopRadius = 4.0,
    marker = {
        type = 1,
        scale = vector3(1.0, 1.0, 1.0),
        color = { r = 255, g = 100, b = 0, a = 100 },
    },
},
```

| Field | Purpose |
| --- | --- |
| `label` | Shop name. |
| `coords`, `heading` | Position and orientation. |
| `drawDistance` | Marker visibility distance. |
| `interactDistance` | Interaction distance. |
| `shopRadius` | Radius within which the shop operation is authorized. |
| `marker.type`, `scale`, `color` | Marker appearance. |

Keep `interactDistance` within `shopRadius`. For shops that have already been created, use the shop section of the admin panel; do not expect a file edit to recreate or replace those shops.

## Levels and XP

| `Config.Levels` setting | Initial value | Purpose |
| --- | --- | --- |
| `enabled` | `true` | Enables progression, requirements, and discounts. |
| `maxLevel` | `10` | Level cap. |
| `defaultXpPerTattoo` | `10` | XP for a tattoo that does not specify `Xp`. |
| `thresholds` | Levels 1 to 10 | Cumulative XP required for each level. |
| `formula.base`, `formula.exponent` | `100`, `1.5` | Parameters for the alternative threshold formula. |
| `zoneRequirements` | `1` for each zone | Per-zone requirement when there is no individual requirement. |
| `discounts` | Enabled, `3` per level, maximum `25` | Percentage discount. |
| `blueprintSlots` | Base `5`, increment `3` | Blueprint slots based on level. |

Thresholds must start at level 1 with 0 XP, continue without gaps, and increase the required XP:

```lua
Config.Levels.thresholds = {
    { level = 1, xpRequired = 0 },
    { level = 2, xpRequired = 100 },
    { level = 3, xpRequired = 250 },
}
Config.Levels.maxLevel = 3
```

The discount is calculated as `level × perLevel`, capped at `maxDiscount`. With the initial values, level 5 gets a 15% discount and the maximum discount is 25%.

Slots are calculated as `base + (level - 1) × perLevel`. With the initial configuration, level 1 has 5 slots and level 5 has 17.

An individual `RequiredLevel` in the catalog takes priority over the zone requirement. See [catalog fields](https://docs.cxgstudios.com/docs/en/01-cxg-tattoos/04-catalogo.md).

When levels are disabled, level restrictions, XP, and discounts do not apply; the blueprint limit uses `Config.Blueprints.maxPerPlayer`. Disabling the system preserves saved XP. On installations that have already been initialized, also update the effective state through the panel.

## Blueprints

Blueprints save groups of tattoos and let players share them using codes. Their initial limits are in `Config.Blueprints`:

| Field | Initial value | Purpose |
| --- | --- | --- |
| `enabled` | `true` | Enables the system. |
| `codePrefix` | `INK` | Code prefix, for example `INK-A3X9`. |
| `codeLength` | `4` | Number of characters after the prefix. |
| `maxPerPlayer` | `20` | Slots used when progression is inactive. |
| `maxTattoosPerBlueprint` | `50` | Maximum tattoos per group. |
| `nameMaxLength` | `60` | Maximum name length. |

Redeeming a code prepares the tattoos in the purchase flow; it does not grant a free purchase. The economy is configured in [integrations](https://docs.cxgstudios.com/docs/en/01-cxg-tattoos/05-integraciones.md).

## Camera

| Table | What it controls |
| --- | --- |
| `CameraOffsets` | Target bone, distance, offsets, and field of view by zone. |
| `CameraFraming` | Overall composition and focus-point offset. |
| `CameraFramingBySide` | Additional settings for front and back views. |
| `CameraManualControls` | Manual controls, movement increments, rotation, zoom, and limits. |

Configured zones are `ZONE_HEAD`, `ZONE_TORSO`, `ZONE_LEFT_ARM`, `ZONE_RIGHT_ARM`, `ZONE_LEFT_LEG`, and `ZONE_RIGHT_LEG`.

Examples of specific changes:

```lua
Config.CameraOffsets['ZONE_TORSO'].fov = 50.0
Config.CameraFraming.screenOffset = 0.35
Config.CameraManualControls.enabled = true
Config.CameraManualControls.step = 0.035
Config.CameraManualControls.zoomStep = 0.08
```

A positive `screenOffset` places the character toward the left to make room for the menu on the right. `lookAtOffsetX/Y/Z` changes the focus point; `camOffsetX/Y/Z` in the per-side settings changes the camera position.

For manual controls, `horizontalDegrees` and `rotationStepDegrees` adjust rotation. `ranges.y/z`, `radialClamp`, and `maxDistance` limit movement. `zoomCompositionMinBias` adjusts centering while zooming in. Change one value at a time and test all six zones with male and female characters.

## Preview clothing

`Config.PreviewOutfit` can clear tattooed areas while the interface is open:

```lua
Config.PreviewOutfit.enabled = true
Config.PreviewOutfit.useDefaultVariation = false
Config.PreviewOutfit.presets['mp_m_freemode_01'].components[11] = {
    drawable = 15,
    texture = 0,
}
```

The included presets distinguish `mp_m_freemode_01` and `mp_f_freemode_01`. Each component specifies `drawable` and `texture`; `clearProps` removes accessories during preview. Adjust the indices to the clothing installed on your server. Keep `useDefaultVariation = false` if you only want to apply the preset components without globally resetting the appearance.

## Permissions, economy, and Qbox

`Config.Permissions`, `Config.AdminCommand`, `Config.Purchases`, and `Config.QbxMulticharacterPreview` are explained in [integrations](https://docs.cxgstudios.com/docs/en/01-cxg-tattoos/05-integraciones.md). Set the actual names of your resources when they differ from the defaults.

## Diagnostics

`Config.Debug` enables general diagnostics. `Config.Permissions.debug` lets you inspect access decisions. Keep both disabled when finished.

`Config.DebugCommands.clientTattooCommand` is disabled initially. Enable that visual command only for testing: it does not save tattoos or replace a purchase.

[Continue to the catalog](https://docs.cxgstudios.com/docs/en/01-cxg-tattoos/04-catalogo.md).
