Все страницы форматов ↓
Юниты, скрипты, конфигурации

TDF / FBI / OTA — текстовые файлы конфигурации

Источник: coreprime/kbot @ 0ab97bf · Редактировать на GitHub

Файлы TDF («Text Data File»), FBI («Feature/Building/Item») и OTA («Online Total Annihilation») используют один и тот же текстовый формат в духе INI. Именно так Cavedog описывала всё, что не было двоичным: характеристики юнитов, параметры оружия, описания объектов, метаданные миссий, звуковые категории, подсказки для ИИ.

Расширение Где искать Примеры
.fbi units/ ARMCOM.FBI, CORRAID.FBI — описания юнитов
.tdf features/, weapons/, sounds/, gamedata/ и др. armflak_weapon.tdf, treeb.tdf
.ota maps/ metal heck.ota — метаданные карты, стартовые позиции, сведения для ИИ

Это обычный текст в ASCII: такой файл открывается в любом текстовом редакторе.

Tip

Попробуйте сами.

# The web UI renders FBI/TDF/OTA as collapsible section trees
kbot mount ~/games/totala --server
# → browse to units/ARMCOM.FBI

О работе в терминальном браузере и параметрах распаковки (flatten) см. справку по kbot mount в описании командной строки.

Из Go. Используйте formats/tdf:

import "github.com/coreprime/kbot/formats/tdf"

doc, _ := tdf.ParseFile("units/ARMCOM.FBI")
info := doc.Section("UNITINFO")
fmt.Println(info.String("UnitName"), info.Int("MaxDamage"))

Синтаксис

Файл TDF — это дерево секций. У каждой секции есть имя в квадратных скобках, за которым идёт тело { ... } с парами ключ=значение и/или вложенными секциями.

[UNITINFO]
{
    UnitName=ARMCOM;
    Designation=Commander;
    Description=Commander, Arm;
    Side=ARM;
    Objectname=armcom;

    BuildCostEnergy=2500;
    BuildCostMetal=2500;
    MaxDamage=3000;

    [SOUNDS]
    {
        canselect=cmdsel1;
        select1=cmdok1;
    }
}

Правила:

  • Имена секций пишутся в квадратных скобках. Всё, что идёт после имени до парной }, принадлежит этой секции. Секция может уместиться в одной строке ([special0] { specialwhat=StartPos1; XPos=464; ZPos=216; }).
  • Значение тянется от = до следующей ;, в том числе через переносы строк. Больше ничто его не завершает, поэтому фигурные и квадратные скобки и = внутри значения — просто текст, а ; в значении не может оказаться никогда. Пробелы, табуляции и переносы строк по краям ключа или значения обрезаются. Если ключ присвоен дважды, остаётся последнее значение.
  • Регистр в ключах не важен. UnitName, unitname и UNITNAME обозначают одно и то же поле, и инструменты обычно приводят ключи к нижнему регистру при чтении. Имена секций тоже сравниваются без учёта регистра.
  • По умолчанию значения — это строки. Числа читаются по-сишному, по начальным цифрам: 12abc читается как 12, а 56.8 — как 56 там, где игре нужно целое (такие поля, как killmul и tidalstrength, читаются как дробные). Элементы списков разделяются пробелами (например, Category=NOTSUB COMMANDER NOTAIR ...).
  • Комментарии затираются раньше, чем читается всё остальное: // до конца строки и блоки /* ... */, которые могут занимать несколько строк. Поэтому missiondescription=See http://tauniverse.com; теряет всё, начиная с //, включая свою ;, и значение продолжается на следующей строке. kbot отказывается записывать значение, содержащее ;, // или /*.
  • Пробельные символы и пустые строки игнорируются.

Вложенные секции (как [SOUNDS] внутри [UNITINFO] выше) — обычное дело в FBI/OTA. Спецификация TDF не задаёт предельной глубины, на практике больше 3 уровней не встречается.


FBI — описания юнитов

FBI — это полное представление движка о юните. В нём в одном месте сведены 3D-модель юнита, скрипт, список оружия, звуковой банк, стоимость постройки и поведение в бою. Сокращённый пример — Командир ARM (Arm Commander):

[UNITINFO]
{
    // === Identification ===
    UnitName=ARMCOM;          // Internal lookup key
    Objectname=armcom;        // → objects3d/armcom.3do, scripts/armcom.cob
    Side=ARM;                 // ARM or CORE
    Designation=Commander;    // Mouseover label
    Description=Commander, Arm;

    // === Economy & build ===
    BuildCostMetal=2500;
    BuildCostEnergy=2500;
    BuildTime=89400;          // Build-power × seconds (engine units)
    WorkerTime=300;           // How fast it builds other things

    // === Combat ===
    MaxDamage=3000;           // Hit points
    Weapon1=COMMANDER_WEAPON; // → weapons/commander_weapon.tdf [COMMANDER_WEAPON]
    Weapon2=disintegrator;    // The dreaded D-gun
    candgun=1;                // Allowed to fire weapon2 on demand

    // === Movement ===
    MaxVelocity=1.15;
    Acceleration=0.075;
    BrakeRate=0.0825;
    TurnRate=510;
    MovementClass=COMMANDER_TANK3;  // → gamedata/movinfo.tdf

    // === Senses ===
    SightDistance=520;
    RadarDistance=585;

    // === Tags & categories ===
    Category=COMMANDER SURFACE MOBILE WEAPON ...;
    NoChaseCategory=AIR;

    [SOUNDS] {
        canselect=cmdsel1;
        select1=cmdok1;
        ...
    }
}

Руководство сообщества по FBI 1998 года (оно сохранено среди исходных материалов этого репозитория) описывает больше сотни полей. Назначение большинства понятно из названия, а неочевидными обычно оказываются эти:

Поле Что оно на самом деле определяет
Bmcode Код страницы меню строительства. Для обычных юнитов оставьте 1.
Category Список тегов через пробел. Его используют BadTargetCategory оружия, NoChaseCategory, ИИ и меню строительства.
MovementClass Ссылка на класс в gamedata/movinfo.tdf, который задаёт допустимые уклоны рельефа, глубину воды и т. д.
YardMap ASCII-рисунок (например, oooo\noooo\n), который задаёт площадь основания юнита и ограничения по воде и суше для каждой клетки.
Corpse Имя секции [FEATURE] (см. ниже), которая остаётся обломками.
SoundCategory Выбирает звуковой банк в gamedata/sound.tdf.
TEDClass Подсказка для редактора Cavedog. Во время игры не учитывается.

Important

UnitName — ключ, по которому юнит ищут во всех остальных местах: на него ссылаются OTA, ИИ, меню строительства. Если вы переименовываете FBI, придётся пройтись grep по всему моду в поисках ссылок.


TDF — описания объектов, оружия и звуков

Файлы features/**/*.tdf содержат секции [FEATURE], по одной на каждый статичный объект карты. Формат TNT (TNT) ссылается на них по имени секции:

[ArmTree01]
{
    description=Arm Tree;
    category=trees;
    object=arm_tree01;       // → objects3d/arm_tree01.3do
    footprintx=1;
    footprintz=1;
    height=20;
    blocking=1;              // Pathing obstacle
    flamable=1;
    burnmin=10;
    burnmax=20;
    burntime=30;
    feature_reclamate=ArmTree01_Heap; // Recursive: what's left when reclaimed
    damage=15;
    reclaimable=1;
    energy=0;
    metal=2;
    seqname=arm_tree01;      // GAF sequence to draw (for animated features)
}

Файлы weapons/*.tdf устроены так же, только секции у них [WEAPON_NAME]. Поле FBI Weapon1=COMMANDER_WEAPON указывает на секцию [COMMANDER_WEAPON] в одном из TDF в weapons/ через таблицу оружия игры, проиндексированную по ID. Каждой секции нужен ID= в диапазоне 0–255, более поздняя секция с тем же ID заменяет более раннюю, а имя указывает на слот с наименьшим номером, где оно встречается (см. Gamedata: таблица оружия). Руководство сообщества по оружию описывает около 60 разных полей. Самые содержательные из них — ballistic/lineofsight/dropped (архетип оружия), weapontimer, weaponvelocity, areaofeffect, edgeeffectiveness, burst/burstrate и подсекция [DAMAGE] (модификаторы урона по категориям).

[FLAMETHROWER] {
    ID=1;
    name=Flame Thrower;
    rendertype=5;
    ballistic=1;
    turret=1;
    range=160;
    reloadtime=1.2;
    weapontimer=1;
    weaponvelocity=188;
    areaofeffect=32;
    burst=17;
    burstrate=.04;
    [DAMAGE] {
        default=10;
        corpyro=2;          // Pyros are nearly fireproof
    }
}

Файлы download/*.tdf добавляют юнит в меню строительства одного или нескольких строителей без изменения sidedata.tdf. Через этот механизм дополнение Cavedog Core Contingency добавляет свои юниты, и этому же соглашению следует каждое дополнение .ufo с одним юнитом.

[MENUENTRY1]
{
    UNITMENU=ARMVP;       // Builder's UnitName
    MENU=3;               // Menu page (row)
    BUTTON=4;             // Slot within the page
    UNITNAME=MYFLASH;     // Unit being placed
}

[MENUENTRY2]              // Additional builders for the same unit
{
    UNITMENU=ARMACV;
    MENU=3;
    BUTTON=4;
    UNITNAME=MYFLASH;
}
Поле Тип Значение
UNITMENU str UnitName строителя, в чьё меню добавляется юнит.
MENU int Номер страницы меню строительства. 1–2 Cavedog зарезервировала за стандартными юнитами, по соглашению сообщества нумерация начинается с 3.
BUTTON int Слот на странице (0–5, расположены сеткой 2 столбца × 3 строки: 0 — вверху слева, 1 — вверху справа, 2 — посередине слева, 3 — посередине справа, 4 — внизу слева, 5 — внизу справа).
UNITNAME str Добавляемый юнит. Должен совпадать с UnitName= в FBI вашего юнита.

Как называть файл. По соглашению файл называют download/<UNITNAME>.tdf (по UNITNAME= первой записи), но движок читает все *.tdf в download/, так что имя файла — лишь подсказка для моддера. Обычно в одном файле описывают один юнит.

Несколько записей. В одном файле может быть несколько записей: в download/Armfort.tdf от Cavedog их три, чтобы оборонительную стену ARM (Arm Fortification Wall) можно было строить с ACK, ACV и ACA. TA 3.1c читает первые пять секций каждого файла, как бы они ни назывались ([MENUENTRY1] — общепринятое имя, но [ENTRY0] тоже работает), а шестая секция не читается никогда. Запись, в которой UNITMENU не называет ни одного юнита или называет юнит без Builder=1, игнорируется, как и запись, в которой UNITNAME не называет ни одного юнита. MENU и BUTTON хранятся в 8 битах, а меню строителя — его список [CANBUILD] плюс добавленное через download — вмещает не больше 31 юнита.

Important

download/*.tdf дополняет меню строительства, ничего не заменяя. Если выбранный слот совпадает с уже существующей записью, поведение движка непредсказуемо: обычно побеждает запись, загруженная позже, но порядок загрузки .ufo на разных платформах не гарантирован. Для модов, которые должны уживаться с другими, выбирайте дальнюю страницу MENU (4 или 5).

Это аддитивная точка расширения для модов: она позволяет выпустить один .ufo, не делая собственную копию sidedata.tdf размером 50 КБ. Весь путь от начала до конца описан в руководстве по моддингу.


OTA — метаданные карты

.ota поставляется вместе с каждым .tnt и содержит всё, что нужно движку, чтобы на карте можно было играть (а не только отрисовать её рельеф):

[GlobalHeader]
{
    missionname=Metal Heck;
    missiondescription=A small, brutal metal map.;
    planet=metal;
    tidalstrength=0;
    solarstrength=20;
    lavaworld=0;
    killmul=50;
    waterdoesdamage=0;
    minwindspeed=100;
    maxwindspeed=2500;
    gravity=112;
    numplayers=2,4,6,8,10;

    [Schema 0] {
        Type=Network 1;
        aiprofile=DEFAULT;
        SurfaceMetal=10;
        MohoMetal=125;
        HumanMetal=1000;
        ComputerMetal=1000;
        HumanEnergy=1000;
        ComputerEnergy=1000;
        [specials] {
            [special0] { specialwhat=StartPos1; XPos=464; ZPos=216; }
            [special1] { specialwhat=StartPos2; XPos=3408; ZPos=216; }
            ...
        }
    }
}

kbot tnt preview читает соответствующий .ota и рисует пронумерованные метки на каждой стартовой позиции выбранной схемы.

Как игра читает схемы и стартовые позиции (все представления kbot — редактор карт в студии, песочница, обозреватель ресурсов, kbot tnt preview, kbot tnt lint и Quality Checker — читают их одинаково, через игровое представление OTA из kbot-io):

  • Схемы ищутся по имени: Schema 0, Schema 1, … до первого пропущенного номера. Имена сравниваются без учёта регистра ([schema 1] тоже подходит), но номер должен быть записан без украшений: [Schema0] или [Schema 01] не находятся никогда, а схема после пропуска (Schema 0, Schema 1, Schema 3) никогда не читается. SCHEMACOUNT игнорируется.
  • В схватке и сетевой игре схема выбирается по Type и числу стартовых позиций, а не по порядку в файле. Подходят только схемы с Network 1–Network 4 (без учёта регистра), в которых есть хотя бы одна стартовая позиция. Для N игроков игра предпочитает последнюю подходящую схему ровно с N стартовыми позициями, а если такой нет — схему, где их больше всего. Миссия кампании выбирает схему по сложности (Easy, Medium, Hard). numplayers — просто текст, который показывается в лобби (карта загружается и с 2, 4, и с 2-8, и с Any).
  • Стартовые позиции — это записи [specials], у которых specialwhat начинается с StartPos (без учёта регистра). StartPosN — это слот игрока N-1, StartPos0 — тоже слот 0, а запись без номера после StartPos получает следующий номер по своему счёту (первая — 1). XPos и ZPos задаются в пикселях карты и хранятся в 16 битах.
  • У отсутствующих ключей есть значения по умолчанию, и это не нули: без missiondescription показывается «No description available», без maxunits (только в кампаниях) лимит равен 200, а заранее расставленный объект ([features]) без XPos или ZPos пропускается, поэтому объекту в столбце или строке 0 нужен явный 0.

Note

Редактор карт в студии правит .ota карты на месте. При сохранении меняются только отредактированные вами значения (и добавляются или удаляются схемы и стартовые позиции, которые вы добавили или удалили). Всё остальное — ключи условий победы и триггеров, useonlyunits, [units], [features], прочие [specials], дробные значения вроде killmul=0.5, комментарии — записывается обратно как было. Удаление схемы или стартовой позиции переписывает файл в раскладке kbot-io (содержимое то же, комментарии пропадают) и перенумеровывает последующие схемы, чтобы игра по-прежнему их находила. .ota, который kbot не может прочитать, показывается вместе с ошибкой и при сохранении остаётся без изменений, а текст в диалогах, содержащий ;, // или /*, отклоняется. Отклоняется и сохранение, после которого игра начала бы читать схему, которую сейчас пропускает: новая схема получает наименьший свободный номер, поэтому в файле с [Schema 0] и [Schema 2] новая [Schema 1] ввела бы в игру [Schema 2]. В сообщении об ошибке названа секция, которую нужно переименовать или удалить. Дробное значение, слишком большое для хранения (killmul=1e999, которое игра читает как бесконечность), показывается как наибольшее число и остаётся записанным как было, пока вы его не измените. Уровень моря игра берёт из заголовка .tnt. Редактор поддерживает уже существующий ключ sealevel= в соответствии с ним, но никогда не добавляет его сам.


Разбор примера — минимальный юнит

Полный, рабочий «ненастоящий» FBI для стационарной турели:

[UNITINFO]
{
    UnitName=MYTURRET;
    Objectname=myturret;
    Side=ARM;
    Designation=Test Turret;
    Description=Bare-minimum turret for format testing.

    BuildCostMetal=200;
    BuildCostEnergy=400;
    BuildTime=2400;
    MaxDamage=600;

    Category=NOTSUB SURFACE WEAPON NOTAIR;
    TEDClass=LASER;
    Builder=0;
    canattack=1;
    onoffable=0;
    ActivateWhenBuilt=1;

    Weapon1=LIGHTLASER;

    FootprintX=2;
    FootprintZ=2;
    YardMap=cccc;
    MaxSlope=15;
    MaxWaterDepth=0;
    SightDistance=300;

    Corpse=MyTurret_Dead;

    [SOUNDS] {
        select1=corselect1;
        ok1=corok1;
    }
}

Чтобы получилось полноценное дополнение с юнитом, в нём должны быть такие файлы:

mymod/
├── units/myturret.fbi
├── objects3d/myturret.3do
├── scripts/MYTURRET.cob
├── features/corpses/myturret.tdf       # contains [MyTurret_Dead]
└── unitpics/MYTURRET.PCX

…а затем каталог упаковывается в HPI:

kbot hpi pack ./mymod --target myturret.ufo

Подводные камни

Warning

Каждое значение должно заканчиваться на ;. Пропущенная точка с запятой не вызывает ошибки: парсер молча склеивает значение со следующей строкой, и характеристики получаются самые загадочные (MaxDamage=3000, за которым следует незавершённый Description=..., даёт юнит с 30 000 очков прочности и без подсказки).

  • В ключах регистр не важен, в значениях — важен. Side=arm сработает в логике классификации юнитов для ARM, но моды, которые на лету переключают стороны через if (Side == "ARM") со строгим сравнением строк, сломаются.
  • Элементы списков разделяются пробелами (Category=COMMANDER MOBILE WEAPON), а не запятыми. Движок делит значение по любым пробельным символам.
  • Однако в некоторых полях OTA используются запятые: numplayers=2,4,6,8,10. Единого соглашения о разделителе списков нет, а numplayers игра вообще не разбирает — она только показывает этот текст.
  • Формального ограничения глубины у вложенных секций нет, но Cavedog ни разу не выпустила ничего глубже 3 уровней. Редакторы, рассчитанные на 2 уровня, споткнутся на нескольких TDF оружия с вложенностью вида [WEAPON][DAMAGE][category].
  • Логические поля — это целые числа (canmove=1, canstop=0), а не true/false. Движок принимает только 1/0.
  • В файлах .ota то и дело встречаются кракозябры UTF-8 в описаниях миссий (типографские кавычки из Word и т. п.). Движок выводит их в кодовой странице Windows-1252, а всё, что в неё не входит, превращает в «тофу» — пустые прямоугольники.

Типичные размеры

Ресурс Диапазон в материалах Cavedog
FBI юнита 1–4 КБ (Командир: ~3 КБ, лёгкий танк: ~1,5 КБ)
TDF одного объекта 200 Б – 1 КБ
TDF оружия 0,5–3 КБ на секцию [WEAPON]
Файл OTA 1–8 КБ
gamedata/sidedata.tdf ~50 КБ (большую часть занимает раскладка HUD)
gamedata/sound.tdf ~20 КБ
Всего FBI в TA + CC ~250 файлов

Приложение A — словарь полей FBI

Все поля, которые обычно встречаются в units/*.fbi, сгруппированные по назначению. Обозначения в столбце Тип: str — идентификатор/строка, int — целое число, float — число с плавающей точкой, bool — 0/1, list — токены через пробельные символы, enum — небольшое целое с задокументированными значениями.

Поля, которых здесь нет, — либо служебные заметки редактора (UnitNumber, Copyright), либо недокументированные. Неизвестные ключи движок молча игнорирует.

Идентификация и отображение

Поле Тип Примечания
UnitName str Основной ключ поиска. На него ссылаются другие конфигурации, ИИ, OTA, меню строительства.
Side str ARM или CORE (TA), Aramon/Taros/Veruna/Zhon (TA:K). Соответствует секции [SIDE<N>] в gamedata/sidedata.tdf.
Objectname str Базовое имя для 3D-модели .3do, скрипта .cob и портрета unitpics/*.pcx юнита.
Designation str «Код типа», который показывается на панели информации о юните (например, ARM-WM у Командира ARM).
Name str Короткое имя, которое показывается над юнитом.
Description str Текст подсказки на кнопке строительства и на панели информации о юните.
GermanName / FrenchName / SpanishName / ItalianName / JapaneseName / PigLatinName str Локализованные имена. Каждое используется в своей языковой версии игры.
GermanDescription / FrenchDescription / SpanishDescription / ItalianDescription / JapaneseDescription / PigLatinDescription str Локализованный текст подсказки.
Version int Версия схемы, которую ведёт редактор. В оригинальных файлах игры всегда 1 или 2.
UnitNumber int ID, нужный только редактору. Во время игры не учитывается.
Copyright str Строка об авторских правах в свободной форме. Не учитывается.
TEDClass str Классификация в редакторе TAE (KBOT, TANK, COMMANDER, …). Ни на что, кроме внешнего вида, не влияет.

Экономика и строительство

Поле Тип Примечания
BuildCostMetal int Сколько металла нужно на постройку этого юнита.
BuildCostEnergy int Сколько энергии нужно на постройку этого юнита.
BuildTime int Строительная мощность × секунды. Движок делит это значение на WorkerTime строителя и получает реальное время постройки.
WorkerTime int Строительная мощность, которую даёт этот юнит, если он строитель.
EnergyUse int Расход энергии за тик, пока юнит активен.
EnergyMake int Выработка энергии за тик, пока юнит активен.
MetalUse int Расход металла за тик.
MetalMake int Выработка металла за тик.
EnergyStorage int Ёмкость хранилища. У юнитов, которые не являются хранилищами, не задаётся.
MetalStorage int Ёмкость хранилища. У юнитов, которые не являются хранилищами, не задаётся.
MakesMetal int Сколько металла синтезатор металла вырабатывает в секунду, пока он включён и его энергия оплачена. Читается как целое (1.9 — это 1). Это отдельный параметр, не MetalMake, который действует всегда.
ExtractsMetal float Сколько металла экстрактор добывает на единицу металла карты под своей площадью основания, пока он включён и обеспечен энергией.
TidalGenerator bool Выработка энергии этим юнитом зависит от tidalstrength карты.
WindGenerator bool Выработка зависит от диапазона скорости ветра на карте.
Builder bool Может строить другие юниты.
Builddistance int Наибольшая дальность наносборщика в клетках по 16 пикселей.
CanReclamate bool Может утилизировать обломки и объекты.
CanCapture bool Может захватывать вражеские юниты (только командиры).
ActivateWhenBuilt bool По завершении постройки переключатель «активен» по умолчанию включён.
onoffable bool Есть переключатель вкл./выкл., которым может пользоваться игрок.

Бой и живучесть

Поле Тип Примечания
MaxDamage int Очки прочности.
Weapon1 / Weapon2 / Weapon3 str Имена секций оружия в weapons/*.tdf. До 3 видов оружия.
wpri_badTargetCategory list Категории, против которых основное оружие малоэффективно (им понижается приоритет).
wsec_badTargetCategory list То же для вспомогательного оружия.
BadTargetCategory list Цели, которых избегает юнит в целом.
NoChaseCategory list Цели, которые юнит не преследует (стреляет, только если они в радиусе поражения).
canattack bool Может вообще применять оружие.
candgun bool Может стрелять из своего 3-го оружия вручную (D-пушка Командира).
commandfire bool Каждый выстрел производится только по команде игрока.
ExplodeAs str Имя оружия для взрыва при гибели (в weapons/*.tdf).
SelfDestructAs str Имя оружия для взрыва при самоуничтожении.
Corpse str Имя секции [FEATURE] в features/**/*.tdf, которая остаётся обломками.
HealTime int За сколько секунд юнит полностью ремонтируется на ремонтной площадке.
DamageModifier float Множитель входящего урона. <1 — повышенная стойкость.
ImmuneToParalyzer bool Не подвержен действию оружия стазиса.
HideDamage bool Скрывает полосу повреждений от противника.
kamikaze bool Вместо стрельбы взрывается при контакте.
firestandorders bool Есть переключатель постоянного режима огня.
StandingFireOrder enum Режим огня по умолчанию: 0 — не стрелять, 1 — ответный огонь, 2 — свободный огонь. Если ключа нет, это 2. У явного значения сохраняются два младших бита, так что 0 — это действительно «Не стрелять» (Hold Fire).
mobilestandorders bool Есть переключатель постоянного режима движения.
StandingMoveOrder enum Режим движения по умолчанию: 0 — на месте, 1 — манёвр, 2 — свободно. Если ключа нет, это 2. У явного значения сохраняются два младших бита (0 у командиров — это «На месте», Hold Position).
ShootMe bool Подсказка ИИ и компьютерным противникам: стрелять по этому юниту в первую очередь.
Commander bool Отмечает юнит как командира (с его гибелью игра проиграна).

Передвижение

Поле Тип Примечания
MaxVelocity float Максимальная скорость в мировых единицах за тик.
Acceleration float Прирост скорости за тик.
BrakeRate float Потеря скорости за тик при торможении.
TurnRate int Скорость поворота в единицах 2π/65536 за тик.
MaxSlope int Самый крутой склон суши, на который юнит может подняться. По умолчанию 255.
MaxWaterDepth int Наибольшая глубина воды, в которую юнит может войти. 0 — только суша. По умолчанию 10000.
MinWaterDepth int Наименьшая глубина воды (только корабли). По умолчанию -10000.
MovementClass str Имя класса в gamedata/moveinfo.tdf ([CLASS0]–[CLASS31]). Если класс найден, его площадь основания, глубины воды и уклоны заменяют собственные ключи FBI (см. Gamedata).
SteeringMode enum 0/1/2 — поворот на месте, затем движение / движение по дуге / мгновенный поворот.
Upright bool Юнит отрисовывается стоящим вертикально (К-боты) или лежащим по рельефу (техника).
BankScale float Насколько сильно юнит кренится в поворотах (авиация). По умолчанию 1, при явном 0 крена нет вовсе.
PitchScale float Насколько сильно юнит задирает или опускает нос при разгоне.
Scale float Множитель визуального масштаба (1.0 — обычный размер).
CanFly bool Флаг авиации.
crusisealt int Высота крейсерского полёта для летающих юнитов.
attackrunlength int Длина захода на цель у СВВП и бомбардировщиков.
HoverAttack bool При атаке самолёт зависает на месте (штурмовики).
floater bool Держится на поверхности воды.
canmove bool Юнит вообще может двигаться.
canpatrol bool Доступен приказ патрулирования.
canstop bool Доступен приказ остановки.
canguard bool Доступен приказ охраны.
canload bool Может брать на борт перевозимые юниты.
transportsize int Класс размера для проверок при погрузке в транспорт.
transportmaxunits / TransMaxUnits int Вместимость транспорта.
manuverleashlength (а также maneuverleashlength) int Насколько далеко от своей позиции юнит может отходить при маневрировании.
BadSlope int Уклон, на котором движение замедляется, но не блокируется.
BuildAngle int Наибольший уклон, на котором этот юнит можно построить.

Обнаружение

Поле Тип Примечания
SightDistance int Радиус обзора (LOS) в клетках по 16 пикселей.
RadarDistance int Радиус действия радара. 0 — радара нет.
SonarDistance int Радиус действия сонара.
RadarDistanceJam int Радиус, в котором юнит глушит вражеский радар.
Stealth bool Юнит не виден на вражеском радаре.
CloakCost int Расход энергии за тик на маскировку, пока юнит стоит на месте.
CloakCostMoving int Расход энергии за тик на маскировку, пока юнит движется.
mincloakdistance int Маскировка срывается, если противник ближе этого числа клеток.

Меню строительства и площадь основания

Поле Тип Примечания
Bmcode int Код меню строительства. Оставьте 1, если юнит строят другие юниты, и 0 для зданий, которые в меню не появляются.
FootprintX / FootprintZ int Площадь основания в клетках по 16 пикселей. Должна совпадать с площадью основания MovementClass.
YardMap str Многострочная ASCII-сетка (o — открыто, c — закрыто, w — вода, g — геотермальный источник), которая задаёт ограничения для каждой клетки.
ThreeD bool Отрисовывается как 3D-модель. У оригинальных юнитов игры всегда 1.
ZBuffer bool Использовать Z-буфер. Всегда 1.
NoShadow bool Не отрисовывать тень.
NoAutoFire bool Отключить автоматическую стрельбу.
norestrict bool Не соблюдать ограничения запретных зон.
IsAirBase bool Здесь могут садиться и ремонтироваться самолёты.
IsFeature bool Считать статичным объектом, а не юнитом.
Category list Критически важно. Список тегов через пробельные символы, который используют наведение оружия, веса ИИ и меню строительства. Стандартные токены: MOBILE, WEAPON, SURFACE, UNDERWATER, VTOL, KBOT, TANK, SHIP, LEVEL1/LEVEL2/LEVEL3, NOTSUB, NOTAIR, COMMANDER, имена сторон.
WaterLine int Глубина, на которой держится плавающий юнит.
altfromsealevel int Высота самолёта отсчитывается от уровня моря, а не от рельефа.

Звук

Поле Тип Примечания
SoundCategory str Имя секции в gamedata/sound.tdf с голосовыми сэмплами юнита.
[SOUNDS] (вложенная секция) подсекция Переопределения прямо в файле для отдельных событий (canselect=…, select1=… и т. д.).

Прочее и малоизученное

Поле Тип Примечания
DefaultMissionType str Начальное состояние задания (Standby, Move и т. д.).
sortbias int Вес при сортировке в меню строительства.
teleporter bool Помечает юнит как платформу телепортации (Галактические врата).
IsAirBase bool См. «Меню строительства и площадь основания» — повторено для полноты.
Ovradjust bool Включает недокументированное переопределение в движке. Используется только у командира.
ShowPlayerName bool Показывает имя игрока над юнитом (только командир).
MoveRate1 / MoveRate2 int Служебные поля редактора. Во время игры не используются.
antiweapons bool Используется платформами перехвата («Стойкость», ПРО).

Живые примеры в справочном каталоге

Как используются поля, лучше всего видно на настоящих FBI. В справочных репозиториях собраны все юниты, которые есть в игре:

  • TA — все FBI: хорошие «насыщенные» примеры — ARMCOM (командир с Commander=1, CloakCost, MaxDamage=3000), ARMSAM (турель с заполненными Weapon1/2/3), ARMBRAWL (самолёт с CanFly, crusisealt, BankScale), ARMMEX (экстрактор металла с ExtractsMetal).
  • TA — все TDF оружия: [FLAMETHROWER] — для burst/burstrate/firestarter, [NUCLEAR_MISSILE] — для двухфазных управляемых ракет, [LIGHTNING] — для лучевого оружия.
  • TA — дерево строительства объектов и оружия — все регистрации [MENUENTRY] в установке.
  • Юниты TA: Kingdoms — другой набор полей (buildcost= с единственным ресурсом, damagecategory=, встроенные секции [WEAPONn]). Хорошие отправные точки — ARAKING (Элсин, монарх Арамона) и ARAARCH (лучник).

См. также

  • TNT — ссылается на имена объектов, которые указывают на секции TDF [FEATURE].
  • 3DO, COB — на них ссылается Objectname в FBI.
  • GAF — на него ссылаются seqname объекта и explosiongaf оружия.
  • TDF в gamedata — moveinfo.tdf, sound.tdf, sidedata.tdf, на которые ссылаются поля FBI.
  • Звук — как SoundCategory превращается в WAV-файлы.
  • Глоссарий — сторона, площадь основания, yardmap, схема.