# Manual completo de mods de Eclipse Imperia

Versión del formato: 1.x.  
Aplicación de referencia: Eclipse Imperia 2.0.0.

## 1. Qué es un mod en Eclipse Imperia

Un mod es una carpeta declarativa que añade contenido mediante JSON. No contiene ni ejecuta Python, JavaScript, DLL, macros o comandos. El motor lee, valida y copia únicamente datos de tres familias:

1. **orígenes**, elegibles al crear un universo;
2. **situaciones**, campañas narrativas de 2 a 8 etapas;
3. **escenarios**, conjuntos de reglas que pueden aplicarse sin borrar progreso.

Cada mod se puede activar o desactivar por universo. Si una partida utiliza un origen o una situación cuyo mod deja de estar activo, la historia se pausa sin borrar su estado. El modo seguro desactiva los mods del universo para poder abrirlo y reparar la instalación.

## 2. Editor accesible recomendado

La forma más segura de crear contenido es el editor de wxPython:

1. abre `EclipseImperia.exe` o `jugar.bat`;
2. asegúrate de que el servidor está detenido;
3. pulsa **Editor de mods**, situado encima de **Importar o exportar partidas**;
4. crea un mod o elige uno instalado;
5. recorre las páginas Manifiesto, Orígenes, Situaciones, Escenarios y Validación;
6. pulsa `Control+H` sobre cualquier campo, lista, selector o botón para conocer su finalidad, valores permitidos y un ejemplo;
7. pulsa **Guardar y validar**;
8. cierra el editor e inicia el servidor para recargar el catálogo.

Cada campo de texto, selector y lista tiene una etiqueta `StaticText` visible colocada inmediatamente encima. Además recibe un nombre accesible explícito para que NVDA, JAWS y Narrador anuncien dónde ha caído el foco al recorrer la ventana con `Tab`, incluso si wxWidgets no relaciona automáticamente la etiqueta visual.

La lista de dependencias expone cada elemento como una casilla de verificación y comunica si está marcado o no marcado. Los diálogos de entrada también colocan la etiqueta encima del campo, seleccionan el valor inicial para poder sustituirlo y usan los botones **Aceptar** y **Cancelar**. Los mensajes informativos comienzan con el cursor al principio y se cierran con **Aceptar**, no con un botón denominado «OK».

El editor permite:

- crear, cargar, editar, duplicar y borrar mods;
- cambiar el identificador, reescribir el espacio de nombres y actualizar las dependencias instaladas que lo referencian;
- elegir dependencias instaladas;
- añadir, duplicar y borrar orígenes;
- elegir cualquiera de las siete bonificaciones implementadas;
- añadir y ordenar etapas;
- añadir hasta seis decisiones por etapa;
- crear escenarios con cualquier regla registrada por el motor;
- heredar automáticamente las reglas actuales y futuras, conservando excepciones propias;
- seleccionar únicamente valores aceptados por el motor;
- revisar los cuatro JSON antes de guardar;
- validar con el mismo código que usa el juego;
- evitar iniciar el servidor mientras los archivos están siendo editados.

El borrado requiere confirmación. Si una partida dependía del mod eliminado, no pierde su progreso, pero ese contenido queda pausado hasta reinstalarlo.

## 3. Estructura de carpetas

Cada mod ocupa una subcarpeta directa de `mods`:

```text
mods/
  autor.mi_mod/
    manifest.json
    origins.json
    situations.json
    scenarios.json
```

Los nombres de los catálogos pueden cambiar en el manifiesto, pero deben ser archivos `.json` situados directamente dentro de la carpeta del mod. No se admiten rutas absolutas, `..`, subcarpetas ni enlaces a archivos exteriores.

Cada JSON tiene un límite de 1 MB. Usa UTF-8. Se recomienda terminar el archivo con un salto de línea.

## 4. `manifest.json`

Ejemplo completo:

```json
{
  "id": "ana.cronicas_estelares",
  "name": "Crónicas estelares",
  "version": "2.1.0",
  "compatible": "1.0",
  "description": "Añade dos orígenes, dos campañas y dos escenarios.",
  "dependencies": [
    "ana.biblioteca_comun"
  ],
  "catalogs": {
    "situations": "situations.json",
    "origins": "origins.json",
    "scenarios": "scenarios.json"
  }
}
```

### Campos

| Campo | Obligatorio | Regla |
|---|---:|---|
| `id` | sí | formato `autor.mod`, en minúsculas; admite números, `_` y `-` |
| `name` | sí | nombre visible; el juego conserva como máximo 80 caracteres |
| `version` | sí | versión propia; se recomienda `mayor.menor.parche` |
| `compatible` | sí | debe compartir la versión mayor de Eclipse Imperia |
| `description` | no | resumen visible; máximo efectivo de 500 caracteres |
| `dependencies` | no | lista de identificadores de otros mods |
| `catalogs` | no | relación entre familia y archivo JSON |

No se permiten dependencias duplicadas, hacia el propio mod, ausentes, inválidas o circulares. Al activar un contenido durante la creación de un universo, sus dependencias se activan en orden transitivo.

## 5. Espacios de nombres

Toda entrada de catálogo usa:

```text
autor.mod:contenido
```

Ejemplos válidos:

```text
ana.cronicas_estelares:colonia_perdida
ana.cronicas_estelares:reloj_imposible
ana.cronicas_estelares:universo_hostil
```

La parte posterior a `:` debe comenzar por letra minúscula y solo puede contener letras minúsculas, números, guion y guion bajo.

No copies el identificador de otro mod. Dos carpetas con el mismo `id` son rechazadas.

## 6. Orígenes

`origins.json` es un objeto cuyas claves son identificadores completos:

```json
{
  "ana.cronicas_estelares:viajeros_del_retorno": {
    "name": "Viajeros del retorno",
    "summary": "Una expedición regresó antes de haber partido.",
    "bonus": "science"
  }
}
```

### Campos

- `name`: nombre elegido en Nueva partida;
- `summary`: presentación narrativa;
- `bonus`: efecto inicial real aplicado por el motor.

### Bonificaciones permitidas

| Valor | Efecto inicial |
|---|---|
| `exploration` | añade un Explorador y garantiza Astrofísica 1 |
| `military` | añade soldados, blindados y moral |
| `industry` | añade metal, cristal, deuterio y Robótica 1 |
| `ecology` | añade alimento, habitabilidad y moral |
| `science` | añade cristal, deuterio y Computación 1 |
| `politics` | añade influencia y apoyo a las facciones |
| `diplomacy` | añade influencia y confianza diplomática |

El origen conserva tres capítulos de legado. El jugador responde mediante tradición, reforma o síntesis. Esos capítulos y sus recompensas generales pertenecen al motor; el mod define identidad, resumen y bonificación inicial.

## 7. Situaciones narrativas

`situations.json` contiene campañas de 2 a 8 etapas:

```json
{
  "ana.cronicas_estelares:reloj_imposible": {
    "name": "El reloj imposible",
    "stages": [
      [
        "Segundo perdido",
        "Todos los cronómetros omiten el mismo segundo.",
        [
          ["study", "Estudias la discontinuidad antes de actuar"],
          ["protect", "Proteges las colonias expuestas"],
          ["exploit", "Intentas obtener una ventaja inmediata"]
        ]
      ],
      [
        "Resolución",
        "La línea temporal exige una decisión final.",
        [
          ["resolve", "Estabilizas una única versión de la historia"]
        ]
      ]
    ]
  }
}
```

Cada etapa es una lista de tres elementos:

1. título;
2. descripción previa a la decisión;
3. lista de 1 a 6 opciones.

Cada opción contiene:

1. clave interna;
2. texto de resultado.

Las claves deben usar el mismo patrón minúsculo que los sufijos. No se pueden repetir dentro de la misma etapa.

El motor registra cada decisión, otorga de 2 a 6 puntos de influencia de manera reproducible y guarda el historial. Las claves `share`, `welcome`, `publish`, `protect`, `integrate`, `ally` y `listen` se interpretan como decisiones cooperativas y mejoran la moral; las demás producen el ajuste neutral o exigente previsto por el motor.

No escribas HTML en los textos. El contenido se presenta como texto y el motor se encarga del marcado accesible.

## 8. Escenarios

`scenarios.json` define conjuntos de reglas:

```json
{
  "ana.cronicas_estelares:frontera_hostil": {
    "name": "Frontera hostil",
    "description": "Pocos minerales, rivales agresivos y muchas anomalías.",
    "include_all_rules": true,
    "rules": {
      "resource_richness": "scarce",
      "ai_aggression": "high",
      "anomaly_density": "dense",
      "victory_mode": "score",
      "victory_score": 90000
    }
  }
}
```

`name` y `rules` son obligatorios. `description` es recomendable. Debe existir al menos una regla, salvo cuando `include_all_rules` sea `true`.

`include_all_rules: true` hace que el escenario reciba el valor inicial de todas las reglas registradas en el motor. Las entradas de `rules` se aplican después y funcionan como excepciones. Esta es la opción recomendada para un escenario demostrativo o pensado para seguir creciendo: si una versión futura incorpora otra regla al catálogo único, el editor wxPython la mostrará y el escenario la heredará sin modificar sus JSON.

Si se quita una excepción desde el editor, la regla no desaparece cuando la cobertura automática está activa: vuelve al valor inicial del catálogo. Si se desactiva la cobertura, `rules` debe conservar al menos una entrada.

### Reglas registradas en esta versión

| Clave | Valores |
|---|---|
| `resource_richness` | `scarce`, `standard`, `abundant`, `lavish` |
| `agricultural_richness` | `scarce`, `standard`, `abundant`, `lavish` |
| `ai_aggression` | `peaceful`, `low`, `normal`, `high`, `relentless` |
| `event_frequency` | `off`, `low`, `normal`, `high`, `chaotic` |
| `economy_multiplier` | `0.5`, `1`, `2`, `4` |
| `fleet_speed_multiplier` | `0.5`, `1`, `2`, `4` |
| `research_speed_multiplier` | `0.5`, `1`, `2`, `4` |
| `system_topology` | `linear`, `circular` |
| `galaxy_topology` | `linear`, `circular` |
| `fleet_debris_percent` | número entre 0 y 100 |
| `defense_debris_percent` | número entre 0 y 100 |
| `deuterium_debris_percent` | número entre 0 y 100 |
| `rare_resource_richness` | `scarce`, `standard`, `abundant`, `wild` |
| `expedition_volatility` | `safe`, `normal`, `dangerous`, `anomalous` |
| `ai_adaptability` | `predictable`, `adaptive`, `chaotic` |
| `ecology_pressure` | `relaxed`, `standard`, `harsh`, `catastrophic` |
| `anomaly_density` | `sparse`, `standard`, `dense`, `surreal` |
| `victory_mode` | `sandbox`, `score`, `domination` |
| `victory_score` | número entre 5.000 y 1.000.000 |

Un escenario activo se aplica desde **Escenarios y mods**. Modifica la configuración correspondiente sin borrar planetas, recursos, tecnologías ni progreso. Algunas reglas influyen principalmente en sucesos o producción futuros.

Una clave desconocida o un valor fuera de la lista provoca el rechazo completo del mod. No se ignora silenciosamente.

## 9. Dependencias y campañas conectadas

Las dependencias sirven para construir campañas por capas:

```text
eclipse.frontera_viva
└── eclipse.archivos_ancestrales
    └── eclipse.cronicas_temporales

eclipse.jardines_estelares
┐
├── eclipse.confederacion_alba
eclipse.mercaderes_vacio
┘

eclipse.cronicas_temporales
eclipse.confederacion_alba
eclipse.legiones_umbral
└── eclipse.odisea_total
```

Un mod dependiente solo aporta contenido cuando todas sus dependencias están activas. Antes de desactivar una base debes desactivar los dependientes.

Las dependencias no mezclan automáticamente textos o entradas. Cada mod conserva su propio espacio de nombres.

## 10. Colección incluida

La distribución incorpora ocho mods completos:

| Mod | Tema | Dependencias |
|---|---|---|
| `eclipse.frontera_viva` | exploración y colonias pioneras | ninguna |
| `eclipse.jardines_estelares` | ecología y xenobiología | ninguna |
| `eclipse.mercaderes_vacio` | comercio, influencia y diplomacia | ninguna |
| `eclipse.legiones_umbral` | guerra y fortalezas lunares | ninguna |
| `eclipse.archivos_ancestrales` | arqueología y reliquias | Frontera viva |
| `eclipse.cronicas_temporales` | causalidad y paradojas | Archivos ancestrales |
| `eclipse.confederacion_alba` | federación política y ecológica | Jardines y Mercaderes |
| `eclipse.odisea_total` | campaña que conecta todas las ramas | Crónicas, Confederación y Legiones |

Cada uno contiene dos orígenes, dos situaciones de cuatro etapas y dos escenarios. `eclipse.odisea_total:demostracion_completa` personaliza todas las reglas admitidas en esta versión y tiene `include_all_rules` activo para heredar las futuras.

## 11. Validación y errores frecuentes

### «El identificador debe usar el formato autor.mod»

Usa minúsculas y un punto que separe autor y nombre. Ejemplo: `maria.rutas_antiguas`.

### «No usa un identificador válido autor.mod:nombre»

La clave del catálogo debe comenzar exactamente por el `id` del manifiesto seguido de `:`.

### «Faltan dependencias instaladas y válidas»

Instala primero las carpetas indicadas o retíralas de `dependencies`.

### «Dependencia circular»

Si A depende de B, B no puede depender directa ni indirectamente de A.

### «Contiene una etapa no válida»

Cada etapa necesita título, descripción y lista de opciones. No uses objetos en lugar de la lista de tres posiciones.

### «Usa una bonificación desconocida»

Elige uno de los siete valores de la tabla de orígenes.

### «La regla no está permitida»

Los escenarios solo pueden modificar claves del catálogo único del motor. Abre el editor para consultar siempre la lista actual: se genera directamente desde ese catálogo.

### «Supera el límite seguro de 1 MB»

Divide la campaña en varios mods o simplifica textos. No cambies el límite local si piensas compartir el contenido.

## 12. Proceso manual sin editor

1. copia una carpeta de la colección;
2. cambia el nombre de la carpeta;
3. modifica `id`, `name`, `version` y `description`;
4. cambia el prefijo de todas las claves de los tres catálogos;
5. revisa dependencias;
6. valida desde el editor o inicia el juego y abre **Escenarios y mods**;
7. corrige cualquier rechazo antes de compartir.

Nunca edites el mod mientras el servidor está procesando una acción. El editor wxPython exige detenerlo precisamente para evitar lecturas parciales.

## 13. Pruebas recomendadas antes de publicar

- el editor informa «Mod válido»;
- el mod aparece sin rechazo en **Escenarios y mods**;
- cada origen se puede elegir al crear una partida;
- la bonificación inicial coincide con la documentación;
- cada situación muestra todas sus etapas y decisiones;
- cada escenario cambia solo las reglas declaradas;
- el modo seguro abre el universo;
- desactivar y volver a activar el mod conserva el progreso narrativo;
- las dependencias se activan en orden;
- todos los textos tienen sentido sin color, imagen o sonido;
- los nombres son distintos y comprensibles con lector de pantalla;
- el ZIP compartido no contiene partidas `.dat`, `.sqlite3` o `.eitransfer`.

## 14. Versionado y compatibilidad

Incrementa:

- parche para correcciones de texto sin cambiar identificadores;
- versión menor al añadir contenido compatible;
- versión mayor al retirar o renombrar identificadores existentes.

Cambiar una clave de origen o situación puede dejar una partida sin su definición. Conserva las claves antiguas siempre que sea posible.

`compatible` comprueba la versión mayor de Eclipse Imperia. Un mod `compatible: "1.0"` funciona con las versiones 1.x. Si una futura versión 2 cambia el formato, deberá declarar compatibilidad 2.x.

## 15. Seguridad y distribución

- comparte únicamente la carpeta del mod o un ZIP que la contenga;
- no añadas ejecutables ni scripts;
- no incluyas datos personales;
- no prometas efectos que el motor no implementa;
- conserva la autoría y licencia que hayas elegido;
- prueba una copia limpia antes de publicarla;
- recomienda hacer copia de la partida antes de cambiar una campaña extensa.

El validador reduce riesgos de ruta, tamaño, tipo y contenido, pero no juzga calidad literaria, equilibrio ni posibles derechos de terceros. La persona autora sigue siendo responsable de lo que distribuye.
