Todas las páginas de formatos ↓
Mapas y terreno

Mapas de TA: Kingdoms (.tnt + .ota + .crt + .kmp)

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

Los mapas de TA: Kingdoms son una variante de TNT (con otra palabra IDVersion) acompañada de uno o dos archivos de metadatos, más un formato de archivo comprimido de campaña HPI v2 para las misiones de un jugador. Esto se parece bastante más al modelo de mapas de TA de lo que sugerían las antiguas notas de investigación sobre «BTM/BMP de mapa de alturas»: en una instalación real de TA:K de GoG no hay ni rastro de archivos .btm ni de BMP acompañantes.

El lector de HPI v2 que ya tiene kbot maneja los archivos comprimidos .kmp de forma transparente. El lector de TNT de kbot reconoce la palabra de versión de TA:K y decodifica la cabecera, el mapa de alturas por DataUnit, la cuadrícula de mapeado de texturas (tablas de nombres de terreno y de desplazamientos U/V), la cuadrícula de colocación de elementos con su tabla de nombres y el minimapa incrustado: basta para renderizar un mapa completo a resolución completa componiendo los JPG de terreno externos y los sprites GAF de los elementos. Esta página documenta lo que se puede verificar a partir de la instalación distribuida y las lagunas que quedan.

Important

Actualización de estado (respecto a la versión original de esta página como «notas de investigación»). Los tipos de archivo de los que hablaba antes esta página (.btm, BMP acompañantes, PCX de paleta por bando) no existen realmente en la instalación de TA: Kingdoms que distribuye GoG. Los tipos de archivo reales se documentan más abajo. Si quieres compararlo con otro proyecto de código abierto de TA:K, consulta iiCompleteDestruction; su analizador está más completo que el de kbot en algunas estructuras propias de TA:K.


Archivos que forman un mapa de TA:K

Recuento en el directorio de mapas de la instalación de GoG:

Extensión Cantidad Finalidad
.kmp 181 Archivo comprimido HPI v2 que reúne el mapa, los scripts y los recursos de una misión de campaña
.tnt 55 Datos del terreno del mapa (binario con forma de TNT y una palabra IDVersion propia de TA:K)
.ota 55 Metadatos del mapa: formato TDF, con la misma forma que el .ota de TA y campos propios de TAK
.txt 55 Descripción del mapa en texto libre (unas pocas palabras; se muestra en el lobby)
.crt 33 Archivo acompañante del escenario: unidades colocadas de antemano, motor de reglas por jugador, regiones de disparo con nombre
.tdf 6 Archivos de ajustes de juego por mapa (ajuste de campaña, empujones a la IA)

Un mapa multijugador típico se distribuye como el trío .tnt + .ota + .txt, a veces con un .crt acompañante. Las misiones de campaña se empaquetan en archivos comprimidos .kmp que reúnen el mismo conjunto con los scripts de la misión.

Tip

Lista el contenido de un mapa de TA:K sin desempaquetar nada:

# The HPI v2 reader handles .kmp transparently
kbot hpi list /path/to/tak/maps/adamantine\ gate.kmp -v
kbot hpi info /path/to/tak/maps/adamantine\ gate.kmp

.tnt: el terreno de TA:K (TNT v2)

TA:K reutiliza la estructura TNT de TA, pero sube la palabra IDVersion. Volcado hexadecimal de abnar's terrace.tnt:

00000000: 00 40 00 00 20 01 00 00 e0 00 00 00 3a 00 00 00   .@.. .......:...
00000010: 34 00 00 00 34 fc 00 00 34 f4 02 00 16 00 00 00   4...4...4.......

El primer uint32 es 0x00004000, frente al 0x00002000 del TNT de TA. El contenedor sigue siendo una cabecera seguida de secciones direccionadas por punteros, pero TA:K no es en absoluto un formato de mosaico de casillas. Donde TA guarda una cuadrícula de índices de casilla y una paleta de gráficos de casilla de 32×32, TA:K guarda el terreno como una cuadrícula de mapeado de texturas que hace referencia a texturas JPG externas, más un mapa de alturas aparte y una cuadrícula de colocación de elementos. Todo lo que sigue está verificado en los 55 mapas distribuidos:

  1. Width/Height cuentan DataUnits de 16 px, no píxeles. Un mapa «15 × 15» como athri cay guarda Width = Height = 480 DataUnits → 480 × 16 = 7680 px de lado. El mapa de alturas y la cuadrícula de elementos se muestrean por DataUnit; el terreno se muestrea en una cuadrícula más gruesa de Graphic Units de 32 px, exactamente la mitad que la de DataUnits en cada eje (guW = Width/2).
  2. La cabecera son doce uint32 consecutivos de desplazamientos y recuentos; los nombres de campo de TA ya no describen su contenido. La tabla de abajo da el significado en TA:K.
  3. Los punteros de sección son absolutos, así que cada sección se lee a partir de su propio puntero y de una longitud calculada.
Desplazamiento Campo de TA:K Tamaño de la sección Notas
0x00 Version — 0x4000 (TA escribe 0x2000)
0x04 Width — DataUnits; ×16 → píxeles, ÷2 → Graphic Units
0x08 Height — DataUnits
0x0C SeaLevel — umbral de altura del agua
0x10 HeightMapOffset Width × Height bytes un byte de altura por DataUnit
0x14 AttributesOffset Width × Height × 2 cuadrícula de elementos: un índice uint16 por DataUnit (≥0xFF00 = ninguno)
0x18 FeatureNamesOffset Count × 132 tabla de nombres de elementos (índice de 4 bytes + nombre de 128 bytes)
0x1C FeatureCount — número de tipos de elemento
0x20 TerrainNamesOffset guW × guH × 4 nombre de textura por GU → terrain/%08x.jpg
0x24 UMappingOffset guW × guH bytes desplazamiento de columna por GU dentro de su textura (×32 px)
0x28 VMappingOffset guW × guH bytes desplazamiento de fila por GU dentro de su textura (×32 px)
0x2C MiniMapOffset 8 + 126×126 uint32 w, uint32 h y después los índices

El mapa de alturas (0x10) tiene un byte por DataUnit: es un campo de elevación en escala de grises, no un mapa de bits de color. El terreno se reconstruye por mapeado de texturas: para cada Graphic Unit, la tabla de nombres de terreno (0x20) da un archivo de textura (terrain/<name>.jpg, con el nombre escrito como 8 dígitos hexadecimales en minúsculas) y las tablas U/V (0x24/0x28) dan la subcasilla de 32×32 que hay que copiar de ese JPG en (u×32, v×32). La cuadrícula de elementos (0x14) es la capa de colocación: un array Width × Height de uint16 en el que cada celda es o bien un índice de elemento en la tabla de nombres o bien un valor centinela alto (≥0xFF00) que significa «aquí no hay elemento»; la celda DataUnit (x, y) de una colocación corresponde al píxel de terreno (x×16, y×16). La tabla de nombres (0x18) usa la misma disposición de entradas de 132 bytes que la tabla TileAnim de TA.

El bloque del minimapa mide siempre 126 × 126 en todo el material distribuido y usa el mismo byte de vacío 0x64 que TA como relleno fuera de los mapas no cuadrados.

Note

Qué funciona hoy con los TNT de TA:K. kbot tnt describe muestra la cabecera, el reino, las dimensiones del mapa de alturas y del terreno y el desglose de elementos. kbot tnt preview --vfs <root> renderiza el terreno con texturas a resolución completa y compone encima el sprite GAF de cada elemento, anclado en su hotspot: el mapa completo tal como lo dibuja el juego. kbot tnt image renderiza el mapa de alturas en escala de grises, que no depende de nada más (no necesita texturas externas; --features superpone marcadores coloreados por categoría). kbot tnt minimap exporta la vista previa incrustada de 126 × 126.

Paleta del minimapa: una por reino

TA:K no colorea su minimapa con una única paleta global. Cada mapa genera su vista previa de 126 × 126 con la paleta de texturas del reino al que pertenece: el campo kingdom= del .ota acompañante (aramon / taros / veruna / zhon / creon). Si renderizas los mismos índices con la paleta de otro reino (o con el PALETTE.PAL de TA) obtienes ruido moteado; con la correcta salen agua, playas y terreno naturales.

kbot tnt minimap resuelve el reino automáticamente a partir del .ota acompañante. Cuando no hay .ota (p. ej., un .tnt suelto), pasa --kingdom <name> de forma explícita:

kbot tnt minimap "athri cay.tnt" -t mini.png          # auto: veruna
kbot tnt minimap loose.tnt --kingdom aramon -t mini.png

.ota: metadatos del mapa (TDF, casi todo conocido)

El .ota de TA:K tiene el mismo formato con forma de TDF que el de TA, con varios campos propios de TAK. El archivo completo de abnar's terrace.ota:

[GlobalHeader]
{
    Copyright=Copyright 1998 Cavedog Entertainment. All rights reserved.;
    missionname=Abnar's Terrace;
    missiondescription=9 x 7  4 Player  32MB;
    kingdom=veruna;          // ← TA:K-specific: the side the map "belongs" to
    numplayers=4;
    size=9 x 7;              // ← TA:K-specific: free-text size for the lobby
    memory=32 MB;            // ← TA:K-specific: ~RAM requirement for the lobby
    hasscenario=0;
    [Map Data]
    {
        Type=Network 1;
        aiprofile=DEFAULT;
        [specials]
        {
            [special0] { specialwhat=StartPos1; XPos=37;   ZPos=190; }
            [special1] { specialwhat=StartPos2; XPos=215;  ZPos=38;  }
            …
        }
    }
}
Campo Equivalente en TA Notas
kingdom= ninguno Afinidad de bando (aramon / taros / veruna / zhon / creon). El lobby filtra por él; también elige la paleta de terreno/minimapa con la que está coloreada la vista previa incrustada del .tnt.
size= ninguno Tamaño del mapa legible para el lobby.
memory= ninguno RAM recomendada. Solo estético.
hasscenario= ninguno 1 en las misiones de campaña, 0 en los mapas de escaramuza.
[Map Data] [Schema N] Reduce la subsección de esquema a un único bloque (TA:K nunca distribuye más de un esquema por mapa).

Todo lo demás (StartPos1..N, aiprofile=, etc.) funciona igual que en TA: el visor de OTA de kbot mount maneja ambos sin cambios.


.kmp: archivos comprimidos HPI v2 de misiones de campaña

.kmp es un archivo comprimido HPI v2 con otra extensión. El principio de adamantine gate.kmp en hexadecimal:

00000000: 48 41 50 49 00 00 02 00 57 32 02 00 77 00 00 00   HAPI....W2..w...
00000010: 15 32 02 00 42 00 00 00 20 00 00 00 00 00 00 00   .2..B... .......
00000020: 53 51 53 48 …                                     SQSH…

Es exactamente la forma de la cabecera v2 (marca HAPI → versión 0x00020000 → cabecera v2 de 24 bytes → chunks SQSH). kbot hpi list, info y extract funcionan directamente. Cada .kmp suele contener:

  • El .tnt y el .ota de la misión
  • Unos cuantos GAF de cinemáticas y de instrucciones de la misión
  • Archivos COB de scripts de misión: TA:K reutiliza el formato COB (VersionSignature == 6) para los scripts de misión, en lugar de un lenguaje de scripting aparte. Aquí están los 3885 usos del opcode MISSION_COMMAND (0x10073000) de la instalación comercial de TAK. Consulta Diferencias de COB v6 en TA: Kingdoms y el apéndice C de cob.md para el formato en disco y el pool de cadenas de nombres de sonido por COB al que indexan las órdenes de misión.
  • A veces, modificaciones de unidades propias de la misión

.crt: script del escenario (unidades, reglas, disparadores)

Un .crt contiene la capa con script de un mapa: las unidades colocadas antes de que empiece la partida, el motor de reglas por jugador que dirige la IA de escaramuza y los objetivos de campaña, y las regiones de disparo rectangulares con nombre a las que hacen referencia esas reglas. Los mapas multijugador distribuyen un esqueleto vacío (sin unidades, nueve plazas de jugador vacías, sin disparadores, 56 bytes); los mapas de campaña y los especiales rellenan todas las secciones, hasta unos 120 KB.

Todo el archivo es little-endian y es una imagen directa de las estructuras en memoria del motor, así que los registros de unidad incluyen varios campos de relleno sin inicializar.

Desplazamiento Tipo Campo Notas
0x00 uint32 Signature 0x3F800000: marca 1.0f en IEEE-754
0x04 uint32 Unknown1 0 en todos los mapas distribuidos salvo uno
0x08 uint32 UnitCount número de registros de unidades colocadas que siguen

abnar's terrace.crt (un esqueleto vacío) empieza así:

00000000: 00 00 80 3f 00 00 00 00 00 00 00 00 09 00 00 00

1.0f, Unknown1 = 0, UnitCount = 0 y después el número de jugadores, 9.

Registros de unidad (568 bytes cada uno)

Desplazamiento Tipo Campo
+0 char[256] UnitType (terminado en NUL)
+256 char[256] UniqueName (normalmente vacío)
+512 uint32 X (mundo)
+516 uint32 Y (eje de altura)
+520 uint32 Z (mundo)
+524 uint32 PlayerId (empieza en 0)
+528 uint32 HealthPercent (normalmente 100)
+532 uint32 ArmorPercent (normalmente 100)
+536 uint32 WeaponPercent (normalmente 100)
+540 uint32 Angle (normalmente 180)
+544 uint32 Veteran
+548 uint32 desconocido
+552 uint32 desconocido
+556 uint32 FootprintX
+560 uint32 FootprintZ
+564 uint32 desconocido

Jugadores, reglas, condiciones, acciones

Después de las unidades, un recuento de jugadores uint32 (siempre 9) precede a otros tantos bloques de jugador. Cada bloque de jugador es un recuento de reglas uint32 seguido de esas reglas. Una regla es:

  • un recuento de condiciones uint32 y después cada condición, que es un opcode uint32 y cinco posiciones de argumento de 64 bytes;
  • un recuento de acciones uint32 y después cada acción, que es un opcode uint32 y cinco posiciones de argumento de 64 bytes.

Disparadores

Un recuento de disparadores uint32 al final precede a otros tantos registros de disparador. Cada uno es un nombre de 256 bytes terminado en NUL seguido de cuatro límites uint32 (Left, Top, Right, Bottom) en celdas del mapa. Los nombres son legibles (The Hill, Player 1).

Herramientas

kbot crt describe <map.crt> muestra el desglose por tipo de unidad, los recuentos de reglas y las regiones de disparo; añade --verbose para ver la lista completa de colocaciones. La herramienta MCP crt_describe devuelve los mismos datos en JSON.

Un archivo, cairbray coast landing.crt, tiene una cabecera desplazada y editada a mano que no encaja con esta disposición; el analizador lo rechaza con un error claro en lugar de decodificarlo mal.


.txt: descripción en texto libre

Una cadena ASCII de una línea que se usa en el lobby. Por ejemplo, abnar's terrace.txt: 9 x 7 4 Player 32MB (la misma cadena que lleva el missiondescription del .ota). Probablemente las herramientas de creación escribían las dos al exportar; el juego parece mostrar el valor del .ota.


Trabajar hoy con mapas de TA:K

Opciones prácticas, de menos a más esfuerzo:

  1. Inspeccionar sin restricciones: kbot hpi list/info/extract sobre archivos .kmp funciona sin más. .ota y .txt son texto plano.
  2. Describir un mapa: kbot tnt describe <map.tnt> muestra la cabecera de TA:K, el reino, las dimensiones del mapa de alturas y del terreno y un desglose de elementos.
  3. Renderizar un minimapa: kbot tnt minimap <map.tnt> -t mini.png exporta la vista previa incrustada de 126 × 126 en color real y elige automáticamente la paleta del reino a partir del .ota acompañante (puedes forzarla con --kingdom; consulta la nota sobre la paleta de arriba).
  4. Renderizar el mapa completo con texturas: kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.png mapea las texturas del terreno a partir de los terrain/*.jpg de la instalación y compone el sprite GAF de cada elemento, con lo que produce el mapa tal como lo renderiza el juego (athri cay → 7680 × 7680). La paleta de los sprites de elementos se lee de palettes/<kingdom>_features.pcx.
  5. Renderizar el mapa de alturas: kbot tnt image <map.tnt> -t height.png no necesita recursos externos; genera el mapa de alturas por DataUnit en escala de grises (--features superpone marcadores de colocación coloreados por categoría).
  6. Reempaquetar un archivo comprimido de campaña: hoy kbot hpi pack solo produce v1, así que un .kmp reempaquetado no cargaría. Para editar a mano un .kmp, extráelo, modifica los archivos sueltos y usa un empaquetador de terceros que entienda v2 hasta que kbot sepa escribir v2.

Warning

TA: Kingdoms necesita -disablecavedogverification para cargar la mayoría de los archivos modificados, mapas modificados incluidos. Sin esa opción, el motor rechaza todo aquello cuyo hash no esté en su lista de permitidos. Indícalo en las instrucciones de instalación de cualquier mod.


Qué puede hacer kbot ahora mismo con los mapas de TA:K y qué no

Operación Estado
Leer las cabeceras y la lista de archivos de un .kmp (HPI v2) ✅
Extraer archivos de un .kmp ✅
Analizar un .ota (formato TDF) ✅
Leer la cabecera de un .tnt de TA:K (kbot tnt describe) ✅
Exportar el minimapa de un .tnt de TA:K (kbot tnt minimap) ✅ (color real: paleta por reino a partir del .ota)
Renderizar el mapa completo de TA:K con texturas (kbot tnt preview --vfs) ✅ (terreno con texturas + sprites GAF de los elementos)
Renderizar el mapa de alturas de TA:K (kbot tnt image) ✅ (escala de grises sin dependencias; --features superpone marcadores)
Escribir un .tnt de TA:K (kbot tnt pack) ❌
Escribir un .kmp (empaquetado HPI v2) ❌

Las pull requests para cualquiera de los puntos ❌ son bienvenidas. Con el mapa de alturas, la cuadrícula de mapeado de texturas, la cuadrícula de elementos y la tabla de elementos ya decodificados, el terreno y los elementos se renderizan a resolución completa; lo que falta es la parte de escritura para hacer el viaje de ida y vuelta con mapas de TA:K editados y el empaquetado v2 de .kmp.


Véase también

  • HPI: el contenedor de archivo comprimido v2 (.kmp es un HPI v2 con otra extensión).
  • TNT: el formato TNT de TA; TA:K reutiliza la estructura con un IDVersion 0x4000.
  • TDF: el formato con el que se analiza el .ota.
  • GAF: los archivos de animación .taf que se usan en todo TA:K (cinemáticas dentro de archivos comprimidos .kmp).
  • Interfaz de TA: Kingdoms: el formato de widgets de menús y HUD.
  • Glosario: side, heightmap.