Усі сторінки форматів ↓
Юніти, скрипти, конфігурації

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/, бо він поєднує три окремі завдання:

  1. Оголошення сторін — ім'я, префікс, командир, шрифти, кольори.
  2. Розмітка HUD — піксельні координати кожної смуги стану, підпису й кнопки в ігровому інтерфейсі.
  3. Меню будівництва — секція [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]).

Розібраний приклад — додавання класу руху

Щоб створити клас «човна, який може переходити вбрід дуже мілку воду»:

  1. Допишіть у 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
    }
  2. У FBI вашого юніта:

    MovementClass=AMPHIB3;

    Площа основи й обмеження класу заміщують власні значення FBI, тож ключі юніта FootprintX/FootprintZ/MaxWaterDepth більше не мають значення.

  3. Запакуйте:

    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.

Див. також

  • TDF — граматика на рівні парсера, спільна з FBI/OTA.
  • Звук — підключення sound.tdf і allsound.tdf.
  • FBI — юніти посилаються на MovementClass, SoundCategory, імена TDF зброї.
  • Глосарій — movement class, footprint, side.