Todas as páginas de formatos ↓
Mapas e terreno

Mapas do TA: Kingdoms — .tnt + .ota + .crt + .kmp

Fonte: coreprime/kbot @ 0ab97bf · Editar no GitHub

Os mapas do TA: Kingdoms são uma variante do TNT (com outra palavra IDVersion) acompanhada de um ou dois ficheiros de metadados, mais um formato de arquivo de campanha HPI v2 para as missões de um jogador. Isto está bastante mais perto do modelo de mapas do TA do que as antigas notas de investigação sobre "BTM/BMP de mapa de alturas" sugeriam: numa instalação real do TA:K da GoG não há qualquer .btm nem BMP auxiliares.

O leitor de HPI v2 que o kbot já tem trata os arquivos .kmp de forma transparente. O leitor de TNT do kbot reconhece a palavra de versão do TA:K e descodifica o cabeçalho, o mapa de alturas de DataUnits, a grelha de mapeamento de texturas (tabelas de nomes de terreno + deslocamentos U/V), a grelha de colocação de elementos

  • a tabela de nomes, e o minimapa incorporado: o suficiente para renderizar um mapa completo em resolução total, compondo os JPG de terreno externos e os sprites GAF dos elementos. Esta página documenta o que é verificável a partir da instalação distribuída e as lacunas que restam.

Important

Ponto da situação (face à versão original desta página, de "notas de investigação"). Os tipos de ficheiro de que esta página falava (.btm, BMP auxiliares, PCX de paleta por lado) não existem de facto na instalação do TA: Kingdoms distribuída pela GoG. Os tipos de ficheiro reais estão documentados abaixo. Para comparar com outro projeto de código aberto para o TA:K, veja iiCompleteDestruction; a implementação do analisador desse projeto é mais completa do que a do kbot em algumas estruturas próprias do TA:K.


Ficheiros que compõem um mapa do TA:K

Contagem feita na pasta de mapas da instalação da GoG:

Extensão Quantidade Finalidade
.kmp 181 Arquivo HPI v2 que agrupa o mapa, os scripts e os recursos de uma missão da campanha
.tnt 55 Dados do terreno do mapa (binário com a forma de TNT e uma palavra IDVersion própria do TA:K)
.ota 55 Metadados do mapa: formato TDF, com a mesma forma do .ota do TA e campos próprios do TAK
.txt 55 Descrição do mapa em texto livre (umas poucas palavras; mostrada no lobby)
.crt 33 Ficheiro auxiliar de cenário: unidades pré-colocadas, motor de regras por jogador, regiões de acionadores com nome
.tdf 6 Ficheiros de ajustes de jogabilidade por mapa (afinação da campanha, pequenos empurrões à IA)

Um mapa multijogador típico é distribuído como um trio .tnt + .ota + .txt, por vezes com um ficheiro auxiliar .crt. As missões da campanha estão empacotadas em arquivos .kmp que agrupam o mesmo conjunto com os scripts da missão.

Tip

Liste o conteúdo de um mapa do TA:K sem desempacotar 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 — terreno do TA:K (TNT v2)

O TA:K reutiliza a estrutura TNT do TA, mas muda a palavra IDVersion. Dump 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.......

O primeiro uint32 é 0x00004000; compare com o TNT do TA, que usa 0x00002000. O contentor continua a ser um cabeçalho seguido de secções endereçadas por ponteiros, mas o TA:K não é, de todo, um formato de mosaicos. Onde o TA guarda uma grelha de índices de mosaicos + uma paleta de gráficos de mosaicos de 32×32, o TA:K guarda o terreno como uma grelha de mapeamento de texturas que refere texturas JPG externas, mais um mapa de alturas separado e uma grelha de colocação de elementos. Tudo o que se segue foi verificado nos 55 mapas distribuídos:

  1. Width/Height são contagens de DataUnits de 16 px, não de píxeis. Um mapa de "15 × 15" como athri cay guarda Width = Height = 480 DataUnits → 480 × 16 = 7680 px de lado. O mapa de alturas e a grelha de elementos são amostrados por DataUnit; o terreno é amostrado numa grelha mais grosseira de Graphic Units de 32 px, exatamente metade da grelha de DataUnits em cada eixo (guW = Width/2).
  2. O cabeçalho são doze uint32 seguidos de deslocamentos e contagens; os nomes dos campos do TA já não descrevem o conteúdo. A tabela abaixo dá o significado no TA:K.
  3. Os ponteiros das secções são absolutos, por isso cada secção é lida pelo seu próprio ponteiro + o comprimento calculado.
Deslocamento Campo do TA:K Tamanho da secção Notas
0x00 Version — 0x4000 (o TA escreve 0x2000)
0x04 Width — DataUnits; ×16 → píxeis, ÷2 → Graphic Units
0x08 Height — DataUnits
0x0C SeaLevel — limiar de altura da água
0x10 HeightMapOffset Width × Height bytes um byte de altura por DataUnit
0x14 AttributesOffset Width × Height × 2 grelha de elementos: índice uint16 por DataUnit (≥0xFF00 = nenhum)
0x18 FeatureNamesOffset Count × 132 tabela de nomes de elementos (índice de 4 bytes + nome de 128 bytes)
0x1C FeatureCount — número de tipos de elementos
0x20 TerrainNamesOffset guW × guH × 4 nome da textura de cada GU → terrain/%08x.jpg
0x24 UMappingOffset guW × guH bytes deslocamento da coluna de cada GU na sua textura (×32px)
0x28 VMappingOffset guW × guH bytes deslocamento da linha de cada GU na sua textura (×32px)
0x2C MiniMapOffset 8 + 126×126 uint32 w, uint32 h e depois os índices

O mapa de alturas (0x10) tem um byte por DataUnit: um campo de elevação em tons de cinzento, não um mapa de bits a cores. O terreno é reconstruído por mapeamento de texturas: para cada Graphic Unit, a tabela de nomes de terreno (0x20) indica um ficheiro de textura (terrain/<name>.jpg, com o nome formatado como hexadecimal de 8 dígitos em minúsculas), e as tabelas U/V (0x24/0x28) indicam o submosaico de 32×32 a copiar desse JPG, em (u×32, v×32). A grelha de elementos (0x14) é a camada de colocação: um vetor Width × Height de uint16, em que cada célula é um índice de elemento na tabela de nomes ou uma sentinela alta (≥0xFF00) que significa "nenhum elemento aqui"; a célula de DataUnit (x, y) de uma colocação corresponde ao píxel do terreno (x×16, y×16). A tabela de nomes (0x18) usa a mesma disposição de entradas de 132 bytes que a tabela TileAnim do TA.

O bloco do minimapa tem sempre 126 × 126 em todos os mapas distribuídos e usa o mesmo byte vazio 0x64 que o TA para o preenchimento fora dos mapas não quadrados.

Note

O que já funciona nos TNT do TA:K. kbot tnt describe mostra o cabeçalho, o reino, as dimensões do mapa de alturas/terreno e a distribuição dos elementos. kbot tnt preview --vfs <root> renderiza o terreno com texturas em resolução total e compõe por cima o sprite GAF de cada elemento, ancorado no seu ponto ativo: o mapa completo, tal como o jogo o desenha. kbot tnt image renderiza o mapa de alturas em tons de cinzento, que é autónomo (não precisa de texturas externas; --features sobrepõe marcas coloridas por categoria). kbot tnt minimap exporta a pré-visualização incorporada de 126 × 126.

Paleta do minimapa — uma por reino

O TA:K não colore o minimapa com uma única paleta global. Cada mapa traz a sua pré-visualização de 126 × 126 já calculada com a paleta de texturas do reino a que pertence: o campo kingdom= do .ota associado (aramon / taros / veruna / zhon / creon). Renderizar os mesmos índices com a paleta do reino errado (ou com o PALETTE.PAL do TA) produz ruído salpicado; com a paleta certa, obtém-se água, praias e terreno naturais.

kbot tnt minimap determina automaticamente o reino a partir do .ota associado. Quando não há .ota (por exemplo, num .tnt solto), passe --kingdom <name> explicitamente:

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

.ota — Metadados do mapa (TDF, quase tudo familiar)

O .ota do TA:K tem o mesmo formato ao estilo TDF que o do TA, com vários campos próprios do TAK. Ficheiro 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 no TA Notas
kingdom= nenhum Afinidade de lado (aramon / taros / veruna / zhon / creon). O lobby filtra por este campo; também seleciona a paleta do terreno/minimapa com que a pré-visualização gravada no .tnt está colorida.
size= nenhum Tamanho do mapa legível, para o lobby.
memory= nenhum RAM sugerida. Cosmético.
hasscenario= nenhum 1 nas missões da campanha, 0 nos mapas de escaramuça.
[Map Data] [Schema N] Corresponde à subsecção do esquema, reduzida a um único bloco (o TA:K só inclui um esquema por mapa).

Tudo o resto (StartPos1..N, aiprofile=, etc.) funciona exatamente como no TA; o visualizador de OTA de kbot mount trata ambos sem alterações.


.kmp — Arquivos HPI v2 das missões da campanha

O .kmp é um arquivo HPI v2 com outro nome. Início, em hexadecimal, de adamantine gate.kmp:

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…

É exatamente a forma do cabeçalho v2 (marcador HAPI → versão 0x00020000 → cabeçalho v2 de 24 bytes → blocos SQSH). kbot hpi list, info e extract funcionam todos diretamente. Cada .kmp contém normalmente:

  • O .tnt e o .ota da missão
  • Alguns GAF de cinemáticas / briefing
  • Ficheiros COB com os scripts da missão: o TA:K reutiliza o formato COB (VersionSignature == 6) para os scripts das missões, em vez de uma linguagem de scripting separada. Os 3885 pontos de opcode MISSION_COMMAND (0x10073000) da instalação comercial do TAK estão aqui. Veja TA: Kingdoms — diferenças do COB v6 e o Apêndice C de cob.md para o formato binário e o conjunto de nomes de sons de cada COB, que os comandos de missão indexam.
  • Por vezes, alterações a unidades específicas da missão

.crt — Script de cenário (unidades, regras, acionadores)

Um .crt contém a camada de scripts de um mapa: as unidades colocadas antes do início da partida, o motor de regras por jogador que conduz a IA da escaramuça e os objetivos da campanha, e as regiões retangulares de acionadores, com nome, a que essas regras se referem. Os mapas multijogador trazem um esboço vazio (sem unidades, nove lugares de jogador vazios, sem acionadores, 56 bytes); os mapas da campanha e os mapas especiais preenchem todas as secções, até ~120 KB.

O ficheiro inteiro é little-endian e é uma imagem direta das estruturas do motor em memória, por isso os registos das unidades incluem vários campos de preenchimento não inicializados.

Deslocamento Tipo Campo Notas
0x00 uint32 Signature 0x3F800000: marcador IEEE-754 1.0f
0x04 uint32 Unknown1 0 em todos os mapas distribuídos menos um
0x08 uint32 UnitCount número de registos de unidades colocadas que se seguem

abnar's terrace.crt (um esboço vazio) começa assim:

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

1.0f, Unknown1 = 0, UnitCount = 0 e depois o número de jogadores, 9.

Registos de unidades (568 bytes cada)

Deslocamento Tipo Campo
+0 char[256] UnitType (terminado em NUL)
+256 char[256] UniqueName (normalmente vazio)
+512 uint32 X (mundo)
+516 uint32 Y (eixo da altura)
+520 uint32 Z (mundo)
+524 uint32 PlayerId (a contar de 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 desconhecido
+552 uint32 desconhecido
+556 uint32 FootprintX
+560 uint32 FootprintZ
+564 uint32 desconhecido

Jogadores, regras, condições, ações

Depois das unidades, um uint32 com o número de jogadores (sempre 9) precede esse número de blocos de jogador. Cada bloco de jogador é um uint32 com o número de regras, seguido dessas regras. Uma regra é:

  • um uint32 com o número de condições; cada condição é um opcode uint32 e cinco posições de argumento de 64 bytes;
  • um uint32 com o número de ações; cada ação é um opcode uint32 e cinco posições de argumento de 64 bytes.

Acionadores

Um uint32 final com o número de acionadores precede esse número de registos de acionadores. Cada um é um nome de 256 bytes terminado em NUL, seguido de quatro limites uint32 (Left, Top, Right, Bottom) em células do mapa. Os nomes são legíveis (The Hill, Player 1).

Ferramentas

kbot crt describe <map.crt> mostra a distribuição dos tipos de unidades, o número de regras e as regiões dos acionadores; acrescente --verbose para obter a lista completa de colocações. A ferramenta MCP crt_describe devolve os mesmos dados em JSON.

Um ficheiro, cairbray coast landing.crt, tem um cabeçalho deslocado, editado à mão, que não corresponde a esta disposição; o analisador rejeita-o com um erro claro, em vez de o descodificar mal.


.txt — Descrição em texto livre

Uma cadeia de caracteres ASCII de uma linha, usada no lobby. Por exemplo, abnar's terrace.txt: 9 x 7 4 Player 32MB (a mesma cadeia que o missiondescription do .ota contém). As ferramentas de criação provavelmente escreviam ambas na exportação; o jogo parece mostrar o valor do .ota.


Trabalhar hoje com mapas do TA:K

Opções práticas, por ordem crescente de esforço:

  1. Inspecionar à vontade — kbot hpi list/info/extract funciona diretamente com ficheiros .kmp. O .ota e o .txt são texto simples.
  2. Descrever um mapa — kbot tnt describe <map.tnt> mostra o cabeçalho do TA:K, o reino, as dimensões do mapa de alturas/terreno e a distribuição dos elementos.
  3. Renderizar um minimapa — kbot tnt minimap <map.tnt> -t mini.png exporta a pré-visualização incorporada de 126 × 126 em cor real e escolhe automaticamente a paleta do reino a partir do .ota associado (substitua-a com --kingdom; veja a nota sobre a paleta acima).
  4. Renderizar o mapa completo com texturas — kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.png aplica ao terreno as texturas de terrain/*.jpg da instalação e compõe o sprite GAF de cada elemento, produzindo o mapa tal como o jogo o renderiza (athri cay → 7680 × 7680). A paleta dos sprites dos elementos é lida de palettes/<kingdom>_features.pcx.
  5. Renderizar o mapa de alturas — kbot tnt image <map.tnt> -t height.png não precisa de recursos externos; gera o mapa de alturas de DataUnits em tons de cinzento (--features sobrepõe marcas de colocação coloridas por categoria).
  6. Reempacotar um arquivo de campanha — por agora, kbot hpi pack só produz v1, por isso um .kmp reempacotado não carregaria. Para editar um .kmp à mão, extraia-o, altere os ficheiros soltos e use um empacotador de terceiros que suporte v2, até o kbot passar a escrever v2.

Warning

O TA: Kingdoms precisa de -disablecavedogverification para carregar a maior parte dos ficheiros modificados, incluindo mapas modificados. Sem isso, o motor rejeita tudo aquilo cujo hash não esteja na sua lista de permissões. Documente isto nas instruções de instalação de qualquer mod.


O que o kbot consegue e não consegue fazer hoje com mapas do TA:K

Operação Estado
Ler os cabeçalhos + a lista de ficheiros de um .kmp (HPI v2) ✅
Extrair ficheiros de um .kmp ✅
Analisar um .ota (formato TDF) ✅
Ler o cabeçalho de um .tnt do TA:K (kbot tnt describe) ✅
Exportar o minimapa de um .tnt do TA:K (kbot tnt minimap) ✅ (cor real — paleta do reino a partir do .ota)
Renderizar um mapa completo do TA:K com texturas (kbot tnt preview --vfs) ✅ (terreno com texturas + sprites GAF dos elementos)
Renderizar o mapa de alturas do TA:K (kbot tnt image) ✅ (tons de cinzento, autónomo; --features sobrepõe marcas)
Escrever um .tnt do TA:K (kbot tnt pack) ❌
Escrever um .kmp (empacotamento HPI v2) ❌

Os pull requests para qualquer um dos itens ❌ são bem-vindos. Com o mapa de alturas, a grelha de mapeamento de texturas, a grelha de elementos e a tabela de elementos todos descodificados, o terreno e os elementos são renderizados em resolução total; as lacunas que restam são a escrita, para fazer a ida e volta de mapas do TA:K editados, e o empacotamento de .kmp v2.


Ver também

  • HPI — o contentor de arquivo v2 (o .kmp é um HPI v2 com outra extensão).
  • TNT — o formato TNT do TA; o TA:K reutiliza a estrutura com um IDVersion 0x4000.
  • TDF — o formato com que o .ota é analisado.
  • GAF — os ficheiros de animação .taf usados em todo o TA:K (cinemáticas nos arquivos .kmp).
  • Interface do TA: Kingdoms — o formato de widgets dos menus e do HUD.
  • Glossário — lado, mapa de alturas.