Mappe di TA: Kingdoms — .tnt + .ota + .crt + .kmp
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
.btmné alcun BMP di accompagnamento.Il lettore HPI v2 già presente in kbot gestisce gli archivi
.kmpin 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.crtdi accompagnamento. Le missioni della campagna sono impacchettate in archivi.kmpche 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:
Width/Heightcontano DataUnit da 16 px, non pixel. Una mappa "15 × 15" comeathri caymemorizzaWidth = Height = 480DataUnit →480 × 16 = 7680px 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).- L'intestazione è composta da dodici
uint32consecutivi 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. - 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
.tnte il.otadella 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'opcodeMISSION_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.
Intestazione
| 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
uint32con il numero di condizioni, poi le condizioni, ciascuna fatta di un opcodeuint32e cinque slot di argomenti da 64 byte; - un
uint32con il numero di azioni, poi le azioni, ciascuna fatta di un opcodeuint32e 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:
- Esaminare liberamente:
kbot hpi list/info/extractsui file.kmpfunziona da subito..otae.txtsono testo semplice. - 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. - Disegnare una minimappa:
kbot tnt minimap <map.tnt> -t mini.pngesporta l'anteprima incorporata da 126 × 126 in truecolor, scegliendo in automatico la palette del regno dal.otache la affianca (si può sovrascrivere con--kingdom; vedi la nota sulla palette qui sopra). - Disegnare la mappa completa con le texture:
kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.pngapplica al terreno le textureterrain/*.jpgdell'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 dapalettes/<kingdom>_features.pcx. - Disegnare la mappa delle altezze:
kbot tnt image <map.tnt> -t height.pngnon ha bisogno di asset esterni; produce la mappa delle altezze per DataUnit in scala di grigi (--featuressovrappone indicatori dei posizionamenti colorati per categoria). - Reimpacchettare un archivio della campagna: oggi
kbot hpi packproduce solo v1, quindi un.kmpreimpacchettato non si caricherebbe. Finché kbot non saprà scrivere v2, modifica un.kmpa 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
.tafusati 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).