Мапи 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— це кількість 16-піксельних DataUnit, а не пікселів. Мапа «15 × 15», як-отathri cay, зберігаєWidth = Height = 480DataUnit →480 × 16 = 7680px на бік. Карта висот і сітка об'єктів дискретизуються по одному значенню на DataUnit; рельєф дискретизується на грубішій 32-піксельній сітці Graphic Unit (графічних одиниць), рівно вдвічі меншій за сітку 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 (×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 сьогодні
Практичні варіанти, від найпростішого до найтрудомісткішого:
- Вільно переглядати —
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не завантажиться. Поки 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.