Усі сторінки форматів ↓
Мапи й рельєф

Мапи 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 постачуваних мапах:

  1. Width/Height — це кількість 16-піксельних DataUnit, а не пікселів. Мапа «15 × 15», як-от athri cay, зберігає Width = Height = 480 DataUnit → 480 × 16 = 7680 px на бік. Карта висот і сітка об'єктів дискретизуються по одному значенню на DataUnit; рельєф дискретизується на грубішій 32-піксельній сітці Graphic Unit (графічних одиниць), рівно вдвічі меншій за сітку DataUnit по кожній осі (guW = Width/2).
  2. Заголовок — це дванадцять послідовних uint32 зі зміщеннями та кількостями; назви полів із TA більше не описують вмісту. Таблиця нижче дає їхнє значення в TA:K.
  3. Вказівники на секції абсолютні, тож кожну секцію читають за її власним вказівником і обчисленою довжиною.
Зміщення Поле 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 (×32px)
0x28 VMappingOffset guW × guH байтів зміщення рядка в текстурі для кожного GU (×32px)
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= немає Рекомендований обсяг RAM. Суто косметичне.
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 сьогодні

Практичні варіанти, від найпростішого до найтрудомісткішого:

  1. Вільно переглядати — kbot hpi list/info/extract для файлів .kmp працює одразу. .ota і .txt — звичайний текст.
  2. Описати мапу — kbot tnt describe <map.tnt> виводить заголовок TA:K, королівство, розміри карти висот і рельєфу та розбивку об'єктів.
  3. Відрендерити мінімапу — kbot tnt minimap <map.tnt> -t mini.png експортує вбудований попередній перегляд 126 × 126 у повному кольорі, автоматично обираючи палітру королівства із сусіднього .ota (її можна перевизначити через --kingdom; див. примітку про палітру вище).
  4. Відрендерити повну текстуровану мапу — kbot tnt preview <map.tnt> --vfs <flattened-tak-root> -t map.png текстурує рельєф із файлів terrain/*.jpg інсталяції й накладає GAF-спрайт кожного об'єкта, створюючи мапу такою, якою її рендерить гра (athri cay → 7680 × 7680). Палітра спрайтів об'єктів читається з palettes/<kingdom>_features.pcx.
  5. Відрендерити карту висот — kbot tnt image <map.tnt> -t height.png не потребує зовнішніх ресурсів; він виводить карту висот DataUnit у відтінках сірого (--features накладає позначки розміщення, забарвлені за категоріями).
  6. Перепакувати архів кампанії — kbot hpi pack наразі створює лише v1, тож перепакований .kmp не завантажиться. Поки kbot не навчиться записувати v2, редагуйте .kmp вручну: розпакуйте його, змініть файли й запакуйте сторонньою утилітою, що підтримує 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) ❌

Pull request-и для будь-якого з пунктів ❌ вітаються. Оскільки карту висот, сітку текстурування, сітку об'єктів і таблицю об'єктів уже декодовано, рельєф і об'єкти рендеряться в повній роздільності; лишаються шлях запису для 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.