Карты TA: Kingdoms — .tnt + .ota + .crt + .kmp
Источник: coreprime/kbot @ 0ab97bf · Редактировать на GitHub
Карты TA: Kingdoms — это вариант TNT (с другим словом IDVersion), дополненный одним или двумя файлами метаданных, а для миссий одиночной игры есть ещё формат архивов кампании на основе HPI v2. Это намного ближе к модели карт TA, чем предполагали старые исследовательские заметки про «BTM / BMP с картой высот»: в настоящей установке TA:K от GoG нет ни
.btm, ни сопутствующих BMP.Существующий в kbot читатель HPI v2 прозрачно открывает архивы
.kmp. Читатель TNT в kbot распознаёт слово версии TA:K и декодирует заголовок, карту высот по DataUnit, сетку наложения текстур (таблицы имён текстур рельефа и смещений U/V), сетку расстановки объектов с таблицей имён и встроенную миникарту — этого достаточно, чтобы отрисовать всю карту в полном разрешении, собрав её из внешних JPG-текстур рельефа и GAF-спрайтов объектов. На этой странице описано то, что можно проверить по поставляемой установке, а также оставшиеся пробелы.
Important
Обновление статуса (по сравнению с первоначальной версией этой
страницы, «исследовательскими заметками»). Типы файлов, которые здесь
раньше обсуждались, — .btm, сопутствующие BMP, PCX с палитрами
сторон — в установке TA: Kingdoms от GoG на самом деле отсутствуют.
Настоящие типы файлов описаны ниже. Для сравнения с другим проектом
TA:K с открытым исходным кодом см.
iiCompleteDestruction:
для некоторых структур, специфичных для TA:K, их парсер полнее, чем у
kbot.
Из каких файлов состоит карта TA:K
Подсчёт по каталогу карт установки от GoG:
| Расширение | Количество | Назначение |
|---|---|---|
.kmp |
181 | Архив HPI v2, в котором собраны карта, скрипты и ресурсы миссии кампании |
.tnt |
55 | Данные рельефа карты (двоичный файл по образцу TNT со своим для TA:K словом IDVersion) |
.ota |
55 | Метаданные карты — формат TDF, та же структура, что у .ota в TA, с полями, специфичными для TAK |
.txt |
55 | Описание карты в свободной форме (несколько слов, показывается в лобби) |
.crt |
33 | Сопутствующий файл сценария: заранее расставленные юниты, движок правил для каждого игрока, именованные области триггеров |
.tdf |
6 | Файлы настройки игрового процесса для отдельных карт (балансировка кампании, подсказки ИИ) |
Обычная карта для сетевой игры поставляется тройкой .tnt + .ota +
.txt, иногда с сопутствующим .crt. Миссии кампании упакованы в архивы
.kmp, где тот же набор файлов собран вместе со скриптами миссии.
Tip
Просмотр содержимого карты TA:K без распаковки:
# 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 — рельеф TA:K (TNT v2)
TA:K использует структуру TNT из TA, но повышает слово IDVersion.
Шестнадцатеричный дамп 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.......
Первый uint32 — 0x00004000, тогда как TNT в TA использует
0x00002000. Контейнер по-прежнему состоит из заголовка и секций, к
которым обращаются по указателям, но TA:K вовсе не мозаика из тайлов.
Там, где TA хранит сетку индексов тайлов и палитру графики тайлов 32×32,
TA:K хранит рельеф как сетку наложения текстур, ссылающуюся на
внешние JPG-текстуры, а также отдельную карту высот и сетку
расстановки объектов. Всё нижеследующее проверено на 55 поставляемых
картах:
Width/Height— это количество DataUnit по 16 пикселей, а не пиксели. Карта «15 × 15», напримерathri cay, хранитWidth = Height = 480DataUnit →480 × 16 = 7680пикселей по стороне. Карта высот и сетка объектов заданы с шагом в один DataUnit, а рельеф — на более крупной сетке Graphic Unit по 32 пикселя, ровно вдвое реже сетки DataUnit по каждой оси (guW = Width/2).- Заголовок — это двенадцать идущих подряд
uint32со смещениями и количествами; имена полей из TA больше не описывают содержимое. В таблице ниже указано их значение в TA:K. - Указатели на секции абсолютные, поэтому каждая секция читается по своему указателю и вычисленной длине.
| Смещение | Поле TA:K | Размер секции | Примечания |
|---|---|---|---|
0x00 |
Version |
— | 0x4000 (TA пишет 0x2000) |
0x04 |
Width |
— | в DataUnit; ×16 → пиксели, ÷2 → Graphic Unit |
0x08 |
Height |
— | в DataUnit |
0x0C |
SeaLevel |
— | порог высоты для воды |
0x10 |
HeightMapOffset |
Width × Height байт |
один байт высоты на DataUnit |
0x14 |
AttributesOffset |
Width × Height × 2 |
сетка объектов: индекс uint16 на DataUnit (≥0xFF00 = нет объекта) |
0x18 |
FeatureNamesOffset |
Count × 132 |
таблица имён объектов (4-байтовый индекс + 128-байтовое имя) |
0x1C |
FeatureCount |
— | количество типов объектов |
0x20 |
TerrainNamesOffset |
guW × guH × 4 |
имя текстуры для каждой GU → terrain/%08x.jpg |
0x24 |
UMappingOffset |
guW × guH байт |
смещение столбца внутри текстуры для каждой GU (×32 пикселя) |
0x28 |
VMappingOffset |
guW × guH байт |
смещение строки внутри текстуры для каждой GU (×32 пикселя) |
0x2C |
MiniMapOffset |
8 + 126×126 |
uint32 w, uint32 h, затем индексы |
Карта высот (0x10) — это один байт на DataUnit, поле высот в
оттенках серого, а не цветное изображение. Рельеф восстанавливается
наложением текстур: для каждой Graphic Unit таблица имён текстур рельефа
(0x20) даёт файл текстуры (terrain/<name>.jpg, имя записано как
8-значное шестнадцатеричное число в нижнем регистре), а таблицы U/V
(0x24/0x28) — подтайл 32×32, который нужно скопировать из этого JPG
с позиции (u×32, v×32). Сетка объектов (0x14) — это слой
расстановки: массив uint16 размером Width × Height, где каждая ячейка
содержит либо индекс объекта в таблице имён, либо большое сигнальное
значение (≥0xFF00), означающее «здесь объекта нет»; ячейка DataUnit
(x, y) соответствует пикселю рельефа (x×16, y×16). Таблица имён
(0x18) использует ту же 132-байтовую структуру записи, что и таблица
TileAnim в TA.
Блок миникарты во всех поставляемых картах всегда 126 × 126 и
использует тот же байт пустоты 0x64, что и в TA, для заполнения вне
неквадратных карт.
Note
Что уже работает с TNT из TA:K. kbot tnt describe выводит
заголовок, королевство, размеры карты высот и рельефа и сводку по
объектам. kbot tnt preview --vfs <root> отрисовывает рельеф в
полном разрешении с наложенными текстурами и накладывает поверх
GAF-спрайт каждого объекта, привязанный к его активной точке, — всю
карту так, как её рисует игра. kbot tnt image отрисовывает
самодостаточную карту высот в оттенках серого (внешние текстуры не
нужны; --features добавляет маркеры, раскрашенные по категориям).
kbot tnt minimap экспортирует встроенное превью 126 × 126.
Палитра миникарты — своя для каждого королевства
TA:K не раскрашивает миникарту одной общей палитрой. Превью 126 × 126
каждой карты запечено с палитрой текстур того королевства, которому
она принадлежит, — это поле kingdom= в соседнем .ota
(aramon / taros / veruna / zhon / creon). Если отрисовать те же
индексы с палитрой чужого королевства (или с PALETTE.PAL из TA),
получится пёстрый шум; с правильной палитрой видны естественные вода,
пляжи и рельеф.
kbot tnt minimap определяет королевство автоматически по соседнему
.ota. Если .ota нет (например, .tnt лежит отдельно), передайте
--kingdom <name> явно:
kbot tnt minimap "athri cay.tnt" -t mini.png # auto: veruna
kbot tnt minimap loose.tnt --kingdom aramon -t mini.png
.ota — метаданные карты (TDF, в основном знакомый)
.ota в TA:K — тот же формат в стиле TDF, что и в TA, с несколькими
полями, специфичными для TAK. Полный файл 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; }
…
}
}
}
| Поле | Аналог в TA | Примечания |
|---|---|---|
kingdom= |
нет | Принадлежность к стороне (aramon / taros / veruna / zhon / creon). По нему фильтрует лобби; кроме того, оно выбирает палитру рельефа и миникарты, которой раскрашено запечённое превью в .tnt. |
size= |
нет | Размер карты в читаемом виде для лобби. |
memory= |
нет | Рекомендуемый объём ОЗУ. Ни на что не влияет. |
hasscenario= |
нет | 1 для миссий кампании, 0 для карт схватки. |
[Map Data] |
[Schema N] |
Сводит подсекцию схемы к одному блоку (TA:K всегда поставляет только одну схему на карту). |
Всё остальное (StartPos1..N, aiprofile= и т. д.) работает так же, как в
TA: просмотрщик OTA в kbot mount справляется с обоими вариантами без
изменений.
.kmp — архивы HPI v2 с миссиями кампании
.kmp — это переименованный архив HPI v2.
Начало файла 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…
В точности структура заголовка v2 (маркер HAPI → версия 0x00020000 →
24-байтовый заголовок v2 → фрагменты SQSH). kbot hpi list, info,
extract работают напрямую. Обычно в .kmp упакованы:
.tntи.otaмиссии- Несколько GAF для роликов и брифингов
- COB-файлы скриптов миссии — для скриптов миссий TA:K использует
формат COB (
VersionSignature == 6), а не отдельный язык скриптов. Здесь находятся все 3 885 мест опкодаMISSION_COMMAND(0x10073000) в оригинальной установке TAK. Формат хранения и пул строк с именами звуков в каждом COB, на который ссылаются команды миссии по индексу, описаны в разделах TA: Kingdoms — отличия COB v6 и Приложение C в cob.md. - Иногда — переопределения юнитов для конкретной миссии
.crt — скрипт сценария (юниты, правила, триггеры)
.crt содержит скриптовый слой карты: юниты, расставленные до начала
игры, движок правил для каждого игрока, который управляет ИИ в схватке и
задачами кампании, и именованные прямоугольные области триггеров, на
которые ссылаются эти правила. Карты для сетевой игры поставляются с
пустой заглушкой (без юнитов, девять пустых слотов игроков, без
триггеров, 56 байт); в картах кампании и особых картах заполнены все
секции, вплоть до ~120 КБ.
Весь файл записан в little-endian и представляет собой прямой образ структур движка в памяти, поэтому записи юнитов содержат несколько неинициализированных полей выравнивания.
Заголовок
| Смещение | Тип | Поле | Примечания |
|---|---|---|---|
0x00 |
uint32 |
Signature | 0x3F800000 — маркер IEEE-754 1.0f |
0x04 |
uint32 |
Unknown1 | 0 на всех поставляемых картах, кроме одной |
0x08 |
uint32 |
UnitCount | число следующих записей расставленных юнитов |
abnar's terrace.crt (пустая заглушка) начинается так:
00000000: 00 00 80 3f 00 00 00 00 00 00 00 00 09 00 00 00
1.0f, Unknown1 = 0, UnitCount = 0, затем число игроков 9.
Записи юнитов (по 568 байт)
| Смещение | Тип | Поле |
|---|---|---|
+0 |
char[256] |
UnitType (завершён NUL) |
+256 |
char[256] |
UniqueName (обычно пусто) |
+512 |
uint32 |
X (мир) |
+516 |
uint32 |
Y (ось высоты) |
+520 |
uint32 |
Z (мир) |
+524 |
uint32 |
PlayerId (с 0) |
+528 |
uint32 |
HealthPercent (обычно 100) |
+532 |
uint32 |
ArmorPercent (обычно 100) |
+536 |
uint32 |
WeaponPercent (обычно 100) |
+540 |
uint32 |
Angle (обычно 180) |
+544 |
uint32 |
Veteran |
+548 |
uint32 |
неизвестно |
+552 |
uint32 |
неизвестно |
+556 |
uint32 |
FootprintX |
+560 |
uint32 |
FootprintZ |
+564 |
uint32 |
неизвестно |
Игроки, правила, условия, действия
После юнитов идёт uint32 с числом игроков (всегда 9), а за ним —
столько же блоков игроков. Каждый блок игрока — это uint32 с числом
правил, за которым следуют сами правила. Правило устроено так:
uint32с числом условий, затем каждое условие — это опкодuint32и пять 64-байтовых слотов аргументов;uint32с числом действий, затем каждое действие — это опкодuint32и пять 64-байтовых слотов аргументов.
Триггеры
Завершающий uint32 с числом триггеров предшествует такому же числу
записей триггеров. Каждая запись — это 256-байтовое имя, завершённое
NUL, и четыре границы uint32 — Left, Top, Right, Bottom — в
ячейках карты. Имена читаемые (The Hill, Player 1).
Инструменты
kbot crt describe <map.crt> выводит сводку по типам юнитов, число
правил и области триггеров; добавьте --verbose, чтобы получить полный
список расстановки. MCP-инструмент crt_describe возвращает те же
данные в виде JSON.
Один файл — cairbray coast landing.crt — имеет сдвинутый, вручную
отредактированный заголовок, не соответствующий этой структуре; парсер
отклоняет его с понятной ошибкой, а не декодирует неверно.
.txt — описание в свободной форме
Одна строка ASCII, используется в лобби. Например,
abnar's terrace.txt: 9 x 7 4 Player 32MB (та же строка, что в поле
missiondescription файла .ota). Скорее всего, инструменты создания
карт записывали оба файла при экспорте; игра, по-видимому, показывает
значение из .ota.
Работа с картами TA:K сегодня
Практические варианты, по возрастанию трудоёмкости:
- Свободный просмотр —
kbot hpi list/info/extractработает с файлами.kmpсразу..otaи.txt— обычный текст. - Описание карты —
kbot tnt describe <map.tnt>выводит заголовок TA:K, королевство, размеры карты высот и рельефа и сводку по объектам. - Отрисовка миникарты —
kbot tnt minimap <map.tnt> -t mini.pngэкспортирует встроенное превью 126 × 126 в полном цвете, автоматически выбирая палитру королевства по соседнему.ota(переопределяется через--kingdom; см. примечание о палитре выше). - Отрисовка всей текстурированной карты —
kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.pngнакладывает на рельеф текстуры изterrain/*.jpgустановки и добавляет GAF-спрайт каждого объекта, получая карту такой, какой её отрисовывает игра (athri cay → 7680 × 7680). Палитра спрайтов объектов читается изpalettes/<kingdom>_features.pcx. - Отрисовка карты высот —
kbot tnt image <map.tnt> -t height.pngне требует внешних ресурсов и выдаёт карту высот по DataUnit в оттенках серого (--featuresдобавляет маркеры расстановки, раскрашенные по категориям). - Перепаковка архива кампании —
kbot hpi packпока создаёт только v1, поэтому перепакованный.kmpне загрузится. Чтобы вручную отредактировать.kmp, извлеките его, измените файлы и упакуйте сторонним упаковщиком с поддержкой v2, пока kbot не научится записывать v2.
Warning
TA: Kingdoms требует -disablecavedogverification, чтобы загрузить
большинство изменённых файлов, включая изменённые карты. Без этого
ключа движок отклоняет всё, чей хэш не входит в его список разрешённых.
Указывайте это в инструкции по установке любого мода.
Что kbot умеет и чего не умеет с картами TA:K сейчас
| Операция | Статус |
|---|---|
Чтение заголовков .kmp (HPI v2) и списка файлов |
✅ |
Извлечение файлов из .kmp |
✅ |
Разбор .ota (формат TDF) |
✅ |
Чтение заголовка .tnt TA:K (kbot tnt describe) |
✅ |
Экспорт миникарты .tnt TA:K (kbot tnt minimap) |
✅ (полный цвет — палитра королевства из .ota) |
Отрисовка всей текстурированной карты TA:K (kbot tnt preview --vfs) |
✅ (рельеф с наложенными текстурами + GAF-спрайты объектов) |
Отрисовка карты высот TA:K (kbot tnt image) |
✅ (самодостаточная, в оттенках серого; --features добавляет маркеры) |
Запись .tnt TA:K (kbot tnt pack) |
❌ |
Запись .kmp (упаковка HPI v2) |
❌ |
Пулреквесты по любому из пунктов ❌ приветствуются. Карта высот, сетка
наложения текстур, сетка объектов и таблица объектов уже декодированы,
так что рельеф и объекты отрисовываются в полном разрешении; остаются
запись для round-trip отредактированных карт TA:K и упаковка .kmp v2.
См. также
- HPI — контейнер архивов v2 (
.kmp— это HPI v2 с переименованным расширением). - TNT — формат TNT из TA; TA:K использует ту же структуру с IDVersion
0x4000. - TDF — формат, в котором разбирается
.ota. - GAF — файлы анимаций
.taf, которые используются по всей TA:K (ролики в архивах.kmp). - Интерфейс TA: Kingdoms — формат виджетов меню и HUD.
- Глоссарий — side, heightmap.