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
}
}
[MENUENTRY] — расширение меню строительства
Файлы 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, схема.