Skip to content

Header Record BTL 头部

状态:Authoritative Reference v1

1. 物理结构

BTL Header 固定为 0x80 字节,由连续 32 个 little-endian uint32 物理槽组成:

text
0x00, 0x04, ... , 0x7C

当前 BtlHeaderSchema 已验证 0x00..0x7F 无空洞、无重叠。Header 中的 count、版本、地图尺寸和扩展长度共同决定后续 BTL section 的物理布局。

当前 Header 全字段写入仍为 NoGo 读取语义已确认不等于允许独立改写 count、长度或条件参数。

主要 authority:

text
reconstruction/src/WC4.Runtime.BattleData/BtlHeaderSchema.cs
reconstruction/docs/btl_editor_round34_header_schema_and_roundtrip_contract_report.md
reports/battle_outcome_btl_field_matrix.csv

2. 完整字段表

OffsetSize当前名称当前语义状态
0x004VersionRaw-BTL 版本选择器Confirmed
0x044MapSource地图来源;当前已确认 0=embedded terrain1=external mapConfirmed
0x084MapCutXcropped-map 原点 XConfirmed
0x0C4MapCutYcropped-map 原点 YConfirmed
0x104MapWidth逻辑地图宽度Confirmed
0x144MapHeight逻辑地图高度Confirmed
0x184CountryCountCountry 记录数量Confirmed
0x1C4BuildingCountBuilding 记录数量Confirmed
0x204UnitCountUnit 记录数量;记录长度随版本变化Confirmed
0x244BehaviorCount物理 Behavior / ArmyAIConfig row 数量Confirmed
0x284EventCountEvent 记录数量Confirmed
0x2C4WeatherCountWeather 记录数量Confirmed
0x304VictoryConditionTypeRaw胜负条件 dispatch typeConfirmed
0x344VictoryEvaluationBoundaryRawcondition-dependent 回合/评估边界;不是通用 RoundMinimumConfirmed
0x384VictoryPrimaryParameterRawcondition-dependent 主参数;不是通用 RoundMaximumConfirmed
0x3C4ReinforcementCountReinforcement 数量;记录长度随版本变化Confirmed
0x404AirstrikeCountAirstrike 数量Confirmed
0x444StartGroupACountStart Group A 物理记录数量;完整玩法语义仍开放Confirmed physical / Partial semantic
0x484StartGroupBCountStart Group B 物理记录数量;完整玩法语义仍开放Confirmed physical / Partial semantic
0x4C4FlagCountFlag / capital Tile 记录数量Confirmed
0x504Header50Rawlow16 已确认是 signed BattleAge;bit16 有独立物理变化但语义未知Partial
0x544VersionDependentExtensionLengthRawv3+ 为 protobuf ExtensionArea 字节长度;v1/v2 不按该规则消费 tailConfirmed version-dependent
0x584AlignedTileSlotCountProvince/Owner 平行数组对齐 slot 数Confirmed
0x5C4VictoryParameter1Raw条件参数 1;不同 victory type 含义不同Confirmed physical / Partial per-type semantic
0x604VictoryParameter2Raw条件参数 2Confirmed physical / Partial per-type semantic
0x644VictoryParameter3Raw条件参数 3Confirmed physical / Partial per-type semantic
0x684MineCountMine / independent object 记录数量Confirmed
0x6C4InitialCountryStrategyOverrideCount0x08 字节开局国家 strategy override 记录数量Confirmed physical+consumer / UnknownNoPositiveCorpus values
0x704StrategyCountCountry strategy schedule 记录数量Confirmed
0x744Header74Raw原版复制,完整 consumer/语义未闭合Unknown
0x784Header78Raw原版复制,完整 consumer/语义未闭合Unknown
0x7C4AirSupportCountAir Support 记录数量Confirmed

3. 0x30/0x34/0x38/0x5C/0x60/0x64 胜负条件参数

旧字段名曾把其中一些字段全局解释成:

text
RoundMinimum
RoundMaximum
resource_economy
resource_industry
resource_technology

原版 FUN_0033CB00 证明这些解释都不能无条件推广到所有 victory type。

当前安全模型:

text
H30 = VictoryConditionTypeRaw
H34 = VictoryEvaluationBoundaryRaw
H38 = VictoryPrimaryParameterRaw
H5C = VictoryParameter1Raw
H60 = VictoryParameter2Raw
H64 = VictoryParameter3Raw

其中:

  • H34 是核心 round/evaluation boundary,原版存在 GameRound > H34 类比较,因此旧名 RoundMinimum 被否定;
  • H38 在不同 condition type 下可以是 target、quota、comparison baseline 或 scoring operand,不能叫统一 RoundMaximum
  • H5C/H60/H64 在三资源条件分支中确实分别充当三个资源 threshold,但其他 condition type 会复用这些槽位做不同参数。

H30 当前 corpus 分布

当前 1358 个 BTL:

text
0=776   1=105   2=94    3=50
4=3     5=9     6=1     7=62
8=69    9=8     10=19   11=12
12=0    13=0    14=122  15=13
16=15

这是原版 1.28.0 的观察分布,不代表其他版本不能出现其他值。

主要证据:reports/battle_outcome_btl_field_matrix.csv

4. 0x50:复合 32 位字段

原版 loader 复制完整 32 位 H50,并明确执行:

text
BattleAge <- signed int16(H50[15:0])

所以:

text
H50[15:0] = signed BattleAge consumer        Confirmed
H50 bit16 = independent physical variation  Confirmed physical / Unknown semantic
others    = current corpus unobserved        Unknown
whole     = raw preservation                 Confirmed
write     = NoGo

当前 1358 个 BTL 只出现四种完整值:

H50文件数
0x00000000978
0x00000001333
0x0001000040
0x000100017

bit0 与 bit16 四种组合均存在,说明不能把高 16 位简单清零或当 padding。

详细证据:reconstruction/docs/btl_editor_round37_header50_bitfield_evidence_recovery_report.md

5. 0x54:版本相关 ExtensionArea 长度

v3+:

text
H54 bytes
-> protobuf MessageLite::ParseFromArray
-> BattleExArgs ExtensionArea

当前 corpus 有 407 个非空 tail,407/407 wire parse 成功。

v1/v2 不能把 H54 无条件解释为同一个可消费 tail 长度,因此字段正式名称保留 VersionDependentExtensionLengthRaw

6. 0x58:不是 selectable tile count

当前 1358/1358 原版 BTL:

text
H58 == align_up(MapWidth * MapHeight, 8)

真实地图 cell 数仍是:

text
MapWidth * MapHeight

H58 用于 Province uint16 与 Owner uint8 两个平行数组的物理 slot 数和对齐。

社区旧称 selectable tile countRefuted

7. 0x6C:Initial Country Strategy Override count

后续 native consumer 已把旧 unknown count 闭合为:

text
H6C = InitialCountryStrategyOverrideRecord count
record size = 0x08

record +0x00 int32 countryId
record +0x04 int32 strategyRowId

加载链:

text
countryId
-> Country lookup
-> Country strategy container
-> FUN_004A7DF4
-> opening strategy override

但当前 1.28.01358/1358 BTL 都是:

text
H6C == 0

所以 record 物理结构和 consumer 已 Confirmed,合法正值域、重复覆盖和部分错误引用行为仍是 UnknownNoPositiveCorpus

详细证据:reconstruction/docs/btl_editor_round38_unknown_compatibility_record_semantics_recovery_report.md

8. 0x74/0x78

当前两字段仍保持 raw:

text
Header74Raw
Header78Raw

当前 1.28.0 corpus 中观察为零不能证明它们是 padding,也不能授权删除、规范化或重新利用。

9. 写入边界

当前 BtlHeaderSchema32/32 Header 槽全部设置:

text
WriteStatus = NoGo

原因包括:

  • count 会改变后续 section 布局;
  • H54 改变 tail 边界;
  • victory 参数需要 type-dependent 不变量;
  • H50/H74/H78 仍含未知语义;
  • H6C 正记录无当前原版 corpus。

因此 Header Reference 当前是读取/研究 authority,不是 Header writer 规范。