Skip to content

Reinforcement Record 增援记录

状态:Authoritative Reference v1

1. 记录版本

Reinforcement 有两种磁盘长度:

BTL 版本磁盘长度原版处理
v10x50转换到 common extended representation
v2/v30x68FUN_0049CE04 复制完整记录并按 +0x4C 排序

当前 1.28.0 corpus:

text
Reinforcement total = 72215
v1                  = 3196
v2/v3               = 69019

原版 FUN_0049CE04+0x4Cint32 排序,直接证明该字段是 appearance/trigger round。

主要证据:

text
reports/btl_v1280_so_recovery.md
reports/route4_identity_reference_contract.md
reconstruction/docs/btl_editor_round11_unit_medal_ribbon_field_audit_report.md
reconstruction/src/WC4.Runtime.BattleData/BtlRecords.cs

2. 完整 byte map

OffsetSizeRaw type当前中文语义 / code name版本状态写入边界
+0x002uint16 LEspawn Tile ID / TileIdv1-v3Confirmed需 global map/ref validation
+0x022uint16 LEEvent activation/group key / EventIdv1-v3Confirmed role / Partial external cases不能要求同 BTL 必有匹配 Event
+0x042int16 LEArmy type/bucket input / ArmyTypeIdv1-v3Confirmeddefinition compatibility required
+0x062int16 LEactive raw / Header06Rawv1-v3Unknown semanticNoGo
+0x082int16 LElevel/variant raw / LevelOrVariantRawv1-v3PartialNoGo
+0x0A1uint8objective marker raw / ObjectiveMarkerRawv1-v3PartialNotAssessed
+0x0B1packed uint8direction + flags / DirectionAndFlagsRawv1-v3PartialNoGo whole-byte edit
+0x0C2int16 LEformation raw / FormationRawv1-v3Confirmed inputNotAssessed
+0x0E2int16 LEspawned Unit death Event ID / DeathEventRawv1-v3Confirmed runtime projectionNoGo
+0x102int16 LEUnit AI mode raw / UnitAiModeRawv1-v3PartialNoGo
+0x122int16 LEhealth-rate raw / HealthRateRawv1-v3PartialNoGo
+0x142int16 LEbehavior raw / BehaviorRawv1-v3PartialNoGo
+0x162int16 LEcurrent-health-percent raw / CurrentHealthPercentRawv1-v3PartialNoGo
+0x182int16 LEactive status raw / Status18Rawv1-v3Unknown semanticNoGo
+0x1A2int16 LEactive status raw / Status1ARawv1-v3Unknown semanticNoGo
+0x1C4int32 LEGeneral ID / GeneralIdv1-v3Confirmed reference familydefinition validation required
+0x20..+0x4740raw bytescommon payload,当前逐字段语义未收敛v1-v3Unknown/Partial rawNoGo
+0x484int32 LERecordId-like Country key / CountryKeyRawv1-v3Confirmed identity domain / Partial external casesNoGo
+0x4C4int32 LEappearance/trigger round / AppearanceRoundv1-v3ConfirmedNotAssessed
+0x504int32 LEGeneral equipment definition ID slot 0v2/v3Confirmedzero or existing definition only
+0x544int32 LEGeneral equipment definition ID slot 1v2/v3Confirmedzero or existing definition only
+0x584int32 LEGeneral equipment definition ID slot 2v2/v3Confirmedzero or existing definition only
+0x5C4int32 LEGeneral equipment definition ID slot 3v2/v3Confirmedzero or existing definition only
+0x604int32 LEGeneral equipment definition ID slot 4v2/v3Confirmedzero or existing definition only
+0x644int32 LEGeneral equipment definition ID slot 5v2/v3Confirmedzero or existing definition only

+0x20..+0x47 当前保持 raw 不是因为原版“不使用”,而是因为本 Reference 尚没有足够逐字段 consumer authority。高保真读写必须逐字节保存该区域。

3. +0x00 Spawn Tile 可以位于当前 BTL crop 之外

全量 72215 条 Reinforcement:

text
current BTL projection 内可解析 Tile = 71847
当前 crop 外但完整 external map 内有效 = 368
完整 map 外原版样本 = 0

因此 Reinforcement TileId 是全局地图身份,不应被当前裁剪后的 BattleTile 列表错误限制。

对于 external-map BTL:

text
local projection miss
!= invalid TileId

当前安全 resolution:如果能在完整 world.bin 容量中定位但不在本 BTL projection,应标记 External,而不是删除或改写该增援。

4. +0x02 是 Event activation/group key

Event common executor FUN_003835B4 对两条增援 Action 分别传入当前 Event.Id

text
ActionType 0x0D
-> FUN_0037BC88(ReinforcementService, current Event.Id)

ActionType 0x18
-> FUN_0037C314(ReinforcementService, current Event.Id, Event+0x18)

Reinforcement service 再按这个 key 查找/遍历关联 records。因此 +0x02 的安全角色不是“这条增援会触发哪个 Event”,而是:

把 Reinforcement record 归组到负责激活/生成它的 Event.Id。

corpus:

text
Reinforcement total                   72215
+0x02 == 0                            70389
+0x02 > 0                              1826
positive resolved to same-BTL Event    1752
positive missing same-BTL Event          74

1752 个可解析目标的 ActionType 引用次数:

text
Action 4       8
Action 6       4
Action 7      12
Action 13   1561
Action 24    167

绝大多数落在 native 已审计的 0x0D / 0x18 增援路径,但 74 个真实正值在当前 BTL Event 表中没有目标。因此“非零 EventId 必须同 BTL resolve”仍不是 writer hard rule。

工具应保留 raw EventId、给 diagnostic、不自动清零,也不能把 Missing reference 当成文件物理损坏。

4.1 +0x0E 是 spawned Unit 的 DeathEventId

normal reinforcement FUN_0037BC88 与 airborne reinforcement FUN_0037C314 都在创建 Unit 后执行等价赋值:

text
runtime Unit+0x150
= sign-extended Reinforcement+0x0E int16

runtime Unit +0x150 已由独立 Unit death recovery 闭合为 death EventId。因此:

text
Reinforcement+0x0E
-> spawned Unit+0x150
-> Unit death EventId dispatcher

corpus:

text
+0x0E == 0       72135
+0x0E > 0           80
+0x0E < 0            0
missing target       0

80 个正值目标 TriggerType:

text
Type1  71
Type4   8
Type5   1

所以 +0x0E 的运行时角色已可标记 Confirmed。现有 parser accessor DeathEventRaw 作为兼容 code name 暂不改名;这不代表语义仍 Unknown,也不开放 writer validity。

新增证据:

text
reconstruction/docs/btl_event_producer_and_execution_lifecycle_closure_v1_report.md
reports/btl_semantic_recovery/event_producer_and_execution_lifecycle_closure_v1/event_producer_and_execution_lifecycle_closure.json

5. +0x48 不是 CountryIndex

旧访问器/社区语义曾把 +0x48 叫 Country index。全 corpus 已直接否定这个解释。

72215 条记录中:

text
71988  -> 能匹配当前 BTL Country.RecordId
  227  -> 当前初始 Country.RecordId 中无匹配,多集中于 Frontier/后续阵营
 7268  -> 数值超出 0..CountryCount-1
    0  -> raw value 0 出现次数

7268 个反例足以证明:

text
+0x48 != BtlCountryIndex

当前安全名称:

text
CountryKeyRaw / RecordId-like country key

解析政策:

  1. 优先按 Country.RecordId 解析;
  2. 当前初始 Country 不存在时保持 Deferred/External;
  3. 绝不能 fallback 到 BTL Country 数组索引
  4. 不因 unresolved 就硬失败或改值。

6. +0x4C AppearanceRound

原版 FUN_0049CE04 直接按该 int32 对 Reinforcement records 排序,spawn manager 再按 schedule 检查。

所以:

text
+0x4C = appearance/trigger round

这是 Reinforcement 当前最强的调度字段之一,状态 Confirmed

7. v2+ +0x50..+0x64 与 Unit 装备编码完全不同

普通 Unit v2+ 使用:

text
+0x30..+0x35
6 x uint8 compressed code

Reinforcement v2+ 使用:

text
+0x50,+0x54,+0x58,+0x5C,+0x60,+0x64
6 x int32 GeneralMedalSettings definition ID

原版生成路径:

text
FUN_00491624 / FUN_00492888
-> FUN_00499268(general, slot, *(int32 *)(record + slotOffset))

因此二者绝不能共用一个 raw equipment editor。

Corpus

text
Reinforcement records with equipment   = 562
Equipment but no General                = 0
Missing equipment definition IDs       = 0

非零 ID 范围按槽分布在 GeneralMedalSettings 的完整定义 ID 域,例如前三槽主要是 1001+,后三槽主要是 2000+ 系列;所有审计到的非零 ID 均能命中定义。

当前安全验证:

text
raw == 0
OR GeneralMedalSettings.Id exists

并且非零装备要求 GeneralId > 0

8. v1 与 v2+ 的边界

v1 record 在 +0x4F 结束,没有六个 equipment definition ID。

所以:

  • 不能把 v2+ 的 +0x50..+0x64 写进 v1;
  • v1 loader 的 common expansion 不代表原 v1 磁盘上存在这些字段;
  • 如果工具需要把 v1 升级成更高版本格式,那是独立结构/版本迁移工作,不是普通字段编辑。

9. 当前 Unknown / Partial backlog

Reinforcement 剩余重点:

  1. +0x06
  2. +0x08 level/variant 的完整 Army/mode 语义;
  3. +0x0B packed direction/flags;
  4. +0x10..+0x1A 多个状态、行为、HP 比例字段的精确生成语义;
  5. +0x20..+0x47 全逐字段 consumer;
  6. +0x48 的 227 个 Deferred/External Country key 最终来源与后续创建链;
  7. Missing Event reference 的完整原版执行反馈;
  8. spawn 失败、占用冲突、重复 schedule 与异常引用的完整边界;
  9. v1 common expansion 中所有新增字段的精确 default/transform。

这些 Unknown 不影响 v1 0x50 / v2+ 0x68 记录的物理 round-trip。