外观
Reinforcement Record 增援记录
状态:Authoritative Reference v1
1. 记录版本
Reinforcement 有两种磁盘长度:
| BTL 版本 | 磁盘长度 | 原版处理 |
|---|---|---|
| v1 | 0x50 | 转换到 common extended representation |
| v2/v3 | 0x68 | FUN_0049CE04 复制完整记录并按 +0x4C 排序 |
当前 1.28.0 corpus:
text
Reinforcement total = 72215
v1 = 3196
v2/v3 = 69019原版 FUN_0049CE04 按 +0x4C 的 int32 排序,直接证明该字段是 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.cs2. 完整 byte map
| Offset | Size | Raw type | 当前中文语义 / code name | 版本 | 状态 | 写入边界 |
|---|---|---|---|---|---|---|
+0x00 | 2 | uint16 LE | spawn Tile ID / TileId | v1-v3 | Confirmed | 需 global map/ref validation |
+0x02 | 2 | uint16 LE | Event activation/group key / EventId | v1-v3 | Confirmed role / Partial external cases | 不能要求同 BTL 必有匹配 Event |
+0x04 | 2 | int16 LE | Army type/bucket input / ArmyTypeId | v1-v3 | Confirmed | definition compatibility required |
+0x06 | 2 | int16 LE | active raw / Header06Raw | v1-v3 | Unknown semantic | NoGo |
+0x08 | 2 | int16 LE | level/variant raw / LevelOrVariantRaw | v1-v3 | Partial | NoGo |
+0x0A | 1 | uint8 | objective marker raw / ObjectiveMarkerRaw | v1-v3 | Partial | NotAssessed |
+0x0B | 1 | packed uint8 | direction + flags / DirectionAndFlagsRaw | v1-v3 | Partial | NoGo whole-byte edit |
+0x0C | 2 | int16 LE | formation raw / FormationRaw | v1-v3 | Confirmed input | NotAssessed |
+0x0E | 2 | int16 LE | spawned Unit death Event ID / DeathEventRaw | v1-v3 | Confirmed runtime projection | NoGo |
+0x10 | 2 | int16 LE | Unit AI mode raw / UnitAiModeRaw | v1-v3 | Partial | NoGo |
+0x12 | 2 | int16 LE | health-rate raw / HealthRateRaw | v1-v3 | Partial | NoGo |
+0x14 | 2 | int16 LE | behavior raw / BehaviorRaw | v1-v3 | Partial | NoGo |
+0x16 | 2 | int16 LE | current-health-percent raw / CurrentHealthPercentRaw | v1-v3 | Partial | NoGo |
+0x18 | 2 | int16 LE | active status raw / Status18Raw | v1-v3 | Unknown semantic | NoGo |
+0x1A | 2 | int16 LE | active status raw / Status1ARaw | v1-v3 | Unknown semantic | NoGo |
+0x1C | 4 | int32 LE | General ID / GeneralId | v1-v3 | Confirmed reference family | definition validation required |
+0x20..+0x47 | 40 | raw bytes | common payload,当前逐字段语义未收敛 | v1-v3 | Unknown/Partial raw | NoGo |
+0x48 | 4 | int32 LE | RecordId-like Country key / CountryKeyRaw | v1-v3 | Confirmed identity domain / Partial external cases | NoGo |
+0x4C | 4 | int32 LE | appearance/trigger round / AppearanceRound | v1-v3 | Confirmed | NotAssessed |
+0x50 | 4 | int32 LE | General equipment definition ID slot 0 | v2/v3 | Confirmed | zero or existing definition only |
+0x54 | 4 | int32 LE | General equipment definition ID slot 1 | v2/v3 | Confirmed | zero or existing definition only |
+0x58 | 4 | int32 LE | General equipment definition ID slot 2 | v2/v3 | Confirmed | zero or existing definition only |
+0x5C | 4 | int32 LE | General equipment definition ID slot 3 | v2/v3 | Confirmed | zero or existing definition only |
+0x60 | 4 | int32 LE | General equipment definition ID slot 4 | v2/v3 | Confirmed | zero or existing definition only |
+0x64 | 4 | int32 LE | General equipment definition ID slot 5 | v2/v3 | Confirmed | zero 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 741752 个可解析目标的 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 int16runtime Unit +0x150 已由独立 Unit death recovery 闭合为 death EventId。因此:
text
Reinforcement+0x0E
-> spawned Unit+0x150
-> Unit death EventId dispatchercorpus:
text
+0x0E == 0 72135
+0x0E > 0 80
+0x0E < 0 0
missing target 080 个正值目标 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.json5. +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解析政策:
- 优先按
Country.RecordId解析; - 当前初始 Country 不存在时保持 Deferred/External;
- 绝不能 fallback 到 BTL Country 数组索引;
- 不因 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 codeReinforcement 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 剩余重点:
+0x06;+0x08level/variant 的完整 Army/mode 语义;+0x0Bpacked direction/flags;+0x10..+0x1A多个状态、行为、HP 比例字段的精确生成语义;+0x20..+0x47全逐字段 consumer;+0x48的 227 个 Deferred/External Country key 最终来源与后续创建链;- Missing Event reference 的完整原版执行反馈;
- spawn 失败、占用冲突、重复 schedule 与异常引用的完整边界;
- v1 common expansion 中所有新增字段的精确 default/transform。
这些 Unknown 不影响 v1 0x50 / v2+ 0x68 记录的物理 round-trip。