I was looking through the tech file parsing code in Outpost 2 and thought I'd note the following things:
[list]
[li]There is a max of 256 techs. (Static buffer limit, unchecked)[/li]
[li]There is a per tech max of 32 REQUIRED_TECH tags. (Static buffer limit, unchecked)[/li]
[li]There is a per tech max of 32 upgrade tags (UNIT_PROP, PLAYER_PROP, FUNCTION_RESULT). (Static buffer limit, unchecked)[/li]
[li]Quoted strings have embedded newline and tab characters stripped. (Allows formatting in tech file)[/li]
[li]Quoted strings must fit within a tag specific static buffer limit. (Excludes tabs and newlines, string will be null terminated).[/li]
[li]Tech name must not exceed 100 characters. (Static buffer size 101 bytes)[/li]
[li]Tech teaser, description, and improvement description must not exceed 800 characters. (Static buffer size 801 bytes)[/li]
[li]Numbers can take an optional leading minus sign. (No positive sign allowed)[/li]
[li]Numbers must fit in a static buffer of 32 bytes, including the leading sign. (Static buffer, checked, Parse error)[/li]
[li]Numbers must be representable as a 32-bit signed integer. (Unchecked, Undefined behaviour)[/li]
[li]The techLevel = techNum / 1000, must not be 0. (Checked, Parse error)[/li]
[li]The techId (and techLevel) should not be negative. (Unexpected values)[/li]
[li]The armour (level) property must be set from 0..5 (inclusive). (Unchecked, Undefined behaviour)[/li]
[li]The game supports 4..18 (inclusive) max scientists on a research topic. (Unchecked, Undefined behaiour)[/li]
[li]The game sets MAX_SCIENTISTS to 1 for the Tiger speed modification in multitek.txt. (Avoids undefined behaviour by not researching in a lab)[/li]
[li]The game sets MAX_SCIENTISTS to 1 for Children's Module and Evacation Module in edentek.txt and ply_tek.txt. (Avoids undefined behaviour by not researching in a lab)[/li]
[li]The game sets MAX_SCIENTISTS to 1 for 5 techs in tutortek.txt. (Avoids undefined behaviour by not researching in a lab)[/li]
[li]The lab value should only be set to 1 = BasicLab, 2 = StandardLab, 3 = AdvancedLab. (Unchecked, Unexpected values)[/li]
[li]The lab value is typically not set for free and disabled techs. (Convention for built in techs)[/li]
[li]Either COST is present, or both EDEN_COST and PLYMOUTH_COST are present. (Unchecked, possibly undefined behaviour)[/li]
[li]The COST values should either be -1 (disabled), 0 (free), or a positive value. (Unchecked, possibly undefined behaviour)[/li]
[li]Each BEGIN_TECH must be paired with END_TECH. All other tags are optional. (Checked, Parse error)[/li]
[li]Single value tags will overwrite their previous values if used more than once. (Unchecked, excludes REQUIRES, UNIT_PROP, PLAYER_PROP, and FUNCTION_RESULT)[/li]
[li]Every tech typically specifies at least CATEGORY and COST. (Convention for built in techs)[/li]
[li]The REQUIRES tag should specify a valid techID. (Unchecked, possibly undefined behaviour)[/li]
[li]The PLAYER_PROP, and FUNCTION_RESULT tags are not used by the standard tech tree files, and are basically useless.[/li]
[/list]


There are 4 main components the parser deals with:
Comments: Starts with a ";" and runs until the next newline character
Tokens  : An un-quoted sequence of characters (generally uppercase by convention) and underscore
Strings : A quoted sequence of characters (tabs and newlines are stripped)
Integers: An optional minus sign followed by a sequence of digits


The parser scans for the following tokens and parameters:
[code]
BEGIN_TECH      string:techName    int:techId
CATEGORY        int:category
DESCRIPTION     string:description
TEASER          string:teaser
IMPROVE_DESC    string:improveDesc
REQUIRES        int:requiredTechId
COST            int:cost    [edenCost = plymouthCost]
EDEN_COST       int:cost
PLYMOUTH_COST   int:cost
MAX_SCIENTISTS  int:maxScientists  [4..18]
LAB             int:lab     [1 = Basic, 2 = Standard, 3 = Advanced]
PLAYER_PROP     token:propName    int:newPropVaue
FUNCTION_RESULT token:propName    int:funcParam    [__fastcall func(int playerNum, int funcParam)]
UNIT_PROP       token:unitTypeName    token:propName    int:newPropValue
END_TECH
[/code]


The following property tokens are supported:
[code]
UNIT_PROP:
	Hit_Points        [Units, but generally Vehicles]
	Armor             [Units, but specifically: GuardTower, Lynx, Panther]
	Production_Capactity  [Buildings, both factory build rates, and capacity for others]
	Move_Speed        [Vehicles]
	Sight_Range       [Units, but specifically: LightTower, GuardTower, Weapons]
	Rate_Of_Fire      [Weapons]
	Build_Time        [Not used in standard tech files]
	Power_Required    [Buildings, but specifically: GORF, Smelter, Rare Smelter]
	Storage_Capacity  [Specifically: University train rate]
	Storage_Bays      [Not used in standard tech files]
	Production_Rate   [Vehicles, mostly colony building and repair]
	Concussion_Damage [Weapons]
	Penetration_Damage  [Weapons]
	Improved          [Unit specific: Mine, RareMine, Smelter, RareSmelter, GORF, Observatory]
	Workers_Required  [Buildings, but specifically: DIRT]
	Common_Required   [Units, but generally vehicles]
	Rare_Required     [Units, but generally vehicles]
	Turn_Rate         [Not used in standard tech files]
	Build_Points      [Not used in standard tech files]
PLAYER_PROP:
	Ore
FUNCTION_RESULT:
	Test_Function
[/code]


The PLAYER_PROP and FUNCTION_RESULT tags quite are useless. The standard tech tree files don't use either of these two tags. The PLAYER_PROP can set the Ore (common) for a player as a research result. Note that it sets the ore, not adds the ore. I don't see a whole lot of use for it. The Test_Function which is called is just a no-op, and no other functions are available, making FUNCTION_RESULT quite pointless.
