Todas las páginas de formatos ↓
Tutoriales y referencia

Escollos habituales al hacer mods y analizar formatos

Fuente: coreprime/kbot @ 0ab97bf · Editar en GitHub

Una chuleta de una sola página con los escollos con los que más gente tropieza de todos los que aparecen repartidos por los documentos de formatos de kbot. Si te topas con un fallo que no tiene ningún sentido, empieza por aquí. Cada punto enlaza con la explicación detallada en la página del formato correspondiente.

Tip

¿Buscas por qué «mi mod no carga»? La regla del punto y coma de TDF (#tdf--fbi--ota, primer punto) explica más casos de «fallo silencioso» que todos los demás escollos juntos.


HPI / UFO / CCX / GP3

  • Los archivos sueltos de la raíz de la instalación tienen prioridad sobre todos los archivos comprimidos. Deja units/MYUNIT.fbi en el disco y el motor lo preferirá a cualquier cosa de totala1.hpi. El diagrama de capas de hpi.md muestra la pila de prioridades completa.
  • Entre los archivos comprimidos gana el primero que se monta, y solo se montan diez *.hpi. TA 3.1c monta rev31.gp3, después *.ccx, *.ufo y los diez primeros *.hpi que se abran, cada grupo ordenado por nombre en mayúsculas según el orden ASCII. Un mod distribuido como zz_mod.hpi queda por debajo de todos los archivos comprimidos de la versión comercial y, en una instalación que ya tenga diez *.hpi que se ordenen antes que él, solo se monta mediante la exploración del disco, por debajo de todo lo demás. Distribuye los mods como .ufo.
  • Los punteros de HPI v1 son absolutos respecto al inicio del archivo, no al del directorio. No restes nada. El truco del analizador de referencia es reservar un búfer de DirectorySize bytes y descifrar el directorio en él a partir del desplazamiento Start, para que los punteros indexen el búfer directamente. Consulta Árbol de directorios.
  • La semilla del cifrado de HPI v1 avanza con la posición en el archivo. No puedes descifrar un búfer de forma aislada: tienes que saber de qué desplazamiento absoluto del archivo procede. Consulta Cómo derivar la clave de cifrado.
  • Si DecryptKey == 0, no apliques el cifrado XOR. Algunos archivos comprimidos personalizados se distribuyen en claro; si aplicas el cifrado igualmente, desordenas lo que ya se podía leer.
  • La suma de comprobación de los chunks SQSH se calcula sobre los bytes cifrados. Compruébala antes de descifrar. Consulta Chunks comprimidos (SQSH).
  • TA: Kingdoms usa HPI v2 (Version == 0x00020000) con otra disposición: sin XOR y con un solo chunk SQSH por archivo. Lee la sección HPI v2 de TA: Kingdoms antes de probar el analizador de v1 con un archivo comprimido de TAK.
  • Las partidas guardadas con la marca BANK son otra cosa: reutilizan el envoltorio HPI, pero el contenido es el estado de la partida serializado, no un sistema de archivos. kbot no las decodifica.
  • .gp3 necesita el parche rev3.1. Por dentro sigue siendo HPI, pero TA sin parchear se niega a montarlo.

TDF / FBI / OTA

  • Todo valor debe terminar en ;. Si falta un punto y coma, los valores de varias líneas se unen sin avisar y salen estadísticas disparatadas. Es la causa número 1 de «mi unidad tiene unos puntos de vida raros / no tiene descripción / cuesta lo que no debe».
  • Las claves no distinguen mayúsculas de minúsculas; los valores sí. Side=arm funciona en la mayoría de las búsquedas, pero rompe cualquier código de mod que compare Side por igualdad de cadenas.
  • Los valores de lista van separados por espacios (Category=COMMANDER MOBILE WEAPON), no por comas. La excepción es el numplayers=2,4,6,8,10 de OTA, que usa comas.
  • Los booleanos son los enteros 1/0, no true/false. El motor solo acepta la forma entera.
  • En los mods, nunca edites sidedata.tdf para añadir unidades. Usa en su lugar un registro [MENUENTRY] en download/<UNITNAME>.tdf, el mismo mecanismo que usa Core Contingency. Consulta TDF: [MENUENTRY] y el tutorial de modding.
  • Bmcode=0 oculta una unidad del menú de construcción aunque todo lo demás sea válido. Casi siempre quieres Bmcode=1.
  • Una unidad que no figura en ningún constructor no se puede construir, aunque su FBI sea válido en todo lo demás. Es el fallo más habitual de «mi unidad nueva existe pero no se puede construir». Consulta el paso 5 del tutorial de modding.
  • La profundidad de las secciones anidadas es una convención, no una especificación. Algunas herramientas suponen 2 niveles; los TDF de armas llegan a 3 ([WEAPON][DAMAGE][category]).

TNT / SCT: terreno del mapa

  • Width y Height de un TNT se miden en celdas de atributos de 16 px, no en casillas ni en píxeles. Divide por 2 para obtener el número de casillas; multiplica por 16 para obtener las dimensiones en píxeles. Consulta la cabecera de TNT.
  • SeaLevel == 0 NO significa «sin agua»: significa que el menor valor posible está en el umbral, así que nada queda bajo el agua. Usa SeaLevel = 1 para los mapas realmente secos.
  • Las palabras de elemento de un TNT solo colocan un elemento por debajo del número de entradas de la tabla de elementos. 0xFFFC es una celda vacía; 0xFFFE (Lava Run, AC02), 0xFFFD y cualquier otra palabra igual o superior al tamaño de la tabla no colocan nada, y en la celda se puede seguir construyendo.
  • El relleno del minimapa de un TNT usa el índice de la paleta 0x64, y el tamaño de la región del mapa se calcula a partir del mapa (lado más largo de 252, con la proporción del mapa visible), no buscando dónde está el relleno. El juego solo lee el minimapa guardado cuando está activado el bit 0 de la palabra de cabecera en 0x2c. Consulta TNT.
  • Los .tnt de TA: Kingdoms usan IDVersion == 0x4000 en lugar del 0x2000 de TA (TA también lee una disposición más antigua, 0x1020). kbot tnt image produce basura con los TNT de TAK; el decodificador de casillas es específico de TA. Consulta Mapas de TA:K.
  • Las secciones SCT tienen que medir un múltiplo de 4 en las dos dimensiones para cargarse en TAE. El formato en disco admite otros tamaños, pero el editor los rechaza con «section misaligned».
  • SCT V2 tiene celdas de altura de 8 bytes, y V3 de 4 bytes. kbot acepta las dos; los mods creados con el editor solo ven V3.

3DO: modelos

  • El eje vertical es Y, no Z. Si importas un 3DO en un motor con Z hacia arriba (Blender, Unreal moderno) sin intercambiar los ejes, todas las unidades quedan tumbadas de lado.
  • Las primitivas sin textura son invisibles salvo que IsColored != 0: el pseudocódigo visible = (texture != "") || (IsColored != 0) cubre los dos casos. Es el fallo más habitual al renderizar 3DO.
  • OffsetToSelectionPrim solo tiene sentido en el objeto raíz; los objetos hijos deben ponerlo a -1 (0xFFFFFFFF).
  • La escala de coma fija es 1 / 65536. Un vértice escrito como 0x00010000 vale 1,0 unidades del mundo; los 16 bits bajos son la parte fraccionaria.
  • Los vértices son locales al objeto, no globales. Dos objetos pueden tener arrays de vértices idénticos: eso es geometría reflejada, no datos compartidos.

COB / BOS: scripts

  • El opcode de call-script es 0x10062000, NO 0x10063000 como afirman algunos documentos anteriores a la 3.1. Los descompiladores antiguos que usan 0x10063000 producen disparates: consulta la referencia de opcodes.
  • Los números de pieza de los opcodes son índices en la tabla de nombres de piezas, no cadenas. El COB lleva los nombres en un pool de cadenas; en tiempo de ejecución se usan índices por velocidad.
  • SET_SIGNAL_MASK solo registra interés: no mata nada. Lo que detiene los scripts cuya máscara tiene X activada es enviar signal X. La regla de lint signal-never-signalled detecta los scripts que fijan una máscara a la que nadie envía nunca una señal.
  • El Scriptor de Cavedog sustituye CURRENT_SPEED por el literal 29, lo que rompe los scripts al estilo de MoveWatcher tras un viaje de ida y vuelta. El descompilador de kbot restaura el nombre simbólico; si tienes que hacer el viaje de ida y vuelta con Scriptor, pon paréntesis: (get CURRENT_SPEED) > 5.
  • Los desplazamientos de salto son desplazamientos en bytes relativos a OffsetToScriptCode, no a la instrucción actual. JUMP 0x4C significa «saltar a OffsetToScriptCode + 0x4C».
  • Los números de puerto de GET_UNIT_VALUE varían entre TA y TA:K. El catálogo de TA (el descompilador de kbot etiqueta los puertos 1–20) está documentado en el apéndice B.

GAF: animaciones de sprites

  • Una secuencia solo se repite en bucle cuando el byte bajo de su palabra +2 no es cero; con 0 se reproduce una vez y se detiene. Todas las secuencias originales guardan 1, así que una herramienta que escriba cero congela los elementos animados.
  • Los fotogramas de textures/*.gaf y anims/vismasks.gaf deben ir sin comprimir. El juego los lee como arrays de píxeles simples.
  • Algunas secuencias se distribuyen con fotogramas de duración 0; el juego muestra un fotograma así durante un tick. No los «corrijas» con un valor por defecto.
  • El índice 0 de la paleta no es transparente por sí mismo. Solo lo son el color clave de un fotograma sin comprimir y los tramos de salto de uno comprimido.
  • Las filas de píxeles comprimidas pueden ser más cortas que Width. El juego sigue leyendo los bytes siguientes; kbot completa la fila con píxeles transparentes y avisa. Ningún archivo original tiene filas así.
  • Los orígenes de las capas son hotspots: cada capa de un fotograma compuesto se coloca de forma que su origen caiga sobre el origen del fotograma.
  • anims/terrain.gaf y anims/vismasks.gaf tienen Version == 0 en su cabecera. El juego ignora la palabra de versión.
  • Los .taf de TA: Kingdoms son de dos clases. Un .taf con paleta ES un GAF, con el mismo formato en disco, salvo que TAK toma la paleta de un .pcx por bando en lugar de la paleta global de TA. Un .taf truecolor reutiliza el mismo contenedor, pero guarda píxeles ARGB de 16 bits y no necesita paleta. Lo que manda es el byte de formato del fotograma (0/1 = con paleta, 4/5 = truecolor), no la extensión: consulta TAF / TSF.

TAF / TSF: animaciones truecolor

  • .taf tiene dos significados: con paleta (se lee como GAF) o truecolor (se lee con kbot taf). Comprueba siempre el byte de formato del fotograma, nunca el nombre del archivo, aunque por convención la mayoría de los archivos truecolor de TAK lleven un sufijo _4444 / _1555.
  • La exportación a GIF pierde información. GIF solo admite un recorte de 1 bit y 255 colores, así que el alfa suave de ARGB4444 se convierte en bordes duros. Usa APNG (kbot taf export --format apng) para conservar el canal alfa real.
  • El campo de nombre del fotograma y el byte de flags 0x0B pueden contener basura. Consérvalos tal cual para un viaje de ida y vuelta exacto byte a byte; no los normalices.
  • Un Delay / Duration de 0 es válido: como en GAF, un fotograma de cero ticks lo controlan los eventos (los fondos de menú estáticos lo usan). No lo «corrijas».

PCX: imágenes

  • TA ignora BytesPerLine. Los lectores estándar descartan el relleno cuando BytesPerLine > Width; TA 3.1c decodifica exactamente Width bytes por fila, así que los archivos con relleno se desplazan en el juego. Escribe BytesPerLine == Width y compruébalo con kbot pcx describe.
  • TA solo carga la versión 5, y decodifica todos los archivos como datos de 8 bits en un solo plano.
  • Los bytes literales con los dos bits altos activados tienen que escaparse con RLE. Un byte suelto con valor 0xC0–0xFF no es válido como literal; escríbelo como un tramo de longitud 1 (0xC1, 0xFF para un solo 0xFF). Si no se trata bien, la decodificación se desincroniza al cabo de una fila.
  • El juego toma los 768 bytes finales como paleta, tengan o no la marca 0x0C; los lectores estándar necesitan la marca.

PAL / ALP / LHT / SHD: paletas y tablas de consulta

  • El 4.º byte de cada entrada NO es alfa. Es un byte de relleno sin uso que Cavedog siempre ponía a 0x00. Las herramientas de paletas de código abierto que lo tratan como alfa no consiguen renderizar la paleta (alfa=0 → todo transparente).
  • El índice 0 es negro, no transparente. El terreno, los minimapas y los fondos lo dibujan opaco; los sprites eligen su propio color clave transparente.
  • Un palette.pal vacío o ausente se sustituye por palette.pcx (sus últimos 768 bytes); de un .pal de más de 1024 bytes se lee hasta el byte 1024.
  • .alp / .lht / .shd NO son paletas RGB: .alp es una tabla de 256×256 y .shd / .lht son tablas de 32×256 de índices de la paleta, y el juego ignora (y reconstruye) una tabla de cualquier otro tamaño. Renderizarlas con kbot pal describe muestra basura; usa kbot pal lookup en su lugar.
  • La paleta de TA tiene 13 tripletes RGB duplicados. Si tu editor elimina duplicados al importar (algunos lo hacen), pierdes entradas y la paleta pasa sin avisar a tener 243 entradas.

FNT: fuentes de mapa de bits

  • Offsets[c] == 0 significa «sin glifo», no «glifo en el desplazamiento 0». El desplazamiento 0 cae en mitad de la cabecera: Cavedog reutiliza el cero como valor centinela.
  • El orden de los bits es MSB primero dentro de cada byte. En las fuentes de mapa de bits modernas es más habitual LSB primero; no lo des por hecho.
  • El flujo de bits es continuo entre filas: no hay relleno al final de cada línea de barrido.

Perfiles de IA

  • Los archivos de IA de TA: Kingdoms no tienen directivas plan: solo líneas weight/limit sueltas. El analizador de kbot abre un plan default implícito; los lectores deberían tolerar que falte el bloque. Consulta Perfiles sin plan de TA:K.
  • No hay validación en ninguna parte. Nombres de unidad mal escritos, valores de peso rotos, líneas fuera de plan: todo se ignora sin avisar. La primera señal de un perfil roto es que «la IA se comporta de forma rara», sin ningún mensaje en el registro.
  • Los alias de categoría (PLANT, LEVEL3) solo «existen» si al menos una unidad los declara en Category=. Escribe mal LEVL3 y la directiva no hará nada, sin avisar.

Sonidos

  • Un WAV que falta no suena, pero no da error. Escribe mal select1=cmsdel1 (letras cambiadas de sitio) y el motor no reproduce nada: ni registro ni sonido de reserva.
  • La extensión .wav está implícita en los valores TDF: no la escribas nunca. select1=cmdsel1.wav se convierte en sounds/cmdsel1.wav.wav y no encuentra nada.

Particularidades de TA: Kingdoms

  • TAK necesita -disablecavedogverification como argumento de línea de comandos para cargar la mayoría de los archivos modificados. Sin esa opción, el motor rechaza todo aquello cuyo hash no esté en su lista de permitidos.
  • TAK tiene 8 códigos de bando en los datos, no 4: ARA / TAR / VER / ZON para los cuatro bandos jugables, más CRE (Creon, Iron Plague), MON (monstruos), LIF (fauna) y NPC (personajes de la campaña). El filtrado de listas de unidades tiene que tenerlos todos en cuenta.
  • Las armas de TAK van en línea dentro de cada FBI como subsecciones [WEAPON1]–[WEAPON3], no en un directorio weapons/*.tdf aparte.
  • Los menús de construcción de TAK son lineales, no de 2×3. Cada constructor tiene un directorio canbuild/<builder>/<unit>.tdf con un único bloque [Menu] { Priority = N; }.

Véase también

  • Tutorial de modding: recorrido completo para crear un mod de unidad de TA.
  • Glosario: definiciones de todos los términos comunes a varios formatos que aparecen arriba.
  • Inicio rápido: cinco comandos de kbot para empezar.