Karten von TA: Kingdoms – .tnt + .ota + .crt + .kmp
Karten von TA: Kingdoms sind eine TNT-Variante (mit anderem IDVersion-Wort), umgeben von einer oder zwei Metadatendateien, dazu kommt ein Format für Kampagnenarchive auf Basis von HPI v2 für die Einzelspielermissionen. Das liegt deutlich näher am Kartenmodell von TA, als die älteren Forschungsnotizen zu „BTM/Höhenkarten-BMP“ vermuten ließen – in einer echten GoG-Installation von TA:K gibt es überhaupt keine
.btm-Dateien oder BMP-Begleitdateien.Der vorhandene HPI-v2-Leser von kbot verarbeitet
.kmp-Archive ohne Weiteres. Der TNT-Leser von kbot erkennt das Versionswort von TA:K und dekodiert den Header, die Höhenkarte der DataUnits, das Texture-Mapping-Raster (Tabellen mit Geländenamen und U/V-Offsets), das Platzierungsraster der Kartenobjekte samt Namenstabelle und die eingebettete Minikarte – genug, um eine vollständige Karte in voller Auflösung zu rendern, indem die externen Gelände-JPGs und die GAF-Sprites der Kartenobjekte zusammengesetzt werden. Diese Seite dokumentiert, was sich an der ausgelieferten Installation überprüfen lässt, und die verbleibenden Lücken.
Important
Neuer Stand (gegenüber der ursprünglichen Fassung dieser Seite als
„Forschungsnotizen“). Die Dateitypen, um die es hier früher ging –
.btm, BMP-Begleitdateien, PCX-Paletten pro Seite – gibt es in der
ausgelieferten GoG-Installation von TA: Kingdoms tatsächlich nicht. Die
echten Dateitypen sind unten dokumentiert. Zum Vergleich mit einem anderen
Open-Source-Projekt zu TA:K siehe
iiCompleteDestruction;
dessen Parser ist bei einigen TA:K-spezifischen Strukturen vollständiger
als der von kbot.
Dateien, aus denen eine TA:K-Karte besteht
Gezählt im Kartenverzeichnis der GoG-Installation:
| Endung | Anzahl | Zweck |
|---|---|---|
.kmp |
181 | HPI-v2-Archiv, das Karte, Skripte und Assets einer Kampagnenmission bündelt |
.tnt |
55 | Geländedaten der Karte (TNT-artige Binärdatei mit einem TA:K-spezifischen IDVersion-Wort) |
.ota |
55 | Karten-Metadaten – TDF-Format, gleich aufgebaut wie die .ota von TA, mit TAK-spezifischen Feldern |
.txt |
55 | Freitext-Beschreibung der Karte (ein paar Wörter; wird in der Lobby angezeigt) |
.crt |
33 | Szenario-Begleitdatei: vorab platzierte Einheiten, Regel-Engine pro Spieler, benannte Auslöserbereiche |
.tdf |
6 | Anpassungsdateien für das Gameplay einzelner Karten (Feinabstimmung der Kampagne, Anstöße für die KI) |
Eine typische Mehrspielerkarte wird als Dreiergespann aus .tnt + .ota +
.txt ausgeliefert, manchmal mit einer .crt-Begleitdatei.
Kampagnenmissionen sind in .kmp-Archive gepackt, die denselben Satz mit
Missionsskripten bündeln.
Tip
Ein TA:K-Kartenpaket auflisten, ohne etwas zu entpacken:
# 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 – Gelände von TA:K (TNT v2)
TA:K verwendet die TNT-Struktur von TA wieder, erhöht aber das
IDVersion-Wort. Hex-Dump von 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.......
Das erste uint32 ist 0x00004000 – zum Vergleich: Das TNT von TA
verwendet 0x00002000. Der Container ist nach wie vor ein Header, gefolgt
von Abschnitten, die über Zeiger adressiert werden, aber TA:K ist überhaupt
kein Kachelmosaik-Format. Wo TA ein Raster aus Kachelindizes plus einen
Vorrat an Kachelgrafiken zu 32×32 speichert, speichert TA:K das Gelände als
Texture-Mapping-Raster, das auf externe JPG-Texturen verweist, dazu eine
separate Höhenkarte und ein Platzierungsraster der Kartenobjekte.
Alles Folgende ist an allen 55 ausgelieferten Karten überprüft:
Width/Heightzählen DataUnits zu 16 px, keine Pixel. Eine „15 × 15“-Karte wieathri cayspeichertWidth = Height = 480DataUnits →480 × 16 = 7680px pro Seite. Höhenkarte und Objektraster werden pro DataUnit abgetastet; das Gelände wird auf einem gröberen Raster aus Graphic Units zu 32 px abgetastet, das auf jeder Achse genau halb so fein ist wie das DataUnit-Raster (guW = Width/2).- Der Header besteht aus zwölf aufeinanderfolgenden
uint32mit Offsets und Anzahlen; die Feldnamen von TA beschreiben den Inhalt nicht mehr. Die Tabelle unten gibt die Bedeutung in TA:K an. - Abschnittszeiger sind absolut, jeder Abschnitt wird also über seinen eigenen Zeiger und eine berechnete Länge gelesen.
| Offset | TA:K-Feld | Abschnittsgröße | Anmerkungen |
|---|---|---|---|
0x00 |
Version |
– | 0x4000 (TA schreibt 0x2000) |
0x04 |
Width |
– | DataUnits; ×16 → Pixel, ÷2 → Graphic Units |
0x08 |
Height |
– | DataUnits |
0x0C |
SeaLevel |
– | Höhenschwelle für Wasser |
0x10 |
HeightMapOffset |
Width × Height Byte |
ein Höhenbyte pro DataUnit |
0x14 |
AttributesOffset |
Width × Height × 2 |
Objektraster: uint16-Index pro DataUnit (≥0xFF00 = keines) |
0x18 |
FeatureNamesOffset |
Count × 132 |
Namenstabelle der Kartenobjekte (4-Byte-Index + 128-Byte-Name) |
0x1C |
FeatureCount |
– | Anzahl der Objekttypen |
0x20 |
TerrainNamesOffset |
guW × guH × 4 |
Texturname pro GU → terrain/%08x.jpg |
0x24 |
UMappingOffset |
guW × guH Byte |
Spalten-Offset pro GU in seine Textur (×32 px) |
0x28 |
VMappingOffset |
guW × guH Byte |
Zeilen-Offset pro GU in seine Textur (×32 px) |
0x2C |
MiniMapOffset |
8 + 126×126 |
uint32 w, uint32 h, dann Indizes |
Die Höhenkarte (0x10) hat ein Byte pro DataUnit – ein Höhenfeld in
Graustufen, keine Farb-Bitmap. Das Gelände wird per Texture-Mapping
rekonstruiert: Für jede Graphic Unit liefert die Tabelle der Geländenamen
(0x20) eine Texturdatei (terrain/<name>.jpg, der Name als achtstellige
Hexzahl in Kleinbuchstaben formatiert), und die U/V-Tabellen
(0x24/0x28) geben die Teilkachel zu 32×32 an, die bei (u×32, v×32)
aus diesem JPG kopiert wird. Das Objektraster (0x14) ist die
Platzierungsebene: ein Array aus uint16 der Größe Width × Height, in dem
jede Zelle entweder einen Objektindex in die Namenstabelle enthält oder
einen hohen Sentinel-Wert (≥0xFF00), der „hier kein Objekt“ bedeutet; die
DataUnit-Zelle (x, y) einer Platzierung entspricht dem Geländepixel
(x×16, y×16). Die Namenstabelle (0x18) verwendet denselben Aufbau
mit Einträgen zu 132 Byte wie die TileAnim-Tabelle von TA.
Der Minikarten-Block ist im gesamten ausgelieferten Bestand immer
126 × 126 groß und verwendet zum Auffüllen außerhalb nicht quadratischer
Karten dasselbe Leer-Byte 0x64 wie TA.
Note
Was heute mit TNTs von TA:K funktioniert. kbot tnt describe gibt
Header, Königreich, Maße von Höhenkarte und Gelände sowie die Aufteilung
der Kartenobjekte aus. kbot tnt preview --vfs <root> rendert das
texturierte Gelände in voller Auflösung und legt das GAF-Sprite jedes
Kartenobjekts darüber, verankert an seinem Hotspot – die vollständige
Karte, wie das Spiel sie zeichnet. kbot tnt image rendert die
eigenständige Höhenkarte in Graustufen (ohne externe Texturen;
--features legt nach Kategorie eingefärbte Markierungen darüber).
kbot tnt minimap exportiert die eingebettete Vorschau in 126 × 126.
Minikarten-Palette – eine pro Königreich
TA:K färbt seine Minikarte nicht mit einer einzigen globalen Palette.
Jede Karte backt ihre Vorschau in 126 × 126 mit der Texturpalette des
Königreichs, zu dem sie gehört – dem Feld kingdom= in der
danebenliegenden .ota (aramon / taros / veruna / zhon /
creon). Dieselben Indizes mit der Palette des falschen Königreichs (oder
mit der PALETTE.PAL von TA) zu rendern, ergibt gesprenkeltes Rauschen;
mit der richtigen erhält man natürliches Wasser, Strände und Gelände.
kbot tnt minimap ermittelt das Königreich automatisch aus der
danebenliegenden .ota. Fehlt die .ota (z. B. bei einer losen .tnt),
gib --kingdom <name> ausdrücklich an:
kbot tnt minimap "athri cay.tnt" -t mini.png # auto: veruna
kbot tnt minimap loose.tnt --kingdom aramon -t mini.png
.ota – Karten-Metadaten (TDF, größtenteils vertraut)
Die .ota von TA:K hat dasselbe TDF-artige Format wie die von TA, mit
einigen TAK-spezifischen Feldern. Die vollständige Datei aus
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; }
…
}
}
}
| Feld | Entsprechung in TA | Anmerkungen |
|---|---|---|
kingdom= |
keine | Zugehörigkeit zu einer Seite (aramon / taros / veruna / zhon / creon). Die Lobby filtert danach; wählt außerdem die Gelände-/Minikarten-Palette, mit der die eingebackene Vorschau der .tnt eingefärbt ist. |
size= |
keine | Kartengröße in lesbarer Form für die Lobby. |
memory= |
keine | Empfohlener Arbeitsspeicher. Rein kosmetisch. |
hasscenario= |
keine | 1 für Kampagnenmissionen, 0 für Skirmish-Karten. |
[Map Data] |
[Schema N] |
Entspricht dem Schema-Unterabschnitt, zu einem einzigen Block zusammengefasst (TA:K liefert pro Karte immer nur ein Schema aus). |
Alles andere (StartPos1..N, aiprofile= usw.) funktioniert genau wie in
TA – der OTA-Betrachter von kbot mount kommt mit beidem ohne Änderung
zurecht.
.kmp – HPI-v2-Archive für Kampagnenmissionen
.kmp ist ein umbenanntes HPI-v2-Archiv. Der
Anfang von adamantine gate.kmp als Hex:
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…
Genau der Aufbau des v2-Headers (HAPI-Marker → Version 0x00020000 →
24-Byte-v2-Header → SQSH-Chunks). kbot hpi list, info und extract
funktionieren alle direkt. Eine .kmp enthält typischerweise:
.tntund.otader Mission- Eine Handvoll GAFs für Zwischensequenzen und Briefings
- COB-Dateien mit Missionsskripten – TA:K verwendet das COB-Format
(
VersionSignature == 6) für Missionsskripte wieder, statt einer eigenen Skriptsprache. Die 3.885 Fundstellen des OpcodesMISSION_COMMAND(0x10073000) in der Verkaufsversion von TAK liegen hier. Das Datenformat und den String-Pool mit Soundnamen pro COB, in den Missionsbefehle indizieren, beschreiben TA: Kingdoms – Unterschiede von COB v6 und Anhang C in cob.md. - Manchmal Überschreibungen von Einheiten pro Mission
.crt – Szenarioskript (Einheiten, Regeln, Auslöser)
Eine .crt enthält die geskriptete Ebene einer Karte: die Einheiten, die
vor Spielbeginn platziert werden, die Regel-Engine pro Spieler, die die
Skirmish-KI und die Kampagnenziele steuert, und die benannten rechteckigen
Auslöserbereiche, auf die sich diese Regeln beziehen. Mehrspielerkarten
liefern einen leeren Stub aus (keine Einheiten, neun leere
Spielerplätze, keine Auslöser, 56 Byte); Kampagnen- und Sonderkarten füllen
jeden Abschnitt, bis zu ~120 KB.
Die ganze Datei ist Little-Endian und ein direktes Abbild der Speicherstrukturen der Engine, daher enthalten die Einheiten-Datensätze mehrere nicht initialisierte Füllfelder.
Header
| Offset | Typ | Feld | Anmerkungen |
|---|---|---|---|
0x00 |
uint32 |
Signature | 0x3F800000 – Marker 1.0f nach IEEE 754 |
0x04 |
uint32 |
Unknown1 | 0 auf jeder ausgelieferten Karte bis auf eine |
0x08 |
uint32 |
UnitCount | Anzahl der folgenden Datensätze platzierter Einheiten |
abnar's terrace.crt (ein leerer Stub) beginnt so:
00000000: 00 00 80 3f 00 00 00 00 00 00 00 00 09 00 00 00
1.0f, Unknown1 = 0, UnitCount = 0, dann die Spieleranzahl 9.
Einheiten-Datensätze (je 568 Byte)
| Offset | Typ | Feld |
|---|---|---|
+0 |
char[256] |
UnitType (NUL-terminiert) |
+256 |
char[256] |
UniqueName (meist leer) |
+512 |
uint32 |
X (Welt) |
+516 |
uint32 |
Y (Höhenachse) |
+520 |
uint32 |
Z (Welt) |
+524 |
uint32 |
PlayerId (ab 0) |
+528 |
uint32 |
HealthPercent (meist 100) |
+532 |
uint32 |
ArmorPercent (meist 100) |
+536 |
uint32 |
WeaponPercent (meist 100) |
+540 |
uint32 |
Angle (meist 180) |
+544 |
uint32 |
Veteran |
+548 |
uint32 |
unbekannt |
+552 |
uint32 |
unbekannt |
+556 |
uint32 |
FootprintX |
+560 |
uint32 |
FootprintZ |
+564 |
uint32 |
unbekannt |
Spieler, Regeln, Bedingungen, Aktionen
Nach den Einheiten steht eine uint32-Spieleranzahl (immer 9), gefolgt
von entsprechend vielen Spielerblöcken. Jeder Spielerblock ist eine
uint32-Regelanzahl, gefolgt von entsprechend vielen Regeln. Eine Regel
besteht aus:
- einer
uint32-Anzahl der Bedingungen, dann ist jede Bedingung einuint32-Opcode und fünf Argumentplätze zu 64 Byte; - einer
uint32-Anzahl der Aktionen, dann ist jede Aktion einuint32-Opcode und fünf Argumentplätze zu 64 Byte.
Auslöser
Am Ende steht eine uint32-Anzahl der Auslöser, gefolgt von entsprechend
vielen Auslöser-Datensätzen. Jeder besteht aus einem NUL-terminierten Namen
zu 256 Byte, gefolgt von vier uint32-Grenzen – Left, Top, Right,
Bottom – in Kartenzellen. Die Namen sind für Menschen lesbar (The Hill,
Player 1).
Werkzeuge
kbot crt describe <map.crt> gibt die Aufteilung nach Einheitentypen, die
Regelanzahlen und die Auslöserbereiche aus; mit --verbose kommt die
vollständige Liste der Platzierungen dazu. Das MCP-Werkzeug crt_describe
liefert dieselben Daten als JSON.
Eine Datei – cairbray coast landing.crt – hat einen verschobenen, von Hand
bearbeiteten Header, der nicht zu diesem Aufbau passt; der Parser lehnt sie
mit einer klaren Fehlermeldung ab, statt sie falsch zu dekodieren.
.txt – Freitext-Beschreibung
Ein einzeiliger ASCII-String, der in der Lobby verwendet wird, z. B.
abnar's terrace.txt: 9 x 7 4 Player 32MB (derselbe String, den
missiondescription der .ota enthält). Die Autorenwerkzeuge haben
vermutlich beides beim Export geschrieben; das Spiel scheint den Wert aus
der .ota anzuzeigen.
Heute mit TA:K-Karten arbeiten
Praktische Möglichkeiten, nach steigendem Aufwand geordnet:
- Frei untersuchen –
kbot hpi list/info/extractauf.kmp-Dateien funktioniert auf Anhieb..otaund.txtsind reiner Text. - Eine Karte beschreiben –
kbot tnt describe <map.tnt>gibt den TA:K-Header, das Königreich, die Maße von Höhenkarte und Gelände und eine Aufteilung der Kartenobjekte aus. - Eine Minikarte rendern –
kbot tnt minimap <map.tnt> -t mini.pngexportiert die eingebettete Vorschau in 126 × 126 in Truecolor und wählt die Palette des Königreichs automatisch aus der danebenliegenden.ota(überschreiben mit--kingdom; siehe den Hinweis zur Palette oben). - Die vollständige texturierte Karte rendern –
kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.pngtexturiert das Gelände aus denterrain/*.jpgder Installation und setzt das GAF-Sprite jedes Kartenobjekts darauf; das Ergebnis ist die Karte, wie das Spiel sie rendert (athri cay → 7.680 × 7.680). Die Palette der Objekt-Sprites wird auspalettes/<kingdom>_features.pcxgelesen. - Die Höhenkarte rendern –
kbot tnt image <map.tnt> -t height.pngbraucht keine externen Assets; es gibt die Höhenkarte der DataUnits in Graustufen aus (--featureslegt nach Kategorie eingefärbte Platzierungsmarkierungen darüber). - Ein Kampagnenarchiv neu packen –
kbot hpi packerzeugt derzeit nur v1, eine neu gepackte.kmpwürde also nicht laden. Bearbeite eine.kmpvon Hand, indem du sie entpackst, die losen Dateien änderst und einen v2-fähigen Packer eines Drittanbieters verwendest, bis kbot v2 schreiben kann.
Warning
TA: Kingdoms braucht -disablecavedogverification, um die meisten
veränderten Dateien zu laden, auch veränderte Karten. Ohne den Schalter
weist die Engine alles ab, dessen Hash nicht auf ihrer Allowlist steht.
Schreib das in die Installationsanleitung jedes Mods.
Was kbot derzeit für TA:K-Karten kann und was nicht
| Vorgang | Stand |
|---|---|
Header + Dateiliste von .kmp (HPI v2) lesen |
✅ |
Dateien aus .kmp entpacken |
✅ |
.ota parsen (TDF-Format) |
✅ |
Header einer TA:K-.tnt lesen (kbot tnt describe) |
✅ |
Minikarte einer TA:K-.tnt exportieren (kbot tnt minimap) |
✅ (Truecolor – Palette pro Königreich aus der .ota) |
Vollständige texturierte TA:K-Karte rendern (kbot tnt preview --vfs) |
✅ (texturiertes Gelände + GAF-Sprites der Kartenobjekte) |
Höhenkarte von TA:K rendern (kbot tnt image) |
✅ (eigenständig in Graustufen; --features legt Markierungen darüber) |
Eine TA:K-.tnt schreiben (kbot tnt pack) |
❌ |
.kmp schreiben (HPI v2 packen) |
❌ |
Pull Requests zu allen ❌-Punkten sind willkommen. Da Höhenkarte,
Texture-Mapping-Raster, Objektraster und Objekttabelle vollständig
dekodiert sind, werden Gelände und Kartenobjekte in voller Auflösung
gerendert; es fehlen noch der Schreibpfad für den Round-Trip bearbeiteter
TA:K-Karten und das Packen von .kmp in v2.
Siehe auch
- HPI – der v2-Archivcontainer (
.kmpist ein HPI v2 mit umbenannter Endung). - TNT – das TNT-Format von TA; TA:K verwendet die Struktur mit IDVersion
0x4000wieder. - TDF – das Format, als das
.otageparst wird. - GAF –
.taf-Animationsdateien, die in TA:K überall vorkommen (Zwischensequenzen in.kmp-Archiven). - Oberfläche von TA: Kingdoms – das Widget-Format für Menüs und HUD.
- Glossar – side, heightmap.