🛡️ TA Archive

Procedural Map Generation

The Map Builder on this site generates playable Total Annihilation maps entirely in your browser. This article documents how it works — the same format knowledge from Reverse Engineering TA Files, applied in the opposite direction: instead of parsing a map, we write one.

The trick: borrow the tile atlas

A TNT file contains three big blocks: the tile map (which tile goes where), per-cell attributes (height, features), and the tile atlas — the actual 32×32-pixel tile graphics, unique per map. A big map carries thousands of unique tiles, easily 10+ MB.

Creating tile graphics from scratch is a content problem, not a format problem — that’s where AI-generated maps (and several failed generator attempts) produce the infamous “random tile noise”. Our builder sidesteps it entirely: it borrows the complete tile atlas of Ancient Issaquah, a Cavedog map whose terrain covers green land, cliffs, shores and water. Every tile in the atlas is indexed with its elevation profile (the four height values of its 2×2 attribute cells), learned from the original map.

That gives the generator something no text model has: a vocabulary of tiles that are known to look good, each tagged with the terrain height it represents.

The pipeline

  1. Heightmap — value noise over the map grid (one height per 16-px attribute cell), with an optional island falloff that pushes the map border below sea level.
  2. Tile matching — for every 32×32 block (2×2 cells), look up the atlas tile whose elevation profile best matches the four generated heights (minimum absolute difference). The result is consistent terrain: shores get shore tiles, heights get highland tiles — because that’s what the atlas tiles represented in the original map.
  3. Attribute block — the chosen tiles’ height values are written into the attribute cells verbatim, so the visible terrain and the walkable heights agree exactly. Features are set to none (0xFFFF).
  4. Assembly — 64-byte header (pointers to each block), tile map, attributes, only the used subset of the atlas, then the minimap (252×252 palette indices, water/lowland/highland colored).
  5. Companion OTA — a matching mission file with four ring-layout start positions, generated by the same rules as the OTA Builder.

Header field 0x2c: the flag that nobody documents

Our first generated map parsed perfectly, rendered a minimap — and crashed Total Annihilation on launch. The culprit: header field 0x2c (kbot calls it Unknown1), which we had set to 0. Checking every real TA map we have: the field is 1 in all of them, without exception (195/195). The engine evidently requires it to be 1 for a well-formed TA map; write 0 and the game dies before the minimap is even considered.

Two more conventions we confirmed the same way, by comparing 195 maps:

This is exactly why the builder is verified against the archive: the format knowledge exists in no single document, only in 600 files that happen to agree.

What it doesn’t do (yet)

Try it

Head to the Map Builder, pick a size and seed, hit Generate, download .tnt + .ota, drop both into your TA folder and start a skirmish. If a generated map looks off in-game, that’s a bug we want to hear about — contact in the Imprint.