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
.btmnem BMP auxiliares.O leitor de HPI v2 que o kbot já tem trata os arquivos
.kmpde 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:
Width/Heightsão contagens de DataUnits de 16 px, não de píxeis. Um mapa de "15 × 15" comoathri cayguardaWidth = Height = 480DataUnits →480 × 16 = 7680px 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).- O cabeçalho são doze
uint32seguidos 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. - 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
.tnte o.otada 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 opcodeMISSION_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.
Cabeçalho
| 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
uint32com o número de condições; cada condição é um opcodeuint32e cinco posições de argumento de 64 bytes; - um
uint32com o número de ações; cada ação é um opcodeuint32e 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:
- Inspecionar à vontade —
kbot hpi list/info/extractfunciona diretamente com ficheiros.kmp. O.otae o.txtsão texto simples. - 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. - Renderizar um minimapa —
kbot tnt minimap <map.tnt> -t mini.pngexporta a pré-visualização incorporada de 126 × 126 em cor real e escolhe automaticamente a paleta do reino a partir do.otaassociado (substitua-a com--kingdom; veja a nota sobre a paleta acima). - Renderizar o mapa completo com texturas —
kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.pngaplica ao terreno as texturas deterrain/*.jpgda 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 depalettes/<kingdom>_features.pcx. - Renderizar o mapa de alturas —
kbot tnt image <map.tnt> -t height.pngnão precisa de recursos externos; gera o mapa de alturas de DataUnits em tons de cinzento (--featuressobrepõe marcas de colocação coloridas por categoria). - Reempacotar um arquivo de campanha — por agora,
kbot hpi packsó produz v1, por isso um.kmpreempacotado 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
.tafusados 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.