Skip to content

BTL 文件布局

1. 当前物理格式结论

原版 loader 先读取固定 0x80 字节 Header,再依据 Header 中的 count、版本和地图来源依次切分后续 section。当前 1.28.0 原版 corpus 的 1358 个 BTL 均满足已恢复的完整长度方程,zero-byte delta。

该结论是物理格式结论,不代表每个 section 内所有字段的玩法语义都已闭合。

2. 固定 section 顺序

顺序SectionCount 来源单条长度
1Header固定 10x80
2CountryH180x12C
3Embedded TerrainMapSource == 0width * height0x10
4Province SlotH580x02
5Tile Owner SlotH580x01
6BuildingH1C0x20
7UnitH20v1 0x30;v2/v3 0x40
8MineH680x0C
9Behavior / ArmyAIConfig EntryH240x10
10WeatherH2C0x10
11EventH280x2C
12ReinforcementH3Cv1 0x50;v2/v3 0x68
13AirstrikeH400x14
14Start Group AH440x08
15Start Group BH480x08
16Flag / CapitalH4C0x04
17Initial Country Strategy OverrideH6C0x08
18Country Strategy ScheduleH700x10
19Air SupportH7C0x10
20ExtensionAreav3+ H54 字节byte stream

证据入口:reports/btl_v1280_so_recovery.md

3. Header H58

H58 不是社区旧文档所称的“可选择地块数量”。

在当前 1358/1358 原版 BTL 中:

text
H58 == align_up(width * height, 8)

原版实际地图 cell 仍由 width * height 决定;H58 用于后续 Province 与 Tile Owner 平行数组的对齐 slot 数。

当前状态:Confirmed

4. Header H54

H54 是版本相关字段:

  • v3+:原版 parser 将其作为 ExtensionArea 的 protobuf 字节长度,并调用 ParseFromArray
  • v1/v2:不能无条件赋予相同全局语义。

当前 407 个非空 v3 ExtensionArea 样本均成功按 protobuf wire 解析。

当前状态:物理用途 Confirmed,完整 Extension 语义 Partial

5. Header H6C

H6CInitialCountryStrategyOverrideRecord 数量;每条记录 0x08

text
+0x00 int32 countryId
+0x04 int32 strategyRowId

原版 consumer 将记录写入国家 strategy 的开局覆盖容器。

当前 1.28.0 corpus 中 H6C == 01358/1358,因此布局与 consumer 已确认,但正记录值域和部分异常边界属于 UnknownNoPositiveCorpus

证据入口:reconstruction/docs/btl_editor_round38_unknown_compatibility_record_semantics_recovery_report.md

6. 版本统计

当前 1.28.0 corpus:

BTL 版本文件数
v1439
v225
v3894
合计1358

地图来源:

MapSource文件数当前解释
01049BTL 内嵌 terrain
1309使用外部 world.bin 地图来源

其他 MapSource 值的容量和行为不能由当前 corpus 推断,保持 Unknown

7. Round-trip 边界

当前 raw-first parser/writer 基线已经证明:

  • 完整文件包络可以精确切分;
  • 未修改 BTL 可以 byte-identical round-trip;
  • ExtensionArea、未知字节和现有 section 布局可以原样保存;
  • 这不等价于任意结构修改或未知字段写入已经安全。

结构增删、count/length 联动、未知字段规范化和任意 Extension 重建仍必须遵守独立 writer 门禁。