TDF у gamedata — таблиці конфігурації рушія
Джерело: coreprime/kbot @ 0ab97bf · Редагувати на GitHub
Файли в
gamedata/— це текстові файли TDF, які налаштовують сам рушій: класи руху, категорії шкоди від зброї, дані сторін (розмітка інтерфейсу, меню будівництва, стартові юніти), прив'язки звуків і кілька невеликих таблиць пошуку. Моди, що змінюють правила гри (а не додають юніти), майже завжди працюють саме тут.
Ця сторінка описує найкорисніші файли gamedata. Усі вони використовують схожу на INI граматику TDF — подробиці на рівні парсера див. у TDF.
Tip
Спробуйте самі.
ls $(kbot ctx path)/gamedata/
# The web UI renders these as collapsible section trees
kbot mount $(kbot ctx path) --server
# → browse to gamedata/sidedata.tdf, then sidedata > [CANBUILD]
Коротко про файли
| Файл | Що визначає |
|---|---|
sidedata.tdf |
Розмітку інтерфейсу кожної сторони, стартового командира, меню будівництва. Найбільший файл у gamedata/. |
moveinfo.tdf |
Класи руху — якою місцевістю може пересуватися кожен «MovementClass». |
weapons.tdf |
Довідковий документ із граматики TDF зброї (переважно коментарі — не таблиця, що використовується під час гри). |
category.tdf |
Зрозумілі людині описи категорій юнітів. Суто косметичний. |
sound.tdf |
Звукові категорії юнітів (на них посилається SoundCategory= у FBI). |
allsound.tdf |
Звуки інтерфейсу та ігрових подій (клацання кнопок, сигнали панелі рахунку, фонова музика). |
los.tdf |
Налаштування зони видимості (модифікатори радіуса огляду залежно від місцевості). |
meteor.tdf |
Параметри метеоритного дощу (використовуються на деяких мапах кампанії). |
unitview.tdf |
Розмітку ігрової панелі інформації про юніт. |
buildinfo.tdf |
Гарячі клавіші меню будівництва й текст підказок. |
version.tdf |
Рядок версії гри, який повідомляє лобі. |
translate.tdf |
Таблицю локалізації рядків інтерфейсу. |
help.tdf |
Статті вбудованої довідкової системи. |
Велика трійка для моддингу — це sidedata.tdf (меню будівництва,
сторони), moveinfo.tdf (класи руху) і weapons.tdf (який є
документацією, а не даними: справжня зброя лежить у weapons/*.tdf).
moveinfo.tdf — класи руху
FBI юніта оголошує його MovementClass=KBOTSS2 (чи щось
подібне); рушій шукає цей клас у moveinfo.tdf, щоб вирішити, якою
місцевістю юніт може пересуватися.
TA 3.1c читає лише секції від [CLASS0] до [CLASS31] (першу секцію з
кожним із цих імен) і знаходить клас за його Name= без урахування
регістру, починаючи з найменшого слота. Коли клас юніта знайдено,
значення класу повністю заміщують власні ключі юніта
FootprintX/FootprintZ, MaxWaterDepth, MinWaterDepth і ключі
нахилів — MaxSlope=20 командира поступається значенню 32 з TANKDS2,
— а ключ, якого клас не задає, отримує ігрове значення за замовчуванням
(див. нижче), а не значення з FBI. Юніт без класу або з класом, якого
гра не може знайти, читає власні ключі FBI з тими самими значеннями за
замовчуванням. Метадані юнітів, пісочниця й хостовані матчі в KBot
Studio визначають рух саме так.
[CLASS0]
{
Name=KBOTSS2; // Class name referenced from FBIs
FootprintX=2; // Cells wide (16-px units)
FootprintZ=2; // Cells deep
MaxWaterDepth=12; // Deepest water it can enter
MaxSlope=32; // Steepest land slope it can climb
}
[CLASS3]
{
Name=TANKDH3;
FootprintX=3;
FootprintZ=3;
MaxWaterDepth=100; // Heavy tank — can ford deep water
MaxWaterSlope=30; // Slope limit *underwater* (separate from MaxSlope)
MaxSlope=15;
}
Поля
| Поле | Тип | Значення |
|---|---|---|
Name |
рядок | Ідентифікатор класу, на який посилається MovementClass= у FBI юнітів. Без урахування регістру. |
FootprintX, FootprintZ |
int | Площа основи для пошуку шляху в клітинках атрибутів по 16 пікселів. Заміщує площу основи з FBI юніта; 0, якщо клас її не задає. |
MaxWaterDepth |
int | Найбільша глибина води (в одиницях висоти рельєфу), у яку юніт може зайти. 0 = лише суходіл. За замовчуванням 10000 (будь-яка глибина): класи суден на повітряній подушці цього ключа не задають, тож такі судна ходять будь-якою водою, хоч би що казав їхній FBI. |
MinWaterDepth |
int | Мінімальна потрібна глибина води (кораблі, підводні човни). За замовчуванням -10000 (без мінімуму). |
MaxSlope |
int | Найкрутіший нахил, на який юніт може піднятися на суходолі (одиниці = 2π / 256 радіана). За замовчуванням 255; обмежений зверху MaxWaterSlope. |
BadSlope |
int | Нахил, на якому юніт рухається зі зниженою швидкістю (повільніше, але без блокування). За замовчуванням — половина MaxSlope; обмежений зверху MaxSlope. |
MaxWaterSlope |
int | Те саме, що MaxSlope, але під водою. За замовчуванням 255 (без обмеження, використовується для суден на повітряній подушці). |
BadWaterSlope |
int | Підводний відповідник BadSlope; за замовчуванням — половина MaxWaterSlope. |
Домовленості щодо імен
Ім'я класу кодує його форму коротким тегом — за домовленістю Cavedog:
| Префікс | Значення |
|---|---|
KBOT |
Двоногий кбот |
TANK |
Гусенична/колісна техніка |
BOAT |
Надводне судно |
SPID |
Павук / багатоногий повзун |
HOVER |
Судно на повітряній подушці |
Далі йде суфікс SS / SF / DS / DH / SH (малий/глибокий/важкий
тощо) і цифра площі основи. Іменування — лише домовленість: рушій
сприймає Name= як непрозорий ключ.
Important
Два юніти з однаковим MovementClass= мають спільну поведінку під
час пошуку шляху. Якщо змінити KBOTSS2 на MaxWaterDepth=50,
кожен малий кбот почне брести водою. Якщо вам потрібне налаштування
для окремого юніта, краще додайте новий клас.
sidedata.tdf — конфігурація сторін
Це найдовший файл у gamedata/, бо він поєднує три окремі завдання:
- Оголошення сторін — ім'я, префікс, командир, шрифти, кольори.
- Розмітка HUD — піксельні координати кожної смуги стану, підпису й кнопки в ігровому інтерфейсі.
- Меню будівництва — секція
[CANBUILD]з переліком того, що може будувати кожен будівельний юніт.
Блок сторони
[SIDE0]
{
name=ARM;
nameprefix=ARM;
commander=ARMCOM; // UnitName of the commander unit
intgaf=ARMINT; // GAF used for intro screen
font=console; // FNT for general text
fontgui=armbutt; // FNT for buttons
energycolor=208; // Palette index for energy bars
metalcolor=224; // Palette index for metal bars
// …followed by ~60 HUD coordinate sub-sections
[LOGO] { x1=132; y1=5; x2=152; y2=25; }
[ENERGYBAR] { x1=471; y1=12; x2=598; y2=14; }
[METALBAR] { x1=218; y1=12; x2=345; y2=14; }
...
}
[SIDE1] { name=CORE; ... }
| Поле | Значення |
|---|---|
name |
Назва сторони для відображення (використовується також для зіставлення категорій). |
nameprefix |
Префікс рядка, що додається до запитів локалізації. |
commander |
UnitName юніта-командира сторони. |
intgaf |
Послідовність GAF, що показується під час вибору фракції. |
font / fontgui |
Файли FNT для тексту HUD і кнопок. |
energycolor / metalcolor |
Індекси палітри для смуг HUD (індекси palette.pal). |
TA 3.1c читає сторони [SIDE0], [SIDE1], … по порядку й зупиняється
на першому відсутньому номері, а також після п'ятої. Секція з будь-яким
іншим іменем ([SIDE01], [SIDE3] після відсутньої [SIDE2], шоста
сторона) ніколи не читається, а кожна прочитана сторона потребує всіх
прямокутників HUD, перелічених нижче (ta.SideRectangles у kbot-io),
інакше гра не завантажує жодної сторони. Вибір сторони в пісочниці
студії пропонує ті самі сторони.
Підсекції координат HUD
Кожен видимий елемент HUD — це блок [NAME] з піксельними координатами
x1/y1/x2/y2. Вони задані відносно базової роздільності 640×480; у
режимах з вищою роздільністю їх масштабує рушій.
[ENERGYBAR] { x1=471; y1=12; x2=598; y2=14; }
Щоб перемістити смугу енергії, змініть чотири числа. Щоб змінити її
вигляд, замініть GAF, яким HUD малює в цій позиції (задається в
unitview.tdf).
Меню будівництва [CANBUILD]
Статичне визначення меню будівництва. Кожен будівельний юніт перелічує, що він може будувати на початку гри:
[CANBUILD]
{
[ARMCOM]
{
canbuild1=ARMSOLAR; // Slot 1 on the build menu
canbuild2=ARMWIN;
canbuild3=ARMESTOR;
canbuild4=ARMMSTOR;
canbuild5=ARMMEX;
...
}
[ARMLAB]
{
canbuild1=ARMCK;
canbuild2=ARMPW;
...
}
}
Номер слота — це позиція на сторінці меню будівництва. Меню
будівництва TA — це сітка 2 стовпці × 3 рядки, тож кожна сторінка
вміщує 6 слотів: canbuild1–canbuild6 — це сторінка 1,
canbuild7–canbuild12 — сторінка 2 і так далі.
Як TA 3.1c читає таблицю (CanBuildBuilder.BuildList у kbot-io; їй
слідують kbot document, переглядач юнітів і меню будівництва в
пісочниці):
- Список отримує лише юніт, у FBI якого встановлено
Builder=1; підсекція для будь-якого іншого юніта ігнорується. - Гра читає першу секцію
[CANBUILD]і в ній — першу підсекцію, названу на честь будівельника (без урахування регістру). - Вона читає
canbuild1,canbuild2, … і зупиняється на першому відсутньому номері:canbuild1=ARMSOLAR; canbuild3=ARMLAB;дає один запис. - Ім'я, яке не відповідає жодному юніту, пропускається, а список містить щонайбільше 30 юнітів. Записи з download (див. нижче) можуть довести меню будівельника до 31 юніта. (Старіша документація подекуди стверджувала, що на сторінці 12 слотів; насправді сітка в грі має 6.) Розкладку по сторінках для кожного будівельного юніта базової гри див. у довіднику дерева будівництва TA.
Important
У модах НЕ редагуйте sidedata.tdf, щоб додати юніти. Схвалений
Cavedog спосіб додати юніт до меню будівництва — постачати файл
download/<UNITNAME>.tdf разом з рештою вашого мода: під час запуску
рушій накладає кожен download/*.tdf поверх статичної таблиці
[CANBUILD] із sidedata.tdf.
Редагувати sidedata.tdf доречно лише тоді, коли ви постачаєте
тотальну конверсію, що переписує всю розмітку HUD і меню будівництва.
Навіть власне розширення Cavedog Core Contingency додає нові юніти
через download/*.tdf, а не змінюючи sidedata.tdf.
Див. TDF: [MENUENTRY]
і посібник з моддингу.
weapons.tdf — довідник із TDF зброї
Попри назву, gamedata/weapons.tdf — це переважно коментарі:
опублікований Cavedog довідник із граматики TDF зброї, який гра ніколи
не завантажує. Справжні визначення зброї лежать у weapons/*.tdf, по
одній секції на кожну зброю (див. TDF). kbot document не
показує секції gamedata/weapons.tdf як зброю.
Таблиця зброї
TA 3.1c будує таблицю з 256 слотів зброї з файлів .tdf, що лежать
безпосередньо в weapons/ (не в його підкаталогах), у тому порядку, в
якому їх перелічує:
- Секція потрапляє в слот, названий її
ID=,0–255. Секція безIDабо з ID поза цим діапазоном пропускається. - Пізніша секція з тим самим
ID— у тому самому файлі чи в пізнішому — заміщує попередню. Weapon1/Weapon2/Weapon3,ExplodeAsіSelfDestructAsюніта називають секцію; ім'я (без урахування регістру) розв'язується в найменший слот, що містить секцію з таким ім'ям.- Значення читаються як числові префікси:
weaponacceleration=13O;— це 13, і хибне значення ніколи не відкидає решту файлу. - Через порушену структуру гра відкидає весь файл, тож жодна зброя з
нього не завантажується, зокрема й секції перед місцем помилки:
заголовок секції без
]чи без{, текст без=або значення без;до кінця файлу, файл, що закінчується всередині секції, або порожній файл. Інших файлів це не стосується. (Зайва}поза будь-якою секцією не призводить до відкидання: гра на ній припиняє читання й зберігає те, що було до неї.) - Відсутній
rangeдорівнює32767; відсутнійminbarrelangle—-11.25градуса;reloadtimeрахується в цілих тіках (30 за секунду,reloadtime*30з відкиданням дробової частини:0.35перезаряджається за 10 тіків, тобто 0,333 с);turnrateзадається в одиницях кута за секунду (65536 = повне коло).
KBot Studio, пакети й kbot host визначають зброю через цю таблицю.
Файли, які гра відкидає, і секції, які вона пропускає чи заміщує,
повідомляються як попередження
(kbot pack їх виводить; студія віддає їх за адресою
/api/studio/weapons/warnings).
Спрайти rendertype=4
Зброя з rendertype=4 запускає 2D-спрайт з anims/fx.gaf, а її color=
визначає, який саме: 0 — cannonshell, 1 — plasmasm, 2 — plasmamd,
3 — ultrashell, 4 — знову plasmasm; будь-яке інше значення (як-от
color=255 в EARTHQUAKE) спрайта не малює. Спрайт просувається на один
кадр за ігровий тік від моменту пострілу, хоч би які тривалості мали
кадри GAF.
Довідкові коментарі документують:
- Три архетипи зброї:
ballistic,lineofsight,dropped. Кожен TDF зброї мусить установити один із них на1. - Дальність, швидкість, прискорення — у пікселях і пікселях за секунду.
- Зона ураження — радіус у пікселях, а
edgeeffectivenessзадає частку спаду (наприклад,0.5= половина шкоди на краю). - Черга й розкид —
burst,burstrate,sprayangle. - Двофазна зброя —
twophase,weapontype2,flighttimeдля снарядів на кшталт starburst. - Тип рендерингу —
rendertype=Nобирає 3D-модель, растр із палітрою, промінь тощо.
У підсекції [DAMAGE] містяться модифікатори шкоди для кожної
категорії цілей:
[FLAMETHROWER] {
...
[DAMAGE]
{
default=10; // Damage applied to anything not listed
corpyro=2; // Pyros are nearly fire-proof
}
}
Ключі в [DAMAGE] — це імена юнітів: перелічений юніт отримує цю
шкоду замість default=, кожен інший юніт отримує default=. Значення
обрізаються до 16 бітів. Вибухи під час загибелі (ExplodeAs,
SelfDestructAs) використовують ту саму таблицю: CORPYRO_BLAST за
замовчуванням завдає 60 шкоди, а Pyro — лише 15.
category.tdf — описи категорій юнітів
Косметичний плаский список, що зіставляє токени категорій із зрозумілим людині текстом. Рушій показує їх на панелі інформації про юніт:
[Plant] { description = Unit Creation plant; }
[KBOT] { description = Some type of units; }
[Tank] { description = Some type of units; }
[Metal] { description = Some type of units; }
Прочерки замість описів — це ненавмисна шаблонна заготовка від Cavedog. Більшість модів залишає цей файл як є; деякі замінюють описи на нормальний художній текст. На ігровий процес його зміна не впливає.
sound.tdf і allsound.tdf
Описано на сторінці WAV / Звук. Коротко:
sound.tdf— прив'язки звуків для категорій юнітів (секції[ARM_COM],[ARM_KBOT]). На них посилаєтьсяSoundCategory=у FBI. Гра читає 23 події, кожну якKEY, потімKEY1,KEY2, … до першого відсутнього номера.allsound.tdf— глобальні прив'язки звуків інтерфейсу ([BIGBUTTON],[SKIRMISH],[BGM]).
Розібраний приклад — додавання класу руху
Щоб створити клас «човна, який може переходити вбрід дуже мілку воду»:
Допишіть у
gamedata/moveinfo.tdf:[CLASS20] { Name=AMPHIB3; FootprintX=3; FootprintZ=3; MaxWaterDepth=100; // Deep water OK MaxSlope=20; // Reasonable land climbing MaxWaterSlope=200; // Smooth underwater movement }У FBI вашого юніта:
MovementClass=AMPHIB3;Площа основи й обмеження класу заміщують власні значення FBI, тож ключі юніта
FootprintX/FootprintZ/MaxWaterDepthбільше не мають значення.Запакуйте:
kbot hpi pack ./mymod --target mymod.ufo
Тепер юніт безперешкодно пересуватиметься і суходолом, і водою.
Note
Читаються лише секції від [CLASS0] до [CLASS31]. Клас у
[CLASS32], [CLASS100] чи [HOVERXL] ніколи не знаходиться, і
юніти, що його називають, повертаються до власних ключів FBI. Оберіть
вільний слот нижче 32 (релізна гра використовує від CLASS0 до
CLASS14); друга секція з тим самим іменем слота ігнорується.
Типові розміри
| Файл | Діапазон у gamedata/ від Cavedog |
|---|---|
sidedata.tdf |
~50 КБ |
moveinfo.tdf |
~3 КБ (15–20 класів) |
sound.tdf |
~20 КБ (понад 300 категорій) |
weapons.tdf |
~2 КБ (переважно коментарі) |
category.tdf |
~1 КБ |
| Інші файли gamedata | < 5 КБ кожен |
Підводні камені
Warning
Багато файлів gamedata завантажуються один раз під час запуску рушія, а не для кожної мапи. Щоб перевірити зміну, доведеться перезапустити гру — перезавантажити лобі недостатньо. На цьому спотикається чимало моддерів, які думають, що їхня зміна «не спрацювала».
- Слоти класів руху фіксовані. Читаються лише секції від
[CLASS0]до[CLASS31]; пропуски в нумерації в межах цього діапазону допустимі. - Коментарі в більшості файлів пишуться через
//, а не/*…*/, алеweapons.tdfвикористовує обидва варіанти. Тестові парсери приймають обидва; деякі сторонні інструменти — ні. - Координати HUD у
sidedata.tdfзадано для базової роздільності 640×480, а для вищих роздільностей їх масштабує рушій. Не записуйте координати в сучасних роздільностях. - У нумерації
[CANBUILD]не має бути пропусків. Гра припиняє читати список будівельника на першому відсутньомуcanbuildN, тожcanbuild11, за яким ідеcanbuild14, втрачає 14-й запис і всі наступні, без жодної помилки. MovementClass, якого гра не може знайти, — не помилка. Юніт мовчки використовує власні ключі FBI зі значеннями гри за замовчуванням для відсутніх — і юніт безMaxWaterDepthтоді бреде водою аж до глибини 10000.