Tutte le pagine dei formati ↓
Mappe e terreno

Mappe di TA: Kingdoms — .tnt + .ota + .crt + .kmp

Fonte: coreprime/kbot @ 0ab97bf · Modifica su GitHub

Le mappe di TA: Kingdoms sono una variante del TNT (con una diversa parola IDVersion) accompagnata da uno o due file di metadati, più un formato di archivio HPI v2 per le missioni della campagna in giocatore singolo. È un modello molto più vicino a quello delle mappe di TA di quanto lasciassero intendere le vecchie note di ricerca su "BTM/heightmap-BMP": in una vera installazione GoG di TA:K non c'è alcun .btm né alcun BMP di accompagnamento.

Il lettore HPI v2 già presente in kbot gestisce gli archivi .kmp in modo trasparente. Il lettore TNT di kbot riconosce la parola di versione di TA:K e decodifica l'intestazione, la mappa delle altezze per DataUnit, la griglia di mappatura delle texture (nomi dei terreni + tabelle degli offset U/V), la griglia di posizionamento degli elementi con la tabella dei nomi e la minimappa incorporata: quanto basta per disegnare una mappa completa a piena risoluzione, componendo i JPG esterni del terreno e gli sprite GAF degli elementi. Questa pagina documenta ciò che si può verificare sull'installazione distribuita, più le lacune che restano.

Important

Aggiornamento sullo stato (rispetto alla versione originale "note di ricerca" di questa pagina). I tipi di file di cui questa pagina parlava un tempo (.btm, BMP di accompagnamento, PCX di palette per fazione) in realtà non ci sono nell'installazione GoG di TA: Kingdoms. I tipi di file reali sono documentati qui sotto. Per un confronto con un altro progetto open source su TA:K, vedi iiCompleteDestruction: per alcune strutture specifiche di TA:K il suo parser è più completo di quello di kbot.


I file che compongono una mappa di TA:K

Conteggio sulla directory delle mappe dell'installazione GoG:

Estensione Numero Scopo
.kmp 181 Archivio HPI v2 che raccoglie mappa, script e asset di una missione della campagna
.tnt 55 Dati del terreno della mappa (binario con la forma di un TNT e una parola IDVersion specifica di TA:K)
.ota 55 Metadati della mappa: formato TDF, stessa forma del .ota di TA, con campi specifici di TAK
.txt 55 Descrizione della mappa in testo libero (poche parole, mostrate nella lobby)
.crt 33 File di scenario di accompagnamento: unità pre-piazzate, motore di regole per giocatore, regioni di trigger con nome
.tdf 6 File di ritocchi al gameplay per singola mappa (bilanciamento della campagna, spinte all'IA)

Una tipica mappa multigiocatore viene distribuita come terna .tnt + .ota

  • .txt, a volte con un .crt di accompagnamento. Le missioni della campagna sono impacchettate in archivi .kmp che contengono lo stesso insieme di file insieme agli script della missione.

Tip

Elenca il contenuto di una mappa di TA:K senza estrarre nulla:

# 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 di TA:K (TNT v2)

TA:K riusa la struttura TNT di TA ma cambia la parola IDVersion. Dump esadecimale di 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.......

Il primo uint32 è 0x00004000, mentre il TNT di TA usa 0x00002000. Il contenitore resta un'intestazione seguita da sezioni indirizzate tramite puntatori, ma TA:K non è affatto un formato a mosaico di tile. Dove TA memorizza una griglia di indici di tile più una palette di grafiche di tile 32×32, TA:K memorizza il terreno come una griglia di mappatura delle texture che rimanda a texture JPG esterne, più una mappa delle altezze separata e una griglia di posizionamento degli elementi. Tutto quanto segue è verificato su tutte le 55 mappe distribuite:

  1. Width/Height contano DataUnit da 16 px, non pixel. Una mappa "15 × 15" come athri cay memorizza Width = Height = 480 DataUnit → 480 × 16 = 7680 px per lato. La mappa delle altezze e la griglia degli elementi sono campionate per DataUnit; il terreno è campionato su una griglia più grossolana di Graphic Unit da 32 px, esattamente la metà della griglia delle DataUnit su ciascun asse (guW = Width/2).
  2. L'intestazione è composta da dodici uint32 consecutivi di offset e conteggi; i nomi dei campi di TA non descrivono più il contenuto. La tabella qui sotto riporta il significato in TA:K.
  3. I puntatori alle sezioni sono assoluti, quindi ogni sezione si legge tramite il suo puntatore più una lunghezza calcolata.
Offset Campo TA:K Dimensione della sezione Note
0x00 Version — 0x4000 (TA scrive 0x2000)
0x04 Width — DataUnit; ×16 → pixel, ÷2 → Graphic Unit
0x08 Height — DataUnit
0x0C SeaLevel — soglia di altezza per l'acqua
0x10 HeightMapOffset Width × Height byte un byte di altezza per DataUnit
0x14 AttributesOffset Width × Height × 2 griglia degli elementi: indice uint16 per DataUnit (≥0xFF00 = nessuno)
0x18 FeatureNamesOffset Count × 132 tabella dei nomi degli elementi (indice di 4 byte + nome di 128 byte)
0x1C FeatureCount — numero di tipi di elementi
0x20 TerrainNamesOffset guW × guH × 4 nome della texture per GU → terrain/%08x.jpg
0x24 UMappingOffset guW × guH byte offset di colonna per GU nella sua texture (×32 px)
0x28 VMappingOffset guW × guH byte offset di riga per GU nella sua texture (×32 px)
0x2C MiniMapOffset 8 + 126×126 uint32 w, uint32 h, poi gli indici

La mappa delle altezze (0x10) ha un byte per DataUnit: è un campo di elevazione in scala di grigi, non una bitmap a colori. Il terreno si ricostruisce per mappatura delle texture: per ogni Graphic Unit, la tabella dei nomi dei terreni (0x20) indica un file di texture (terrain/<name>.jpg, con il nome scritto come esadecimale minuscolo a 8 cifre), e le tabelle U/V (0x24/0x28) indicano il sotto-tile 32×32 da copiare da quel JPG a (u×32, v×32). La griglia degli elementi (0x14) è il livello dei posizionamenti: un array Width × Height di uint16 in cui ogni cella contiene o un indice di elemento nella tabella dei nomi o un valore sentinella alto (≥0xFF00) che significa "nessun elemento qui"; la cella DataUnit (x, y) di un posizionamento corrisponde al pixel del terreno (x×16, y×16). La tabella dei nomi (0x18) usa la stessa struttura di voce da 132 byte della tabella TileAnim di TA.

Il blocco della minimappa è sempre 126 × 126 in tutti i file distribuiti e usa lo stesso byte vuoto 0x64 di TA come riempimento fuori dalle mappe non quadrate.

Note

Che cosa funziona oggi sui TNT di TA:K. kbot tnt describe riporta l'intestazione, il regno, le dimensioni di mappa delle altezze e terreno e la ripartizione degli elementi. kbot tnt preview --vfs <root> disegna il terreno texturizzato a piena risoluzione e vi compone sopra lo sprite GAF di ogni elemento, ancorato al suo hotspot: la mappa completa come la disegna il gioco. kbot tnt image disegna la mappa delle altezze in scala di grigi, autosufficiente (non servono texture esterne; --features sovrappone indicatori colorati per categoria). kbot tnt minimap esporta l'anteprima incorporata da 126 × 126.

Palette della minimappa — una per regno

TA:K non colora la minimappa con un'unica palette globale. Ogni mappa cuoce la sua anteprima 126 × 126 sulla palette delle texture del regno a cui appartiene: il campo kingdom= nel .ota che la affianca (aramon / taros / veruna / zhon / creon). Disegnare gli stessi indici con la palette del regno sbagliato (o con il PALETTE.PAL di TA) produce un rumore puntinato; con quella giusta si ottengono acqua, spiagge e terreno naturali.

kbot tnt minimap ricava automaticamente il regno dal .ota che affianca la mappa. Quando il .ota manca (ad es. un .tnt sciolto), passa esplicitamente --kingdom <name>:

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

.ota — Metadati della mappa (TDF, in gran parte familiare)

Il .ota di TA:K ha lo stesso formato in stile TDF di quello di TA, con diversi campi specifici di TAK. Il file completo 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 in TA Note
kingdom= nessuno Affinità di fazione (aramon / taros / veruna / zhon / creon). La lobby filtra in base a questo campo, che sceglie anche la palette del terreno e della minimappa con cui è colorata l'anteprima cotta nel .tnt.
size= nessuno Dimensione della mappa in forma leggibile, per la lobby.
memory= nessuno RAM consigliata. Puramente estetico.
hasscenario= nessuno 1 per le missioni della campagna, 0 per le mappe da schermaglia.
[Map Data] [Schema N] Riduce la sottosezione dello schema a un unico blocco (TA:K distribuisce sempre un solo schema per mappa).

Tutto il resto (StartPos1..N, aiprofile=, ecc.) funziona esattamente come in TA: il visualizzatore OTA di kbot mount gestisce entrambi senza modifiche.


.kmp — Archivi HPI v2 delle missioni della campagna

Un .kmp è un archivio HPI v2 rinominato. L'inizio in esadecimale di 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…

È esattamente la forma dell'intestazione v2 (marcatore HAPI → versione 0x00020000 → intestazione v2 da 24 byte → chunk SQSH). kbot hpi list, info ed extract funzionano tutti direttamente. Di solito ogni .kmp contiene:

  • Il .tnt e il .ota della missione
  • Una manciata di GAF per i filmati e i briefing
  • File COB degli script della missione: TA:K riusa il formato COB (VersionSignature == 6) per gli script delle missioni, invece di un linguaggio di scripting separato. Le 3.885 occorrenze dell'opcode MISSION_COMMAND (0x10073000) nell'installazione originale di TAK si trovano qui. Vedi TA: Kingdoms — differenze di COB v6 e l'Appendice C di cob.md per il formato binario e per il pool di stringhe dei nomi dei suoni, per ogni COB, a cui fanno riferimento i comandi delle missioni.
  • A volte, sostituzioni delle unità specifiche della missione

.crt — Script di scenario (unità, regole, trigger)

Un .crt contiene il livello di scripting di una mappa: le unità piazzate prima dell'inizio della partita, il motore di regole per giocatore che guida l'IA delle schermaglie e gli obiettivi della campagna, e le regioni di trigger rettangolari con nome a cui quelle regole fanno riferimento. Le mappe multigiocatore contengono uno stub vuoto (nessuna unità, nove slot di giocatore vuoti, nessun trigger, 56 byte); le mappe della campagna e quelle speciali popolano ogni sezione, fino a ~120 KB.

L'intero file è little-endian ed è un'immagine diretta delle strutture in memoria del motore, quindi i record delle unità includono diversi campi di riempimento non inizializzati.

Offset Tipo Campo Note
0x00 uint32 Signature 0x3F800000: marcatore IEEE-754 1.0f
0x04 uint32 Unknown1 0 in tutte le mappe distribuite tranne una
0x08 uint32 UnitCount numero di record di unità piazzate che seguono

abnar's terrace.crt (uno stub vuoto) inizia così:

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

1.0f, Unknown1 = 0, UnitCount = 0, poi il numero di giocatori, 9.

Record delle unità (568 byte ciascuno)

Offset Tipo Campo
+0 char[256] UnitType (terminato da NUL)
+256 char[256] UniqueName (di solito vuoto)
+512 uint32 X (mondo)
+516 uint32 Y (asse dell'altezza)
+520 uint32 Z (mondo)
+524 uint32 PlayerId (a partire da 0)
+528 uint32 HealthPercent (di solito 100)
+532 uint32 ArmorPercent (di solito 100)
+536 uint32 WeaponPercent (di solito 100)
+540 uint32 Angle (di solito 180)
+544 uint32 Veteran
+548 uint32 sconosciuto
+552 uint32 sconosciuto
+556 uint32 FootprintX
+560 uint32 FootprintZ
+564 uint32 sconosciuto

Giocatori, regole, condizioni, azioni

Dopo le unità, un uint32 con il numero di giocatori (sempre 9) precede altrettanti blocchi di giocatore. Ogni blocco di giocatore è un uint32 con il numero di regole, seguito da altrettante regole. Una regola è composta da:

  • un uint32 con il numero di condizioni, poi le condizioni, ciascuna fatta di un opcode uint32 e cinque slot di argomenti da 64 byte;
  • un uint32 con il numero di azioni, poi le azioni, ciascuna fatta di un opcode uint32 e cinque slot di argomenti da 64 byte.

Trigger

Un uint32 finale con il numero di trigger precede altrettanti record di trigger. Ognuno è un nome di 256 byte terminato da NUL, seguito da quattro limiti uint32 (Left, Top, Right, Bottom) espressi in celle della mappa. I nomi sono leggibili (The Hill, Player 1).

Strumenti

kbot crt describe <map.crt> stampa la ripartizione per tipo di unità, il numero di regole e le regioni di trigger; aggiungi --verbose per l'elenco completo dei posizionamenti. Lo strumento MCP crt_describe restituisce gli stessi dati in JSON.

Un file, cairbray coast landing.crt, ha un'intestazione spostata e modificata a mano che non corrisponde a questa struttura; il parser lo rifiuta con un errore chiaro invece di decodificarlo male.


.txt — Descrizione in testo libero

Una stringa ASCII di una riga, usata nella lobby. Per esempio abnar's terrace.txt: 9 x 7 4 Player 32MB (la stessa stringa contenuta nel missiondescription del .ota). Probabilmente gli strumenti di creazione scrivevano entrambi durante l'esportazione; il gioco sembra mostrare il valore del .ota.


Lavorare oggi con le mappe di TA:K

Le opzioni pratiche, in ordine crescente di impegno:

  1. Esaminare liberamente: kbot hpi list/info/extract sui file .kmp funziona da subito. .ota e .txt sono testo semplice.
  2. Descrivere una mappa: kbot tnt describe <map.tnt> riporta l'intestazione TA:K, il regno, le dimensioni di mappa delle altezze e terreno e la ripartizione degli elementi.
  3. Disegnare una minimappa: kbot tnt minimap <map.tnt> -t mini.png esporta l'anteprima incorporata da 126 × 126 in truecolor, scegliendo in automatico la palette del regno dal .ota che la affianca (si può sovrascrivere con --kingdom; vedi la nota sulla palette qui sopra).
  4. Disegnare la mappa completa con le texture: kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.png applica al terreno le texture terrain/*.jpg dell'installazione e compone lo sprite GAF di ogni elemento, producendo la mappa come la disegna il gioco (athri cay → 7680 × 7680). La palette degli sprite degli elementi viene letta da palettes/<kingdom>_features.pcx.
  5. Disegnare la mappa delle altezze: kbot tnt image <map.tnt> -t height.png non ha bisogno di asset esterni; produce la mappa delle altezze per DataUnit in scala di grigi (--features sovrappone indicatori dei posizionamenti colorati per categoria).
  6. Reimpacchettare un archivio della campagna: oggi kbot hpi pack produce solo v1, quindi un .kmp reimpacchettato non si caricherebbe. Finché kbot non saprà scrivere v2, modifica un .kmp a mano estraendolo, cambiando i file sciolti e usando un programma di impacchettamento di terze parti che conosca la v2.

Warning

TA: Kingdoms richiede -disablecavedogverification per caricare la maggior parte dei file modificati, mappe comprese. Senza questa opzione il motore rifiuta qualsiasi file il cui hash non compaia nel suo elenco di quelli ammessi. Riportalo nelle istruzioni di installazione di qualsiasi mod.


Che cosa kbot sa e non sa fare oggi con le mappe di TA:K

Operazione Stato
Leggere intestazioni + elenco dei file di un .kmp (HPI v2) ✅
Estrarre file da un .kmp ✅
Analizzare un .ota (formato TDF) ✅
Leggere l'intestazione di un .tnt di TA:K (kbot tnt describe) ✅
Esportare la minimappa di un .tnt di TA:K (kbot tnt minimap) ✅ (truecolor: palette del regno presa dal .ota)
Disegnare una mappa di TA:K completa con le texture (kbot tnt preview --vfs) ✅ (terreno texturizzato + sprite GAF degli elementi)
Disegnare la mappa delle altezze di TA:K (kbot tnt image) ✅ (autosufficiente, in scala di grigi; --features sovrappone gli indicatori)
Scrivere un .tnt di TA:K (kbot tnt pack) ❌
Scrivere un .kmp (impacchettamento HPI v2) ❌

Le pull request su qualsiasi voce ❌ sono benvenute. Con la mappa delle altezze, la griglia di mappatura delle texture, la griglia degli elementi e la tabella degli elementi tutte decodificate, terreno ed elementi vengono disegnati a piena risoluzione; le lacune che restano sono il percorso di scrittura, per il round-trip delle mappe di TA:K modificate, e l'impacchettamento dei .kmp v2.


Vedi anche

  • HPI: il contenitore di archivio v2 (un .kmp è un HPI v2 con l'estensione cambiata).
  • TNT: il formato TNT di TA; TA:K ne riusa la struttura con un IDVersion 0x4000.
  • TDF: il formato secondo cui viene analizzato il .ota.
  • GAF: i file di animazione .taf usati ovunque in TA:K (i filmati negli archivi .kmp).
  • Interfaccia di TA: Kingdoms: il formato dei widget di menu e HUD.
  • Glossario: fazione (side), mappa delle altezze (heightmap).