外观
Event Record 事件记录
状态:Authoritative Reference v1
1. 物理结构
BTL Event record 固定为:
text
0x2C = 44 bytes当前 1.28.0 corpus:
text
Event records = 15052原版 FUN_00383274 复制完整 0x2C 记录并建立 Event 索引。Event 是固定物理容器 + trigger/action 类型依赖参数 union,所以不能把所有参数槽赋予一个跨 ActionType/TriggerType 永远成立的业务名称。
主要证据:
text
reports/btl_v1280_so_recovery.md
reconstruction/src/WC4.Runtime.BattleData/BtlRecords.cs
reconstruction/docs/rendering/event50101_opening_morale_event_recovery_20260723.md2. 完整 byte map
| Offset | Size | Raw type | 当前中文语义 / code name | 状态 | 写入边界 |
|---|---|---|---|---|---|
+0x00 | 4 | int32 LE | Event identity / Id | Confirmed | reference validation required |
+0x04 | 2 | int16 LE | linked Event ID / LinkedEventId | Confirmed | NoGo automatic repair |
+0x06 | 2 | int16 LE | linked Event delay / LinkedEventDelay | Confirmed | NoGo automatic repair |
+0x08 | 4 | int32 LE | trigger type / TriggerType | Confirmed dispatch | per-type writer NoGo |
+0x0C | 4 | int32 LE | action type / ActionType | Confirmed dispatch | per-type writer NoGo |
+0x10 | 4 | int32 LE | type-dependent parameter / Parameter10 | Partial | NoGo |
+0x14 | 4 | int32 LE | action-dependent target parameter;Action 0..3 时为 CountryRecordId / TargetCountryRecordIdRaw | Partial | NoGo |
+0x18 | 4 | int32 LE | action-dependent parameter / ActionParameter | Partial | NoGo |
+0x1C | 2 | int16 LE | trigger condition low / TriggerConditionLow | Partial | NoGo |
+0x1E | 2 | int16 LE | trigger-side CountryRecordId-like parameter / TriggerCountryRecordIdRaw | Partial | NoGo |
+0x20 | 2 | int16 LE | trigger value / TriggerValue | Partial | NoGo |
+0x22 | 1 | uint8 | disabled/seed extension / DisabledSeed | Partial | NoGo |
+0x23 | 1 | uint8 | trigger radius/extension byte / TriggerRadiusOrExtension | Partial | NoGo |
+0x24 | 4 | int32 LE | dialogue ID / DialogueId | Confirmed | definition/reference validation required |
+0x28 | 1 | uint8 | disk executed-state seed / runtime executed state byte / ExecutedSeed | Confirmed active byte | NoGo |
+0x29..+0x2B | 3 | raw bytes | conventional 0xCC disk tail in normal records;不是强制 parser checksum | Confirmed convention / not validation | raw-preserve |
物理上 +0x28..+0x2B 也可以作为一个 uint32 RuntimeMarkerRaw 读取,但当前已确认的运行时活动位首先是 +0x28 的 executed byte。
3. +0x04/+0x06:Linked Event chain
磁盘上这两个 int16 连续存储;旧资料有时将 +0x04 起始的 32 位 word 描述为:
text
low16 = linked Event ID
high16 = linked Event delay当前强类型 parser 等价地拆成:
text
+0x04 LinkedEventId
+0x06 LinkedEventDelayEvent chain 是记录间引用,工具不能因为目标 Event 当前不可解析就自动重编号、删除或改成 0。
4. +0x14 不是 Country 数组索引
旧兼容访问器曾叫:
text
TargetCountryIndex但 ActionType 0..3 的原版 action switch 已确认:
text
BTL Event +0x14
-> FUN_003835B4
-> FUN_00346FB0
-> lookup runtime Country by Country.RecordId因此对已闭合的 morale actions,正式解释是:
text
TargetCountryRecordIdRaw不是 BtlCountryIndex。
event50101 动态证据进一步给出:
text
CountryRecordId 3 -> BTL Country slot 0
CountryRecordId 4 -> BTL Country slot 2二者并不等于数组下标,直接证明旧 Index 名称过强。
由于其他 ActionType 可能复用 +0x14 做其他参数,字段整体仍保持 Partial 而不是无条件改名成 Country ID。
5. +0x1E TriggerCountryRecordIdRaw
Trigger-side Country 字段同样通过 FUN_00346FB0 按 runtime Country 的 record ID 解析。
当前已确认:
text
zero / negative
!= BTL Country slot 0这些值在已审计路径应保持 NotApplicable/特殊参数语义,而不是错误 fallback 到 Country 数组第 0 项。
旧兼容 alias TriggerCountryIndex 仅为历史 API,不应继续作为正式语义名称。
6. ActionType 已直接闭合的分支
如果只需要快速查数值含义,可直接看 Event ActionType / TriggerType 值域速查。
0x00..0x03:Country-wide morale actions
原版 FUN_003835B4 对目标 Country 调用 morale helper:
| ActionType | 士气变化 | 持续回合 | 当前状态 |
|---|---|---|---|
0x00 | +1 | 3 | Confirmed |
0x01 | -1 | 3 | Confirmed |
0x02 | -2 | 3 | Confirmed |
0x03 | -3 | 3 | Confirmed |
执行链:
text
Event +0x14 CountryRecordId
-> resolve Country
-> walk Country-owned Tile chain
-> read each Tile primary Unit
-> FUN_004773D4(unit, moraleDelta, 3)
-> refresh presentationevent50101 runtime trace 已确认 ActionType 0 产生 5 个持久士气 +1 状态提交。
0x0D
text
normal reinforcement/spawn path状态:Confirmed path family。完整参数、失败和占用边界仍需继续闭合。
0x0E
text
ownership/camp transfer path状态:Confirmed path family。完整目标域、顺序、异常边界仍是 Partial。
0x18
text
airborne reinforcement/spawn path状态:Confirmed path family。
7. 其他 ActionType 不能从编号猜名字
当前 Reference 只给 native consumer 已直接支持的 ActionType 正式名称。
特别禁止:
- 从社区表格直接生成完整 action enum;
- 因参数看起来像 Tile/Country 就推断 action 名称;
- 把征服/集团军 JSON
EventBuffSettings的 type 编号混入 BTL EventActionType。
这两个 Event 系统不是同一编号域。
8. TriggerType 0x05:proximity-family trigger
原版把 TriggerType 0x05 放入独立 trigger list;社区/原版样本在 +0x20..+0x23 表现出 Tile/radius-like 参数形态。
当前允许结论:
text
TriggerType 0x05 = proximity-family trigger但以下仍未完全闭合:
+0x20的所有 value 子语义;+0x22/+0x23的 disabled/radius/filter 精确 bit/byte 规则;- 不同目标类型/阵营/filter 的组合;
- 多目标同时满足时的顺序和 once/repeat 边界。
因此不能把 +0x23 无条件叫“半径”。正式名称保持 TriggerRadiusOrExtension。
9. +0x28..+0x2B 的 00 CC CC CC
普通原版磁盘记录常见:
text
00 CC CC CC其中:
text
+0x28 = executed-state seed / runtime executed byte
+0x29..+0x2B = conventional 0xCC tail bytes关键结论:原版 importer 不会因为这 4 字节不是 00 CC CC CC 就拒绝 Event。
所以社区说法:
Event 必须以
00 CC CC CC结尾,否则导入失败。
当前裁决:PartialRefutation。
它是正常磁盘 seed/padding convention,不是 parser checksum。
高保真工具仍应原样保存 +0x29..+0x2B,不能因为不是强校验就自动清零或重写。
10. Event 参数必须按 union 阅读
安全思路:
text
TriggerType
-> 解释 trigger 参数槽
ActionType
-> 解释 action 参数槽而不是:
text
固定 offset
-> 永远只有一个业务名称例如 +0x14 在 Action 0..3 中已经闭合为 CountryRecordId,但这不能推出所有 ActionType 都使用 Country。
因此作者工具如果未来开放 Event writer,应先建立:
text
ActionType × field meaning × reference domain × valid sentinel
TriggerType × field meaning × reference domain × valid sentinel的完整门禁矩阵,不能用一个通用属性面直接修改所有参数。
11. 当前 closure backlog
Event 是 BTL 长尾语义中当前较大的剩余块,重点包括:
- 全部
TriggerType原版 dispatch 与参数 union; - Trigger
0x05radius/filter 完整语义; - 全部
ActionTypeswitch 分支; - 每个 Action 的
+0x10/+0x14/+0x18参数解释; - linked Event 延迟、循环、重复、missing target 的完整调度边界;
- Event executed/disabled state 的初始化、重复执行和续关行为;
- reinforcement/ownership/airborne actions 的完整写集和失败行为;
- dialogue action 与 UI/presentation 的精确时序;
- 非法 Country/Event/Tile 引用的原版异常/跳过/反馈行为。
物理 0x2C record 已闭合;这里剩下的是 runtime union semantics,而不是文件长度问题。