> 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/es/nucleo/cuxial-multichar/configuration.md).

# Configuración

Todas las opciones de Cuxial Multichar: huecos, Discord, registro, menores, aparición, escena y pantalla de carga.

Todo se ajusta en `shared/config.lua`. Las ubicaciones, el contenido de la pantalla de carga y las nacionalidades están en la carpeta `data`. Reinicia el recurso después de cada cambio.

## General

| Opción      | Tipo     | Por defecto  | Qué hace                                                                                                                                            |
| ----------- | -------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `debug`     | boolean  | `false`      | Muestra mensajes de depuración en la consola                                                                                                        |
| `ui.accent` | string   | configurable | Color de acento de la interfaz y de la pantalla de carga, en hexadecimal                                                                            |
| `hud`       | function | vacía        | Se llama con `false` cuando la selección se abre y con `true` cuando se cierra. Úsala para ocultar y mostrar tu HUD. El minimapa se oculta sin ella |

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

```lua
hud = function(visible)
    exports.mi_hud:setVisible(visible)
end,
```

{% endcode %}

## Personajes

| Opción                   | Tipo    | Por defecto | Qué hace                                                  |
| ------------------------ | ------- | ----------- | --------------------------------------------------------- |
| `characters.slots`       | number  | `3`         | Personajes que puede tener cualquier jugador              |
| `characters.maxSlots`    | number  | `10`        | Tope absoluto. Ningún rol ni ID de usuario lo supera      |
| `characters.allowDelete` | boolean | `true`      | `true` deja a los jugadores borrar sus propios personajes |

## Huecos por Discord

Da más personajes a roles o usuarios concretos de Discord.

| Opción                      | Tipo    | Por defecto | Qué hace                                                                                  |
| --------------------------- | ------- | ----------- | ----------------------------------------------------------------------------------------- |
| `discordSlots.enabled`      | boolean | `false`     | `true` activa los huecos extra por rol y por ID de usuario                                |
| `discordSlots.roles`        | lista   | vacía       | Entradas `{ id = 'ID_DEL_ROL', slots = N }`. Necesita las convars del bot                 |
| `discordSlots.users`        | tabla   | vacía       | Entradas `['ID_DE_USUARIO_DE_DISCORD'] = N`. Funciona sin el bot                          |
| `discordSlots.cacheMinutes` | number  | `10`        | Minutos que se recuerdan los roles de un jugador antes de volver a pedirlos a Discord     |
| `discordSlots.timeoutMs`    | number  | `4000`      | Milisegundos de espera a Discord. Si no contesta, el jugador se queda con los huecos base |

Cómo se calcula el número final:

* `slots` en un rol o en un usuario es el número **total** de personajes, no una suma.
* Si un jugador coincide con varias entradas, gana el número más alto.
* El resultado nunca baja de `characters.slots` ni pasa de `characters.maxSlots`.
* El jugador necesita Discord vinculado a FiveM. Sin él, recibe los huecos base.

{% hint style="info" %}
El token del bot y el ID del servidor son convars, no opciones del config. Mira [Instalación](/scripts/es/nucleo/cuxial-multichar/installation.md).
{% endhint %}

## Registro

| Opción                           | Tipo    | Por defecto    | Qué hace                                                    |
| -------------------------------- | ------- | -------------- | ----------------------------------------------------------- |
| `register.name.min` / `max`      | number  | `2` / `32`     | Longitud permitida del nombre y del apellido                |
| `register.dob.format`            | string  | `"DD-MM-YYYY"` | Formato de fecha: `DD-MM-YYYY`, `YYYY-MM-DD` o `MM-DD-YYYY` |
| `register.dob.minYear`           | number  | `1950`         | Año de nacimiento más antiguo aceptado                      |
| `register.minAge`                | number  | `18`           | Edad mínima de un personaje adulto                          |
| `register.height.enabled`        | boolean | `true`         | Muestra el campo de estatura                                |
| `register.height.min` / `max`    | number  | `150` / `200`  | Rango de estatura en cm                                     |
| `register.backstory.enabled`     | boolean | `true`         | Muestra el campo de historia                                |
| `register.backstory.min` / `max` | number  | `10` / `300`   | Longitud permitida de la historia                           |

La lista de nacionalidades está en `data/nationalities.lua`.

## Personajes menores

Un menor se crea como solicitud. El jugador elige a los progenitores y escribe una motivación, y el staff la aprueba o la rechaza. Hasta que se aprueba, no se puede jugar con el personaje.

| Opción                          | Tipo    | Por defecto                  | Qué hace                                                                                         |
| ------------------------------- | ------- | ---------------------------- | ------------------------------------------------------------------------------------------------ |
| `family.enabled`                | boolean | `true`                       | Activa los personajes menores                                                                    |
| `family.minAge` / `maxAge`      | number  | `6` / `17`                   | Rango de edad de un menor                                                                        |
| `family.motivation.min` / `max` | number  | `30` / `600`                 | Longitud permitida de la motivación                                                              |
| `family.height.min`             | number  | `100`                        | Estatura mínima de un menor en cm                                                                |
| `family.height.max`             | tabla   | `male = 168`, `female = 158` | Estatura máxima según el género                                                                  |
| `family.adultHeight`            | tabla   | `male = 182`, `female = 170` | Estatura adulta de referencia. El personaje se escala como su estatura dividida entre este valor |
| `family.growthCommand`          | string  | `"height"`                   | Comando con el que el menor cambia su estatura. `false` lo quita                                 |
| `family.scaleRadius`            | number  | `60.0`                       | Distancia en metros dentro de la cual se ve a los demás jugadores escalados                      |
| `family.rejectCooldownHours`    | number  | `24`                         | Horas de espera tras un rechazo antes de enviar otra solicitud. `0` lo desactiva                 |
| `family.allowOwnParent`         | boolean | `false`                      | `true` permite elegir como progenitores a personajes de la propia cuenta                         |
| `family.maxPending`             | number  | `1`                          | Solicitudes pendientes permitidas por jugador                                                    |

Las solicitudes se revisan mediante los [exports](/scripts/es/nucleo/cuxial-multichar/developers.md).

## Aparición

| Opción                    | Tipo             | Por defecto | Qué hace                                                                                                                                                                                                                 |
| ------------------------- | ---------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `spawn.newCharacter`      | vec4             | —           | Dónde se coloca un personaje nuevo mientras se abre el creador de apariencia                                                                                                                                             |
| `spawn.birth`             | vec4             | —           | Dónde aparece un personaje nuevo al salir del creador. `false` omite este traslado                                                                                                                                       |
| `spawn.registerPreview`   | vec4             | —           | Dónde se muestra el personaje durante la creación                                                                                                                                                                        |
| `spawn.registerReference` | vec4             | —           | Dónde se coloca la referencia adulta al ajustar la estatura de un menor                                                                                                                                                  |
| `spawn.fallback`          | vec4             | —           | Se usa cuando un personaje no tiene posición guardada o no hay ubicación disponible                                                                                                                                      |
| `spawn.apartments`        | string / boolean | `"auto"`    | `"auto"` usa apartamentos iniciales si `qbx_properties` está en marcha y el framework los tiene activados. `true` / `false` lo fuerza. Con apartamentos se omiten el creador de apariencia y el traslado a `spawn.birth` |

Los personajes que ya existen aparecen siempre en su última posición guardada.

## Escena

| Opción                   | Tipo    | Por defecto                  | Qué hace                                                                                                          |
| ------------------------ | ------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `scene.randomLocation`   | boolean | `true`                       | `true` elige una ubicación al azar cada vez. `false` usa siempre la primera de la lista                           |
| `scene.emotes`           | lista   | `texting`, `idle3`, `smoke2` | Comandos de emote que se reproducen al azar cuando la ubicación no tiene `emote` propio. Necesita `cuxial_emotes` |
| `scene.fallbackScenario` | string  | `"WORLD_HUMAN_STAND_MOBILE"` | Escenario que se usa cuando `cuxial_emotes` no está en marcha                                                     |
| `scene.posture`          | string  | `"side"`                     | `"side"` respeta la orientación de la ubicación. `"front"` gira al personaje hacia la cámara                      |
| `scene.depthOfField`     | boolean | `true`                       | Desenfoque del fondo. El jugador puede quitarlo con el modo FPS                                                   |
| `scene.cameraDistance`   | number  | `2`                          | Distancia de cámara por defecto: `1` cerca, `2` lejos                                                             |

### Ubicaciones

`data/locations.lua` contiene los lugares donde se muestran los personajes.

{% code title="data/locations.lua" %}

```lua
{ label = 'Rockford Hills', coords = vec4(-852.73, -226.99, 61.02, 354.04) },

{
    label = 'Comisaría',
    coords = vec4(444.37, -984.33, 30.69, 71.35),
    groups = { 'police' },
    emote = { scenario = 'WORLD_HUMAN_COP_IDLES' },
},
```

{% endcode %}

| Campo                                        | Qué hace                                                                                                                                             |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label`                                      | Nombre de la ubicación                                                                                                                               |
| `coords`                                     | Posición y orientación del personaje                                                                                                                 |
| `groups`                                     | Nombres de trabajo o banda. La ubicación solo se usa con personajes que pertenezcan a alguno, y esos personajes solo reciben ubicaciones de su grupo |
| `emote`                                      | `{ command = '...' }` para un emote o `{ scenario = '...' }` para un escenario de GTA                                                                |
| `camera`                                     | `front` (por defecto), `back`, `close` o `free`                                                                                                      |
| `cameraCoords`, `fov`, `focusOffset`, `blur` | Posición y óptica de la cámara, solo con `camera = 'free'`. `cameraCoords` es obligatorio en ese modo                                                |
| `scene`                                      | `'bar'` reproduce la animación de apoyarse con los props definidos en `data/scenes.lua`                                                              |

`data/vehicle_locations.lua` contiene los puntos que se usan cuando el personaje posa con un vehículo. `data/scenes.lua` contiene las animaciones de las escenas de barra, pareja, mejor amigo y vehículo.

## Carné, vehículos y pareja

| Opción                     | Tipo             | Por defecto                   | Qué hace                                                                                                    |
| -------------------------- | ---------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `idCard.enabled`           | boolean          | `true`                        | Muestra el carné real mientras se crea el personaje                                                         |
| `idCard.resource`          | string           | `"cuxial_license"`            | Recurso que aporta el carné                                                                                 |
| `idCard.item`              | string           | `"id_card"`                   | Objeto cuyo carné se usa                                                                                    |
| `idCard.cardId`            | string           | `nil`                         | ID de un carné concreto. `nil` lo deduce del objeto                                                         |
| `vehicles.enabled`         | boolean          | `true`                        | Deja al jugador elegir un vehículo propio para la escena                                                    |
| `vehicles.resource`        | string           | `"cuxial_garages"`            | Recurso que tiene que estar en marcha para esta función                                                     |
| `vehicles.spotCommand`     | string / boolean | `false`                       | Nombre de un comando que copia tu `vec4` actual al portapapeles, para rellenar `data/vehicle_locations.lua` |
| `partner.enabled`          | boolean          | `true`                        | Activa las escenas de pareja y de mejor amigo                                                               |
| `partner.maxDistance`      | number           | `10.0`                        | Distancia máxima en metros para invitar a alguien                                                           |
| `partner.inviteSeconds`    | number           | `60`                          | Segundos que dura abierta una invitación                                                                    |
| `partner.invitesPerMinute` | number           | `3`                           | Invitaciones que puede enviar un jugador por minuto                                                         |
| `partner.commands.invite`  | string           | `"partnerinvite"`             | Nombre del comando de invitación                                                                            |
| `partner.commands.force`   | tabla            | `forcepartner`, `group.admin` | `name` y `restricted` (permiso) del comando de staff                                                        |

## Mundo

Clima y hora que se ven en la selección. Cada jugador puede cambiarlos en sus ajustes.

| Opción                  | Tipo    | Por defecto | Qué hace                                         |
| ----------------------- | ------- | ----------- | ------------------------------------------------ |
| `world.enabled`         | boolean | `true`      | `false` no toca el clima ni la hora del servidor |
| `world.weather`         | string  | `"XMAS"`    | Tipo de clima de GTA                             |
| `world.hour` / `minute` | number  | `23` / `30` | Hora del día                                     |

## Pantalla de carga y música

| Opción              | Tipo    | Por defecto | Qué hace                                                                                             |
| ------------------- | ------- | ----------- | ---------------------------------------------------------------------------------------------------- |
| `loading.enabled`   | boolean | `true`      | `false` cierra la pantalla de carga nada más empezar                                                 |
| `loading.autoEnter` | boolean | `false`     | `true` entra a la selección sin el botón de comenzar                                                 |
| `loading.handoffMs` | number  | `2400`      | Duración de la transición hacia la selección, en milisegundos                                        |
| `loading.timeoutMs` | number  | `60000`     | Límite de seguridad en milisegundos. La pantalla de carga se cierra si la transición no llega        |
| `loading.debug`     | boolean | `false`     | Salida de depuración de la pantalla de carga                                                         |
| `music.enabled`     | boolean | `true`      | Música en la pantalla de carga y en la selección                                                     |
| `music.file`        | string  | `""`        | Ruta dentro de `web/build` de la pista que se usa cuando `data/loading.lua` no tiene lista de pistas |
| `music.scale`       | number  | `0.35`      | Multiplicador de volumen sobre el volumen que elige el jugador                                       |
| `music.analyse`     | boolean | `true`      | Hace que la interfaz reaccione al ritmo                                                              |

El contenido se edita en `data/loading.lua`:

| Campo                        | Qué hace                                                                                                     |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `background.video`           | Archivo de vídeo dentro de `web/build`, o una URL. Vacío por defecto: sin vídeo, fondo oscuro con partículas |
| `background.dim`, `blur`     | Oscurecido (de 0 a 1) y desenfoque del vídeo                                                                 |
| `background.loop`, `startAt` | Repetir el vídeo y segundo en el que empieza                                                                 |
| `background.sound`           | `'auto'` detecta si el vídeo tiene sonido. `true` / `false` lo fuerza                                        |
| `background.title`, `artist` | Se muestran en el reproductor cuando el sonido es el del vídeo                                               |
| `tipSeconds`                 | Segundos que cada consejo permanece en pantalla                                                              |
| `tracks`                     | Lista de reproducción: `{ id, url, title, artist }`. Vacía por defecto: sin música                           |
| `tips`                       | Consejos: `{ id, category, title, text }`                                                                    |
| `keys`                       | Guía de teclas: `{ id, keys, label, category, description }`                                                 |

{% hint style="info" %}
El paquete no incluye vídeo ni música. Pon tus archivos en `web/build/video` y `web/build/music`, creando las carpetas si faltan, y añádelos en `data/loading.lua`. Usa vídeo `.webm` y audio `.ogg`.
{% endhint %}

## Objetos iniciales, comandos y registros

| Opción                  | Tipo    | Por defecto                          | Qué hace                                                                                                                                                         |
| ----------------------- | ------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `starterItems`          | lista   | `phone`, `id_card`, `driver_license` | `{ item, amount }`. `identity = true` rellena el objeto con el nombre, la fecha de nacimiento y la nacionalidad del personaje. `metadata` fija metadatos propios |
| `commands.logout`       | tabla   | `logout`, `group.admin`              | `name` y `restricted` (permiso) del comando. `restricted = false` lo abre a todos                                                                                |
| `commands.logoutPlayer` | tabla   | `logoutplayer`, `group.admin`        | `name` y `restricted` (permiso) del comando                                                                                                                      |
| `logs.enabled`          | boolean | `true`                               | Envía registros a Discord cuando la convar del webhook está definida                                                                                             |
| `logs.convar`           | string  | `"cuxial_multichar_webhook"`         | Nombre de la convar que guarda el webhook                                                                                                                        |
| `logs.username`         | string  | `"Multicharacter"`                   | Nombre que muestra el webhook                                                                                                                                    |

## Cambios habituales

{% tabs %}
{% tab title="Más huecos para un rol" %}

```lua
discordSlots = {
    enabled = true,
    roles = {
        { id = '123456789012345678', slots = 5 },
    },
},
```

{% endtab %}

{% tab title="Desactivar los menores" %}

```lua
family = {
    enabled = false,
    -- ...
},
```

{% endtab %}

{% tab title="Abrir /logout a los jugadores" %}

```lua
commands = {
    logout = { name = "logout", restricted = false },
    logoutPlayer = { name = "logoutplayer", restricted = "group.admin" },
},
```

{% endtab %}

{% tab title="Otros objetos iniciales" %}

```lua
starterItems = {
    { item = "phone", amount = 1 },
    { item = "water", amount = 2 },
    { item = "id_card", amount = 1, identity = true },
},
```

{% endtab %}
{% endtabs %}


---

# 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/es/nucleo/cuxial-multichar/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.
