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

# Configuration

Every option of Cuxial Chat explained: config, channels and the command palette.

Everything you can adjust lives in three files: `shared/config.lua` for behaviour, `data/channels.lua` for the channels and `data/commands.lua` for the command palette. Restart the resource after any change.

## General

| Option            | Type    | Default | What it does                                                                                                            |
| ----------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
| `debug`           | boolean | `false` | Prints traces to the console. Also enabled by setting the convar `cuxial_chat_debug` to `1`.                            |
| `proximity`       | number  | `12.0`  | Radius in metres of the proximity channels: IC, OOC, ME, DO, dice rolls and images.                                     |
| `persistSettings` | boolean | `true`  | `true` saves each player's settings in the database, tied to the character. `false` keeps them only on the player's PC. |

## Interface · `ui`

| Option        | Type         | Default      | What it does                                                                        |
| ------------- | ------------ | ------------ | ----------------------------------------------------------------------------------- |
| `accent`      | string (hex) | configurable | Accent colour of the interface.                                                     |
| `openKey`     | string       | `'T'`        | Default key that opens the chat. Each player can rebind it in the GTA key settings. |
| `maxMessages` | number       | `400`        | Messages the interface keeps in memory. From 21 to 2000.                            |

## Roleplay actions · `actions`

| Option    | Type   | Default  | What it does                                                                                                                                                                                                            |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `display` | string | `'head'` | Where `/me`, `/do` and dice rolls are shown for players who have not chosen it themselves. `'both'` = chat and above the head, `'head'` = above the head only, `'chat'` = chat only. Any other value works as `'both'`. |

{% hint style="info" %}
This is only the server default. Every player can pick their own value in the chat settings, and their choice wins.
{% endhint %}

## Bubbles · `bubble`

| Option       | Type    | Default | What it does                                                                                |
| ------------ | ------- | ------- | ------------------------------------------------------------------------------------------- |
| `distance`   | number  | `25.0`  | Metres beyond which a bubble is not drawn. Also the range of the "is typing" indicator.     |
| `ms`         | number  | `6000`  | Lifetime of a bubble, in milliseconds.                                                      |
| `tick`       | number  | `50`    | Milliseconds between refreshes while bubbles are visible. Lower is smoother and costs more. |
| `idle`       | number  | `300`   | Milliseconds between checks when there is nothing to draw.                                  |
| `typingMs`   | number  | `8000`  | Milliseconds until the "is typing" indicator expires.                                       |
| `typingSelf` | boolean | `true`  | `true` shows your own typing indicator. `false` shows it only to others.                    |
| `stack`      | number  | `3`     | Maximum bubbles stacked per player.                                                         |

## Anonymous names · `anonymous`

Hides the player's name while they wear a mask.

| Option     | Type      | Default                  | What it does                                                                  |
| ---------- | --------- | ------------------------ | ----------------------------------------------------------------------------- |
| `enabled`  | boolean   | `true`                   | `true` hides the name with a mask on. `false` always shows the name.          |
| `anyMask`  | boolean   | `true`                   | `true` accepts any mask. `false` accepts only the ones listed in `masks`.     |
| `masks`    | number\[] | `{}`                     | Mask numbers (drawable) that hide the name. Only used when `anyMask = false`. |
| `label`    | string    | `'anonymous_label'`      | Name shown instead. A locale key or a literal text.                           |
| `channels` | table     | `me`, `do`, `dice`, `ic` | Channels where the name is hidden: `true` hides it, `false` shows it.         |

Only the proximity channels can hide the name: `ic`, `ooc`, `me`, `do` and `dice`. Private messages and the organization channel always show the real name.

## Organization channel · `gchat`

A channel shared by all organizations. The public variant is also read by the police.

| Option           | Type         | Default                | What it does                                                                                   |
| ---------------- | ------------ | ---------------------- | ---------------------------------------------------------------------------------------------- |
| `enabled`        | boolean      | `true`                 | `false` removes both commands.                                                                 |
| `command`        | string       | `'gchat'`              | Command of the channel between organizations.                                                  |
| `publicCommand`  | string       | `'gchatp'`             | Command of the variant the police can also read.                                               |
| `policeJobs`     | string\[]    | `{ 'leo' }`            | List of police jobs. Add the ones on your server. Each entry matches a job type or a job name. |
| `requireDuty`    | boolean      | `true`                 | `true` = police read and write only while on duty. `false` = always.                           |
| `policeCanWrite` | boolean      | `true`                 | `true` = police can write in the public channel. `false` = read only.                          |
| `fallbackColor`  | string (hex) | `'#8b5cf6'`            | Colour of an organization without its own colour.                                              |
| `policeColor`    | string (hex) | `'#4f8cff'`            | Colour of police messages and of the "Open" tag.                                               |
| `policeLabel`    | string       | `'gchat_police_label'` | Police tag. A locale key or a literal text.                                                    |

{% hint style="info" %}
An organization is the player's gang, as reported by `cuxial_bridge`. Anything the police write is always sent as public.
{% endhint %}

## Images · `images`

| Option       | Type      | Default                                                                        | What it does                                                      |
| ------------ | --------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------- |
| `enabled`    | boolean   | `false`                                                                        | `true` registers the image command.                               |
| `command`    | string    | `'img'`                                                                        | Command used to send an image.                                    |
| `channel`    | string    | `'ooc'`                                                                        | Channel the image is posted in. An `id` from `data/channels.lua`. |
| `hosts`      | string\[] | `i.imgur.com`, `cdn.discordapp.com`, `media.discordapp.net`, `media.tenor.com` | Allowed domains. Any other link is rejected.                      |
| `extensions` | string\[] | `png`, `jpg`, `jpeg`, `gif`, `webp`                                            | Allowed file extensions, in lowercase.                            |
| `perMinute`  | number    | `3`                                                                            | Images per player per minute.                                     |

Only `https` links of up to 400 characters are accepted, and the link must end in the image file. Images always go to nearby players, whatever the channel.

## Logs · `logs`

| Option             | Type    | Default                    | What it does                                                                                             |
| ------------------ | ------- | -------------------------- | -------------------------------------------------------------------------------------------------------- |
| `enabled`          | boolean | `true`                     | `false` stores nothing.                                                                                  |
| `channels`         | table   | `ooc`, `ic`, `pm`, `gchat` | Channels that are logged. An empty table logs every channel.                                             |
| `database`         | boolean | `true`                     | `true` saves to the table `cuxial_chat_logs`. `false` sends to Discord only.                             |
| `keepDays`         | number  | `14`                       | Days the database keeps the logs. `0` keeps them forever. Old rows are removed when the resource starts. |
| `discord.convar`   | string  | `'cuxial_chat_webhook'`    | Name of the `server.cfg` convar that holds the webhook URL. Empty convar = no Discord.                   |
| `discord.batch`    | number  | `15`                       | Queued messages that trigger a webhook request at once.                                                  |
| `discord.flushMs`  | number  | `20000`                    | Milliseconds between writes. Applies to the webhook and to the database.                                 |
| `discord.username` | string  | `'Chat'`                   | Name the webhook posts as.                                                                               |

## Channels · `data/channels.lua`

Each entry is a channel: its tab, its colour and the command it writes with.

| Field     | Type         | What it does                                                                             |
| --------- | ------------ | ---------------------------------------------------------------------------------------- |
| `id`      | string       | Internal identifier. Used by the config and by the exports.                              |
| `label`   | string       | Locale key of the name shown on the tab.                                                 |
| `voice`   | string       | Locale key of the caption shown in the bubble.                                           |
| `color`   | string (hex) | Colour of the channel.                                                                   |
| `tab`     | boolean      | `true` gives the channel its own tab. `false` shows it only in the general view.         |
| `order`   | number       | Position of the tab.                                                                     |
| `icon`    | string       | Bubble icon: `user`, `eye`, `dice`, `lock`, `radio`, `message`, `shield` or `megaphone`. |
| `command` | string       | Command of the channel. Players can write directly in a tab only if its channel has one. |
| `sound`   | boolean      | `true` plays a sound on incoming messages.                                               |
| `bubble`  | boolean      | `true` shows its messages above the author's head.                                       |
| `mutable` | boolean      | `false` stops players from muting the channel in their settings.                         |

Channels included: `ic`, `ooc`, `me`, `do`, `pm`, `dice`, `gchat`, `sancion` and `system`.

{% hint style="warning" %}
Do not remove `ic` or `system`. Plain messages fall back to `ic` and messages from other resources fall back to `system`.
{% endhint %}

## Command palette · `data/commands.lua`

The list the chat suggests when a player types `/`. It only describes the commands; it does not create them.

| Field     | Type   | What it does                                                          |
| --------- | ------ | --------------------------------------------------------------------- |
| `name`    | string | Command without the slash.                                            |
| `help`    | string | Locale key of the description.                                        |
| `channel` | string | Channel the command belongs to. It sets the colour of the suggestion. |
| `params`  | table  | Arguments shown, each with `name` and an optional `optional = true`.  |

Commands announced by other resources are added to this list on their own.

## Texts

All texts are in `locales/en.json` and `locales/es.json`. The language follows the `ox:locale` convar.

## Common changes

### Show actions in the chat as well

{% code title="shared/config.lua" %}

```lua
actions = {
    display = 'both',
},
```

{% endcode %}

### Hide names only behind specific masks

{% code title="shared/config.lua" %}

```lua
anonymous = {
    enabled = true,
    anyMask = false,
    masks = { 51, 52, 111 },
    label = 'anonymous_label',
    channels = {
        me = true,
        ['do'] = true,
        dice = true,
        ic = false,
    },
},
```

{% endcode %}

### Enable images

{% code title="shared/config.lua" %}

```lua
images = {
    enabled = true,
    command = 'img',
    channel = 'ooc',
    hosts = { 'i.imgur.com' },
    extensions = { 'png', 'jpg', 'jpeg', 'gif', 'webp' },
    perMinute = 3,
},
```

{% endcode %}

### Rename the organization commands

{% code title="shared/config.lua" %}

```lua
gchat = {
    command = 'org',
    publicCommand = 'orgp',
    -- keep the rest of the block as it is
},
```

{% endcode %}

{% hint style="info" %}
After renaming, update the `gchat` and `gchatp` entries in `data/commands.lua` so the palette shows the new names.
{% endhint %}

### Log every channel to Discord only

{% code title="shared/config.lua" %}

```lua
logs = {
    enabled = true,
    channels = {},
    database = false,
    keepDays = 14,
    discord = {
        convar = 'cuxial_chat_webhook',
        batch = 15,
        flushMs = 20000,
        username = 'Chat',
    },
},
```

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.cuxial.com/scripts/interface/cuxial-chat/configuration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
