The terrain file, drawn to scale
A TNT is not one bitmap. It is a compact terrain database: a tile-index grid, a 16-pixel attribute grid, an embedded tile atlas, optional feature records, and a 252×252 minimap — all connected by absolute file pointers.
1. File anatomy
2. Header — 0x40 bytes
| Offset | Size | Field | Meaning |
|---|---|---|---|
0x00 | uint32 | idVersion | Always 0x2000 in valid classic TNT files. |
0x04 | uint32 | width | Attribute cells across the map. Graphic tile width is width / 2. |
0x08 | uint32 | height | Attribute cells down the map. Graphic tile height is height / 2. |
0x0C | uint32 | ptrMapData | Absolute offset to the uint16 tile-index array. |
0x10 | uint32 | ptrMapAttr | Absolute offset to 4-byte attributes; one per 16×16 attribute cell. |
0x14 | uint32 | ptrTileGfx | Absolute offset to the embedded 32×32 tile atlas. |
0x18 | uint32 | tiles | Number of unique tile bitmaps. |
0x1C | uint32 | tileAnims | Number of feature/animation records. |
0x20 | uint32 | ptrTileAnims | Feature-record/string-table location; historically named “pointer to animations”. |
0x24 | uint32 | seaLevel | Any attribute height below this is underwater. |
0x28 | uint32 | ptrMiniMap | Absolute offset to minimap dimensions and pixels. |
0x2C | uint32 | unknown1 | Write 1. Real maps and TAUtil identify this as required for the minimap/game path. |
0x30–0x3F | 4×uint32 | reserved | Usually zero; do not invent semantics. |
3. Two grids, one map
W×H has (W/2)×(H/2) tile positions.4. Attribute cell — exactly 4 bytes
uint8. TA terrain elevation at this 16×16 location. Values are game heights, not automatically “meters”.uint16 little-endian. 0xFFFF = none; 0xFFFC = void; 0xFFFE occurs in some early Cavedog maps with unknown meaning.// Read one attribute, little-endian
height = read_u8();
feature = read_u16_le();
padding = read_u8();
// Attribute at (x, y), row-major
file_offset = ptrMapAttr + ((y * width) + x) * 4;5. Tile map and tile graphics
tileWidth = width / 2;
tileHeight = height / 2;
tileCountInMap = tileWidth * tileHeight;
// The file may pad this array to a multiple of 8 uint16 entries.
tileIndex = read_u16_le(ptrMapData + ((ty * tileWidth) + tx) * 2);
tilePixels = file[ptrTileGfx + tileIndex * 1024 : +1024];
// 1024 bytes = 32 × 32 palette indices, row-major.PALETTE.PAL; displaying the byte as grayscale can be misleading.6. Feature records and minimap
ptrMiniMap: uint32 width, uint32 height, then width×height bytes. Classic maps normally use 252×252.Known feature strings
The feature index in attribute bytes 1–2 points into this table. These are the strings currently confirmed in our local TNT corpus; this is a verified list, not a claim that the original TA feature vocabulary ends here.
RockMetalMetal extractor / metal deposit used by the image-map importer.GeothermalGeothermal vent used by the image-map importer.Tree1Tree feature used by the image-map importer.RockRock feature used by the image-map importer.MetalVent05Observed in an original-style local TNT map; feature naming is map/feature-set dependent.0 means the first record in that TNT's own feature table, not a universal TA feature ID. Read the table, resolve the string, then interpret the corresponding game feature definition.The Kingdom Of TA II — complete feature table
This original map contains 579 feature records. The list below is copied from the TNT feature table in index order; spelling and case are preserved. The map header is 1120 × 960 attribute cells, 49266 tiles, sea level 95.
Show all 579 feature strings
000 MetalZone_MAX001 GreenVent01002 GreenVent03003 DryVent04004 DryVent02005 EGVent4006 EGVent2007 EGVent1008 EGVent3009 WetVent06010 AquaOre3011 WaterMetal03012 AquaOre2013 EverGnMetal1014 EverGnMetal2015 RockMetal1016 RockMetal017 RockMetal2018 DryMetal01019 DryMetal03020 DryMetal02021 RockMetal3022 EverGnMetal3023 EverGnMetal4024 ArchMetal1025 ArchMetal3026 ArchMetal2027 WetMetal01028 MAMetal1029 MMedium01030 WetMetal03031 WetMetal02032 EverGnMetal6033 EverGnMetal5034 LushVent01035 LushVent03036 GreenVent08037 WetVent02038 WetVent03039 GreenVent06040 GreenVent04041 WetVent05042 WetVent01043 WetVent04044 SlateMetal4045 DryRuin01046 DryRuin03047 DryRuin05048 DryRuin06049 DryRuin02050 DryRuin07051 AraHut01052 AraHut03053 AraHut07054 AraHut08055 AraHut09056 AraHut05057 AraHut11058 AraHut10059 AraHut12060 Alien2061 Arrow2left062 Biohazard1063 Circlearrows064 Construction1065 Pod1066 Satellite067 Csymbol068 Airpad2069 Road2070 Road1arrow2071 Bluefingers_SM072 ButterWasp_SM073 NeckTrap_SM074 MorningHorn_SM075 AraTree01076 AraTree02077 AraTree03078 AraTree04079 AraTree04a080 AraTree06081 AraTree05082 AraTree03a083 AraTree01a084 DryRock10085 DryRock11086 DryRock09087 DryCrush34088 DryCrush44089 DryRock14090 DryRock04091 DryRock03092 DryRock01093 DryRock12094 DryRock15095 DryCrush43096 DryRock05097 DryRock02098 DryRock08099 DryRock07100 DryRock06101 AraTree02a102 ZonWall07103 HollyCock_SM104 SeaLeaf_SM105 Aracrop01106 Aracrop04107 Aracrop02108 Lush09109 Lush08110 tubertreesmudge2111 Lush07crisp112 lushfoliage06113 Lush07114 Rock4115 ArchiTree01116 ArchiTree04117 DryCrush33118 ArchiVent02119 AcidAquaOre1120 AcidAquaOre2121 AcidAquaOre3122 WaterMetal02123 WaterMetal01124 AquaOre1125 AraTree07126 AraTree09127 AraTree07a128 PGVent01129 GreenVent09130 GreenVent02131 GreenVent05132 eiffel133 VerWall08134 VerWall03135 VerTow01136 VerWall01137 VerJoint12138 VerJoint09139 VerJoint10140 VerJoint08141 VerWall04142 VerJoint06143 VerJoint11144 VerWall05145 VerWall02146 VerJoint05147 VerJoint07148 VerWall09149 VerWall12150 VerTow04151 VerBuild05152 VerTow02153 VerTow03154 VerJoint03155 VerJoint01156 VerWall06157 VerJoint04158 VerJoint02159 VerBuild04160 VerBuild06161 VerBuild08162 VerBuild03163 VerBuild02164 VerBuild01165 VerBuild07166 VerHut02167 VerHut07168 VerHut06169 VerHut01170 VerHut03171 VerHut04172 VerHut05173 VerHut09174 VerHut08175 VerHut10176 ZonTree09a177 ZonTree07a178 ZonTree08a179 ZonTreeDead07a180 ZonTree06181 FTree2182 TTree3183 Lush05184 ZonTreeDead08a185 ZonTreeDead09a186 VerFountain01187 TarDev04188 TarDev05189 VerAlt01190 YellowHuskies_SM191 SilkyWeb_SM192 Mystique_SM193 Heartless_SM194 VelvetLuster_SM195 VerPlant04196 ZonPlant06197 blossom1198 blossom2199 MarsPlant02Crisp200 MarsPlant02201 MarsPlant07202 MarsPlant05203 MarsPlant01Crisp204 VerPlant02205 VerPlant01206 VerPlant03207 VerPlant06208 VerPlant05209 VerPlantScar01210 LavaCrush02211 LavaRockA008212 LavaRockA006213 LavaRockA012214 LavaRockB017215 LavaRockC003216 LavaRockC008217 LavaRockC012218 LavaRockC012Scar219 LavaCrush03220 brock4221 Brock2222 Rock6223 Rock5224 Rock2225 Rock3226 Rock227 Rock1a228 Rock3a229 Rock4a230 Rock3b231 Rock2b232 Rock05233 Rock07234 Rock1b235 Rockgone02236 Rock11237 Rock11a238 Rock12239 Rock07b240 Rock08241 Rock06b242 Rock09243 Rock06a244 Rock10245 Rock05a246 MoonRock11247 MoonRock13248 MoonRock10249 MoonRock12250 MoonRock15251 MoonRock17252 MoonRock18253 MoonCrush18254 MoonCrushB255 MoonRock14256 MoonRock09257 MoonRock08258 MoonRock07259 MoonRock06260 MoonRock03261 MoonRock02262 MoonRock04263 MoonRock09Scar264 MoonCrush10265 ArchiTree02266 ArchiTree05267 Palm02268 Palm04269 HangingPearls_SM270 ZonTree01271 ZonTree03272 ZonTree04273 ZonTreeDead04274 ZonTreeDead06275 ZonTreeDead05276 ZonTree05277 ZonPlant04278 ZonPlant02279 ZonPlant03280 ZonPlant01281 ZonPlant05282 ZonPlant07283 ZonPlant08284 ZonPlant09285 ZonPlant10286 ZonPlant11287 ZonPlant14288 ZonPlant15289 ZonPlant13290 ZonPlant17291 ZonPlant18292 ZonPlant19293 ZonPlant12294 PowerBells_SM295 GroundHuggers_SM296 FirePlant_SM297 StarLights_SM298 AraWall05299 AraWall04300 AraWall02301 AraWall01302 AraWall06303 AraWall03304 ZonTree02305 ZonTreeSmudge03306 ZonTreeSmudge02307 ZonTreeSmudge01308 ZonTreeSmudge04309 ZonHut01310 ZonHut02311 ZonHut03312 ZonHut04313 ZonHut05314 VerTree04315 VerTree06316 VerTree05317 VerTree07318 VerTree08319 VerTree09320 MarsPlant01321 lushfoliage05322 lushfoliage2-01323 ArchiFoliage01324 ArchiFoliage03325 ArchiFoliage04x326 Frond02327 ZonHut06328 ZonRuin01329 ZonRuin02330 ZonRuin03331 ZonHut07332 ArchiTree06333 LushRock07334 LushRock08335 LushRock05336 LushRock04337 LushRock02338 LushCrushed06339 LushRock06340 LavaRockB012341 LavaRockB011342 TarDev06343 TarDev08344 ZonRuin15345 ZonRuin16346 TarDev07347 ZonHut08348 ZonHut09349 ZonHut11350 ZonHut10351 Lush04352 Lush06353 Lush04crisp354 Lush05crisp355 Lush06crisp356 ZonTmound01357 ZonTmound03358 ZonTmound05359 ZonTmound06360 ZonTmound04361 SatinsMist_SM362 Aracrop03363 Aracrop05364 DVCactus01365 DVCactus02366 DVCactus03367 DVBloom01368 DVBloom02369 AraTree10370 AraTree08371 AraTree08a372 DawnSunburst_SM373 Tree1374 Tree4375 Tree5376 Tree6377 Tree4Dead378 Tree5Dead379 Tree3380 Tree2381 Tree1Dead382 Tree2Dead383 Tree3Dead384 IWantYou_SM385 lushfoliage02386 lushfoliage2-03387 lushvine01388 lushfoliage2-02389 Lush08crisp390 lushfoliage01391 lushfoliage07392 lushfoliage2-05393 lushvine02394 lushvine03395 FTree1396 TTree1397 FTree3398 TTree2399 Rock2a400 Rock06401 Frond01402 MoonRock19403 MoonRock16404 EGHead1b405 EGHead3b406 EGHead7407 Totem Pole 1408 MoonRock05409 ZonWall08410 AraTow01411 AraTow02412 AraTow03413 AraTow04414 Pipe03Hole415 Pipe03416 Light02417 Barrier04418 Barrier10419 DryRock13420 Palm05421 Palm06422 Lushpsmudge01423 Lushpsmudge02424 DryCrush43Scar425 DryCrush44Scar426 Rockgone01427 MoonRock01428 Lushpsmudge04429 Lushpsmudge03430 ZonWall06431 Barrier01432 Barrier12433 Barrier16434 Barrier19435 Barrier20436 widget17437 widget15438 widget18439 widget16440 widgetscar02441 widgetscar01442 widget14443 widgetscar04444 widgetscar03445 widgetscar06446 Truck07447 Truck04448 Truck03449 Pastascar01450 lushfoliage2-04451 MetalZone_+1.5452 MetalTower14453 MetalTower13454 MetalTower02455 MetalTower01456 MetalTower12457 MetalTower11458 MetalTower03459 LavaCrushA003460 LavaCrushA013461 LavaCrushA004Scar462 LavaRockA005463 Tree6Dead464 ArchiTree02crisp465 LushTree01466 Lush03467 Lush02crisp468 Lush02469 Aracrop06470 DryRock01Scar471 lushfoliage04472 lushfoliage03473 Lush09crisp474 Building06475 Building08476 Building15477 dvspire1478 dvspire3479 dvspire2480 dvspire4481 dvspire7482 Lunar Spire 1483 Lunar Spire 2484 Lunar Spire 5485 Lunar Spire 4486 Lunar Spire 7487 Lunar Spire 8488 Lunar Spire 10489 Lunar Spire 11490 Lunar Spire 12491 Lunar Spire 13492 Lunar Spire 6493 Lunar Spire 3494 LavaRockA015Scar495 LavaRockA008Scar496 LavaRockA016Scar497 LavaRockA003498 LavaCrush01499 LavaRockC015500 LavaRockA004501 LavaRockA004Scar502 LavaRockB012Scar503 LavaRockA015504 LavaRockA016505 LavaCrushB012506 LavaRockA013507 LavaRockC005508 LavaCrushC003Scar509 LavaCrush03Scar510 LushCrushed04511 LushRock01512 LushCrushed08513 LushCrushed208514 LushCrushed206515 LushRock03516 LavaRockC008Scar517 LushCrushed03518 LushCrushed05519 LushCrushed207520 TarTree07521 TarTree09522 TarTree08523 TarTreeSmudge02524 TarTreeSmudge01525 TarTree06526 TarTree05527 TarTree04528 TarTree03529 TarTreeSmudge03530 Building01531 Building09532 Building11533 Building14c534 Building15c535 Building06c536 Building07537 Building05b538 Building05539 Building04b540 Building02c541 Building01c542 Building13c543 Building14b544 EGSPatch1545 EGShroom3546 EGshroom2547 EGShroom1548 Coral01549 AquaCoral03550 anemone-03551 anemone-04552 anemone-05553 anemone-06554 anemone-07555 anemone-08556 anemone-10557 anemone-16558 anemone-12559 anemone-11560 aquacoral-01561 aquacoral-02562 aquacoral=04563 aquacoral-05564 anemone-14565 aquacoral-03566 aquacoral-07567 anemone-15568 aquacoral-06569 anemone-09570 anemone-13571 Seagrass01572 Seagrass02573 Seagrass03574 VerTreeDead06575 ZonTreeSmudge05a576 VerLampBurning01577 VerLampBurning02578 vent02mmWidth = read_u32_le(ptrMiniMap + 0);
mmHeight = read_u32_le(ptrMiniMap + 4);
for (y = 0; y < mmHeight; y++)
for (x = 0; x < mmWidth; x++)
pixel = file[ptrMiniMap + 8 + y * mmWidth + x];7. Resolving a feature: TNT → TDF → GAF
The TNT does not contain the complete feature asset. It contains the placement reference: an attribute-cell index points into the TNT's own feature-name table. The name then resolves into a feature definition and, normally, a GAF animation or image set supplied by the game, a tileset, a map archive, or a mod.
TDF — text definition files
- TDF is TA's bracketed, semicolon-terminated text format: named sections contain key/value entries and nested sections.
- Feature definitions commonly provide the feature section name, world/asset name, footprint, blocking/collision flags, reclaim/resource properties, damage or animation references, and rendering metadata.
- The section name is the important bridge: a TNT string such as
Tree1must match the feature definition/asset naming used by the installed data set. - TDF is not a universal global registry. A map may depend on stock TA data, a custom feature pack, or files bundled in its UFO/HPI.
Concrete TDF example: Bluefingers_SM
The following is a shortened, documented excerpt from features\\Flowers\\AtlFlowers2.tdf, bundled with The Kingdom Of TA II. The section name is the feature key; the values describe gameplay behaviour and name the GAF sequences used for rendering and state changes.
[Bluefingers_SM]
{
world=Atlantis;
description=BlueFingers;
category=Atlantis;
animating=0;
footprintx=1;
footprintz=1;
height=4;
filename=Atlflowers2;
seqname=BlueFingers_SM;
seqnameshad=BlueFingersShad_SM;
seqnamereclamate=FlowerSMrec_01;
energy=20;
seqnameburn=FlowerBurn_01;
featureburnt=Smudge01;
burnmin=5;
burnmax=15;
sparktime=5;
spreadchance=70;
seqnamedie=Smudge01;
featuredead=Smudge01;
Damage=1;
animtrans=0;
shadtrans=1;
flamable=1;
reclaimable=1;
featurereclamate=Smudge01;
reproduce=1;
reproducearea=6;
hitdensity=5;
blocking=0;
}[Bluefingers_SM]The section key is the name resolved from the map's feature table.footprintx/z, heightPlacement footprint and approximate visual/physical height.filename + seqname*The GAF basename and named entries for normal, shadow, reclaim, burn and death states.blocking, reclaimable, Damage, …Runtime behaviour; exact supported keys depend on the TA/mod data set.GAF — indexed animation files
- GAF begins with a header containing an entry count and an array of absolute pointers to entries.
- Each entry has a frame count, two unknown/reserved fields, and a 32-byte name.
- Each frame table stores width, height, X/Y offsets, a transparency palette index, a compression flag, optional nested-frame pointers, and a pointer to frame data.
- Frame data is either an uncompressed palette-index image or a compressed image decoded with the GAF frame codec. A GAF entry can therefore represent a static image, an animation, or nested/compound frames.
- Pixels are palette indices; resolve them through
PALETTE.PAL. Transparency is indicated by the frame's transparency index.
// conceptual resolver
cell = tnt.attributes[y * width + x];
if (cell.feature != 0xFFFF && cell.feature != 0xFFFC) {
name = tnt.featureNames[cell.feature];
definition = tdf.lookup(name); // installed data / feature pack
animation = gaf.lookup(definition.assetName);
image = gaf.decode(animation, palette);
}features\\Flowers\\AtlFlowers2.tdf and Anims\\AtlFlowers2.gaf. A TNT alone can identify a placed feature, but cannot guarantee that the referenced visual/definition assets are installed.8. Minimal parser checklist
- Read the 16 little-endian uint32 header fields.
- Validate
idVersion == 0x2000, even dimensions, and every pointer within the file. - Read
(width/2)×(height/2)uint16 tile indices; account for padding to an 8-entry boundary when calculating the next block. - Read
width×heightfour-byte attributes row-major. - Read
tiles×1024tile pixels and decode them through the TA palette. - Use the feature count and pointer to locate the feature table/string area; do not blindly assume it is empty.
- Read the minimap dimensions and palette-index pixels from
ptrMiniMap. - Pair the TNT with its OTA. TNT contains terrain; OTA contains mission metadata, schema and start positions.
References and tools
Primary format references: TAUtil source, especially TntHeader, TileAttr, TntReader and TntWriter; Mappy source, especially MapModelTntAdapter; and the historical TA TNT format notes.
Site implementation: Reverse Engineering TA Files, Procedural Map Generation, and the independent _render_tnt.py decoder in the TA Archive working tree.