All format pages ↓
Units, scripts, configs

TDF / FBI / OTA — Text Configuration Files

From coreprime/kbot @ 0ab97bf · Edit on GitHub

TDF ("Text Data File"), FBI ("Feature/Building/Item"), and OTA ("Online Total Annihilation") files all share the same INI-like text format. They are the canonical way Cavedog declared anything that wasn't binary — unit stats, weapon parameters, feature definitions, mission metadata, sound categories, AI hints.

Extension Where you'll find it Examples
.fbi units/ ARMCOM.FBI, CORRAID.FBI — unit definitions
.tdf features/, weapons/, sounds/, gamedata/, etc. armflak_weapon.tdf, treeb.tdf
.ota maps/ metal heck.ota — map metadata, start positions, AI brief

These files are plain ASCII; you can open one in any text editor.

Tip

Try it yourself.

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

See the CLI kbot mount reference for terminal-browser usage and flatten options.

From Go. Use 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"))

Syntax

A TDF file is a tree of sections. Each section has a name in square brackets, then a { ... } body containing key=value pairs and/or nested sections.

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

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

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

Rules:

  • Section names are in square brackets; everything that follows until the matching } belongs to that section. A section may sit on one line ([special0] { specialwhat=StartPos1; XPos=464; ZPos=216; }).
  • A value runs from the = to the next ;, across line breaks: nothing else ends it, so braces, brackets and = inside a value are plain text, and a value can never contain a ;. Spaces, tabs and line breaks at either end of a key or value are trimmed. A key assigned twice keeps its last value.
  • Keys are case-insensitive. UnitName, unitname and UNITNAME all refer to the same field; tools commonly canonicalise to lowercase on read. Section names are compared ignoring case too.
  • Values are strings by default. Numbers are read the C way, from the leading digits: 12abc reads as 12 and 56.8 as 56 where the game wants a whole number (fields such as killmul and tidalstrength are read as fractions). Lists are space-separated (e.g. Category=NOTSUB COMMANDER NOTAIR ...).
  • Comments are blanked out before anything else is read: // to the end of the line, and /* ... */ blocks, which may span lines. So missiondescription=See http://tauniverse.com; loses everything from // onwards, including its ;, and the value runs on into the next line. kbot refuses to write a value containing ;, // or /*.
  • Whitespace and blank lines are ignored.

Nested sections (like [SOUNDS] inside [UNITINFO] above) are common in FBI/OTA. The TDF spec doesn't fix a maximum depth; in practice you won't see more than 3.


FBI — unit definitions

An FBI is the engine's complete view of a unit. It pulls the unit's 3D model, the script, the weapon list, the sound bank, build costs, and combat behaviour together in one place. A trimmed Arm Commander example:

[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;
        ...
    }
}

The 1998 community FBI guide (preserved in this repo's source materials) documents over a hundred fields. Most are self-explanatory; the non-obvious ones tend to be:

Field What it really controls
Bmcode Build-menu page code — leave at 1 for normal units.
Category Space-separated tag list used by weapon BadTargetCategory, NoChaseCategory, AI, and the build menus.
MovementClass References a class in gamedata/movinfo.tdf defining acceptable terrain slopes, water depth, etc.
YardMap ASCII picture (e.g. oooo\noooo\n) declaring the unit's footprint and water/land restrictions per cell.
Corpse Name of a [FEATURE] (see below) used as the wreckage drop.
SoundCategory Picks the audio bank in gamedata/sound.tdf.
TEDClass Hint to the Cavedog editor; ignored at runtime.

Important

UnitName is the lookup key everywhere else — the OTA references it, the AI references it, the build menu references it. If you rename an FBI you have to grep the entire mod for references.


TDF — feature, weapon, sound definitions

features/**/*.tdf files contain [FEATURE] sections, one per static map prop. The TNT format (TNT) references these by section name:

[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 follow the same pattern, with [WEAPON_NAME] sections. The FBI's Weapon1=COMMANDER_WEAPON field resolves to the [COMMANDER_WEAPON] section in some TDF in weapons/, through the game's ID-indexed weapon table: each section needs an ID= in 0–255, a later section with the same ID replaces an earlier one, and a name resolves to the lowest slot holding it (see Gamedata: the weapon table). The community weapons guide documents about 60 distinct fields; the meaty ones are ballistic/lineofsight/dropped (the weapon archetype), weapontimer, weaponvelocity, areaofeffect, edgeeffectiveness, burst/burstrate, and the [DAMAGE] sub-section (per-category damage modifiers).

[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
    }
}

Files in download/*.tdf register a unit with the build menus of one or more constructors without modifying sidedata.tdf. This is the mechanism Cavedog's Core Contingency expansion uses to add its units, and the convention every single-unit .ufo add-on follows.

[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;
}
Field Type Meaning
UNITMENU str UnitName of the constructor unit whose menu we're adding to.
MENU int Build-menu page number. 1–2 are reserved by Cavedog for stock units; community convention is to start at 3.
BUTTON int Slot within the page (0–5, laid out as a 2-column × 3-row grid: 0=top-left, 1=top-right, 2=mid-left, 3=mid-right, 4=bottom-left, 5=bottom-right).
UNITNAME str The unit being added — must match the UnitName= in your unit's FBI.

File-naming convention. The file is conventionally download/<UNITNAME>.tdf (matching the UNITNAME= of the first entry), but the engine reads every *.tdf in download/, so the filename is purely a hint to the modder. One unit per file is the norm.

Multiple entries. A single file can hold several entries — Cavedog's download/Armfort.tdf uses three to make the Arm Fortification Wall buildable from ACK, ACV, and ACA. TA 3.1c reads the first five sections of each file, whatever their names ([MENUENTRY1] is the convention, [ENTRY0] works as well); a sixth section is never read. An entry whose UNITMENU names no unit, or no unit with Builder=1, is ignored, as is one whose UNITNAME names no unit. MENU and BUTTON are kept to 8 bits, and a builder's menu — its [CANBUILD] list plus the download additions — holds at most 31 units.

Important

download/*.tdf adds to the build menu; it doesn't replace anything. If the slot you pick collides with an existing entry, the engine's behaviour is unpredictable — usually the later-loaded entry wins, but .ufo load order isn't guaranteed across platforms. Pick a high MENU page (4 or 5) for mods meant to coexist.

This is the additive mod hook that lets you ship a single .ufo without forking the 50 KB sidedata.tdf. See the modding tutorial for end-to-end usage.


OTA — map metadata

.ota ships alongside every .tnt and carries everything the engine needs to play the map (as opposed to render its terrain):

[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 reads the matching .ota and draws numbered markers at each start position of the chosen schema.

How the game reads the schemas and start positions (every kbot view — the studio map editor, the sandbox, the asset explorer, kbot tnt preview, kbot tnt lint and the Quality Checker — reads them the same way, through kbot-io's OTA game view):

  • Schemas are found by name, Schema 0, Schema 1, … up to the first missing number. Names are compared ignoring case ([schema 1] counts), but the number must be written plainly: [Schema0] or [Schema 01] is never found, and a schema after a gap (Schema 0, Schema 1, Schema 3) is never read. SCHEMACOUNT is ignored.
  • Skirmish and multiplayer games pick a schema by Type and start count, not by position. Only Network 1 to Network 4 schemas (compared ignoring case) with at least one start position qualify. For N players the game prefers the last qualifying schema with exactly N start positions, otherwise the one with the most. A campaign mission picks by difficulty (Easy, Medium, Hard). numplayers is only text shown in the lobby (2, 4, 2-8 and Any all load).
  • Start positions are the [specials] entries whose specialwhat starts with StartPos (ignoring case). StartPosN is player slot N-1, StartPos0 is slot 0 too, and an entry with no number after StartPos takes the next number of its own (the first is 1). XPos and ZPos are map pixels, kept to 16 bits.
  • Missing keys have defaults, not zeros: a missing missiondescription shows "No description available", a missing maxunits (campaigns only) means 200, and a pre-placed feature ([features]) with no XPos or ZPos is skipped, so one at column or row 0 needs an explicit 0.

Note

The studio map editor edits a map's .ota in place. Saving changes only the values you edited (and adds or removes the schemas and start positions you added or removed); everything else — victory and trigger keys, useonlyunits, [units], [features], other [specials], fractions such as killmul=0.5, comments — is written back as it was. Removing a schema or a start position rewrites the file in kbot-io's layout (same content, comments dropped) and renumbers later schemas so the game still finds them. An .ota kbot cannot read is shown with its error and left unchanged on save, and dialog text containing ;, // or /* is refused. So is a save that would make the game read a schema it skips now: adding a schema takes the lowest free number, so in a file with [Schema 0] and [Schema 2] the new [Schema 1] would bring [Schema 2] into play; the error names the section to rename or remove. A fraction too large to hold (killmul=1e999, which the game reads as infinity) shows as the largest number and is kept as written unless you change it. The game takes the sea level from the .tnt header; the editor keeps an existing sealevel= key in step but never adds one.


Worked example — minimal unit

A complete, working "fake" FBI for a stationary turret:

[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;
    }
}

To make this a complete unit add-on you'd ship:

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

…then HPI-pack the directory:

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

Gotchas

Warning

Every value must end with ;. A missing semicolon doesn't error — the parser silently merges the value with the next line, producing baffling stats (a MaxDamage=3000 followed by an unterminated Description=... produces a unit with 30,000 hit points and no tooltip).

  • Keys are case-insensitive, values are not. Side=arm will match unit-classification logic for ARM, but mods that switch sides on the fly with if (Side == "ARM") against string-equality lookups will break.
  • List values are space-separated (Category=COMMANDER MOBILE WEAPON) — not comma-separated. The engine splits on any whitespace.
  • Some OTA fields use commas, however: numplayers=2,4,6,8,10. There isn't a single list-delimiter convention, and the game never parses numplayers at all — it only shows the text.
  • Nested sections have no formal depth limit, but Cavedog never shipped anything more than 3 deep. Editors that assume 2-deep will fail on a handful of weapon TDFs with [WEAPON][DAMAGE][category]- style nesting.
  • Boolean fields are integers (canmove=1, canstop=0), not true/false. The engine accepts 1/0 only.
  • .ota files routinely have UTF-8 mojibake in mission descriptions (smart-quotes from Word, etc.). The engine renders them with the Windows-1252 codepage and will tofu anything outside it.

Typical sizes

Asset Range observed in Cavedog content
Unit FBI 1–4 KB (commander: ~3 KB; light tank: ~1.5 KB)
Single-feature TDF 200 B – 1 KB
Weapon TDF 0.5–3 KB per [WEAPON] section
OTA file 1–8 KB
gamedata/sidedata.tdf ~50 KB (HUD layout dominates)
gamedata/sound.tdf ~20 KB
Total FBIs in TA + CC ~250 files

Appendix A — FBI field dictionary

Every field commonly found in units/*.fbi. Grouped by purpose. Type column key: str = identifier/string; int = integer; float = float; bool = 0/1; list = whitespace-separated tokens; enum = small integer with documented meanings.

Fields not listed here are either editor scratch (UnitNumber, Copyright) or undocumented. The engine ignores unknown keys silently.

Identity & display

Field Type Notes
UnitName str Primary lookup key. Referenced by other configs, the AI, OTA, build menus.
Side str ARM or CORE (TA), Aramon/Taros/Veruna/Zhon (TA:K). Matches a [SIDE<N>] in gamedata/sidedata.tdf.
Objectname str Base name for the unit's .3do mesh, .cob script, and unitpics/*.pcx portrait.
Designation str The "type code" displayed in the unit info panel (e.g. ARM-WM for the Arm commander).
Name str Short display name shown over the unit.
Description str Tooltip text shown on the build button and unit info panel.
GermanName / FrenchName / SpanishName / ItalianName / JapaneseName / PigLatinName str Localised names. Used per shipped locale.
GermanDescription / FrenchDescription / SpanishDescription / ItalianDescription / JapaneseDescription / PigLatinDescription str Localised tooltip text.
Version int Editor-tracked schema version. Always 1 or 2 in retail content.
UnitNumber int Editor-only ID. Ignored at runtime.
Copyright str Free-form copyright string. Ignored.
TEDClass str TAE editor classification (KBOT, TANK, COMMANDER, …). Cosmetic only.

Economy & construction

Field Type Notes
BuildCostMetal int Metal required to build this unit.
BuildCostEnergy int Energy required to build this unit.
BuildTime int Build-power × seconds. The engine divides by the constructor's WorkerTime to get real-world build time.
WorkerTime int Build-power emitted by this unit when it's a constructor.
EnergyUse int Energy drained per tick when active.
EnergyMake int Energy produced per tick when active.
MetalUse int Metal drained per tick.
MetalMake int Metal produced per tick.
EnergyStorage int Storage capacity. Blank for non-storage units.
MetalStorage int Storage capacity. Blank for non-storage units.
MakesMetal int Metal a metal maker converts per second while it is on and its energy is paid; read as a whole number (1.9 is 1). Separate from MetalMake, which is always on.
ExtractsMetal float Metal an extractor yields per unit of map metal under its footprint, while it is on and powered.
TidalGenerator bool This unit's energy output scales with the map's tidalstrength.
WindGenerator bool Output scales with the map's wind speed range.
Builder bool Can build other units.
Builddistance int Maximum nano-lathe distance, in 16-px cells.
CanReclamate bool Can reclaim wreckage/features.
CanCapture bool Can capture enemy units (commanders only).
ActivateWhenBuilt bool Defaults the "active" toggle to on when construction completes.
onoffable bool Has an on/off toggle the player can flip.

Combat & survivability

Field Type Notes
MaxDamage int Hit points.
Weapon1 / Weapon2 / Weapon3 str Names of weapon sections in weapons/*.tdf. Up to 3 weapons.
wpri_badTargetCategory list Categories the primary weapon does poorly against (deprioritised).
wsec_badTargetCategory list Same for secondary weapon.
BadTargetCategory list Targets the unit as a whole avoids.
NoChaseCategory list Targets the unit won't pursue (will fire only if in range).
canattack bool Can fire weapons at all.
candgun bool Can fire its 3rd weapon manually (the Commander's D-gun).
commandfire bool Forces every shot to be player-initiated.
ExplodeAs str Weapon name for the on-death explosion (in weapons/*.tdf).
SelfDestructAs str Weapon name for the self-destruct explosion.
Corpse str [FEATURE] section name in features/**/*.tdf for the wreckage drop.
HealTime int Seconds to fully heal at a repair pad.
DamageModifier float Multiplier applied to incoming damage. <1 = resistant.
ImmuneToParalyzer bool Ignores stasis weapons.
HideDamage bool Hides the damage bar from the enemy.
kamikaze bool Detonates on contact instead of firing.
firestandorders bool Has the standing-fire-order toggle.
StandingFireOrder enum Default fire stance: 0 = hold, 1 = return, 2 = at will. A missing key is 2; an explicit value keeps its low two bits, so 0 really is Hold Fire.
mobilestandorders bool Has the standing-move-order toggle.
StandingMoveOrder enum Default move stance: 0 = hold, 1 = manoeuvre, 2 = roam. A missing key is 2; an explicit value keeps its low two bits (the commanders' 0 is Hold Position).
ShootMe bool Hint to AI/computer opponents: prioritise targeting this unit.
Commander bool Marks this as a commander unit (loses game when killed).

Movement

Field Type Notes
MaxVelocity float Top speed in world units per tick.
Acceleration float Speed gained per tick.
BrakeRate float Speed lost per tick when stopping.
TurnRate int Rotation speed in 2π/65536 units per tick.
MaxSlope int Steepest land slope the unit can climb. Default 255.
MaxWaterDepth int Deepest water the unit can enter. 0 = strictly land; default 10000.
MinWaterDepth int Minimum water depth (boats only). Default -10000.
MovementClass str Class name in gamedata/moveinfo.tdf ([CLASS0]–[CLASS31]). When it resolves, the class's footprint, water depths and slopes replace the FBI's own keys (see Gamedata).
SteeringMode enum 0/1/2 — turn-then-move vs. arc vs. instant.
Upright bool Renders the unit standing (kbots) or flat (vehicles).
BankScale float How aggressively the unit rolls when turning (aircraft). Default 1; an explicit 0 never banks.
PitchScale float How aggressively the unit pitches when accelerating.
Scale float Visual scale multiplier (1.0 = normal).
CanFly bool Aircraft flag.
crusisealt int Cruise altitude for fliers.
attackrunlength int Distance for VTOL/bomber strafe runs.
HoverAttack bool Aircraft hovers while attacking (gunships).
floater bool Floats on water surface.
canmove bool The unit can move at all.
canpatrol bool Patrol order is enabled.
canstop bool Stop order is enabled.
canguard bool Guard order is enabled.
canload bool Can load transported units.
transportsize int Size class for transport-load checks.
transportmaxunits / TransMaxUnits int Capacity for transport units.
manuverleashlength (also maneuverleashlength) int How far from its standing position the unit will manoeuvre.
BadSlope int Slope at which movement slows but isn't blocked.
BuildAngle int Maximum slope on which this unit can be built.

Senses

Field Type Notes
SightDistance int LOS radius in 16-px cells.
RadarDistance int Radar coverage radius. 0 = no radar.
SonarDistance int Sonar coverage radius.
RadarDistanceJam int Radius the unit jams enemy radar.
Stealth bool Unit doesn't appear on enemy radar.
CloakCost int Energy per tick to remain cloaked while stationary.
CloakCostMoving int Energy per tick to remain cloaked while moving.
mincloakdistance int Cloak fails when an enemy is within this many cells.

Build menu & footprint

Field Type Notes
Bmcode int Build-menu code. Leave at 1 for unit-buildable; 0 for buildings that don't appear.
FootprintX / FootprintZ int Footprint in 16-px cells. Must match the MovementClass footprint.
YardMap str Multi-line ASCII grid (o=open, c=closed, w=water, g=geothermal) defining per-cell restrictions.
ThreeD bool Renders as a 3D model. Always 1 for retail units.
ZBuffer bool Use Z-buffering. Always 1.
NoShadow bool Skip shadow rendering.
NoAutoFire bool Disable automatic firing.
norestrict bool Skip restricted-zone enforcement.
IsAirBase bool Aircraft can land/repair here.
IsFeature bool Treat as a static feature, not a unit.
Category list Critical. Whitespace-separated tag list used by weapon targeting, AI weights, build menus. Standard tokens: MOBILE, WEAPON, SURFACE, UNDERWATER, VTOL, KBOT, TANK, SHIP, LEVEL1/LEVEL2/LEVEL3, NOTSUB, NOTAIR, COMMANDER, side names.
WaterLine int Depth at which a floating unit settles.
altfromsealevel int Aircraft altitude is measured from sealevel, not terrain.

Audio

Field Type Notes
SoundCategory str Name of a section in gamedata/sound.tdf providing the unit's voice samples.
[SOUNDS] (nested section) sub-section Inline overrides for specific events (canselect=…, select1=…, etc.).

Misc / poorly-understood

Field Type Notes
DefaultMissionType str Initial mission state (Standby, Move, etc.).
sortbias int Sorting weight in the build menu.
teleporter bool Marks as a teleport platform (Galactic Gate).
IsAirBase bool See "Build menu & footprint" — duplicated for completeness.
Ovradjust bool Triggers an undocumented engine override; only the commander uses it.
ShowPlayerName bool Shows the player's name above the unit (commander only).
MoveRate1 / MoveRate2 int Editor scratch. Not used at runtime.
antiweapons bool Used by anti-weapon platforms (Fortitude, anti-nuke).

Live examples in the reference catalogue

Field usage is best learned from real FBIs. The reference repos catalogue every shipped unit:

  • TA — every FBI: good "rich" examples are ARMCOM (commander with Commander=1, CloakCost, MaxDamage=3000), ARMSAM (turret with Weapon1/2/3 filled), ARMBRAWL (aircraft with CanFly, crusisealt, BankScale), ARMMEX (metal extractor with ExtractsMetal).
  • TA — every weapon TDF: [FLAMETHROWER] for burst/burstrate/firestarter, [NUCLEAR_MISSILE] for two-phase guided missiles, [LIGHTNING] for a beam weapon.
  • TA — feature & weapon build-tree — every [MENUENTRY] registration in the install.
  • TA: Kingdoms units — the different field set (buildcost= single resource, damagecategory=, inline [WEAPONn]). ARAKING (Aramon's monarch Elsin) and ARAARCH (Archer) are good entry-points.

See also

  • TNT — references feature names that resolve to [FEATURE] TDF sections.
  • 3DO, COB — referenced from FBI Objectname.
  • GAF — referenced from feature seqname and weapon explosiongaf.
  • Gamedata TDFs — moveinfo.tdf, sound.tdf, sidedata.tdf referenced from FBI fields.
  • Sound — how SoundCategory resolves to WAV files.
  • Glossary — side, footprint, yardmap, schema.