Skip to content

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.md

2. 完整 byte map

OffsetSizeRaw type当前中文语义 / code name状态写入边界
+0x004int32 LEEvent identity / IdConfirmedreference validation required
+0x042int16 LElinked Event ID / LinkedEventIdConfirmedNoGo automatic repair
+0x062int16 LElinked Event delay / LinkedEventDelayConfirmedNoGo automatic repair
+0x084int32 LEtrigger type / TriggerTypeConfirmed dispatchper-type writer NoGo
+0x0C4int32 LEaction type / ActionTypeConfirmed dispatchper-type writer NoGo
+0x104int32 LEtype-dependent parameter / Parameter10PartialNoGo
+0x144int32 LEaction-dependent target parameter;Action 0..3 时为 CountryRecordId / TargetCountryRecordIdRawPartialNoGo
+0x184int32 LEaction-dependent parameter / ActionParameterPartialNoGo
+0x1C2int16 LEtrigger condition low / TriggerConditionLowPartialNoGo
+0x1E2int16 LEtrigger-side CountryRecordId-like parameter / TriggerCountryRecordIdRawPartialNoGo
+0x202int16 LEtrigger value / TriggerValuePartialNoGo
+0x221uint8disabled/seed extension / DisabledSeedPartialNoGo
+0x231uint8trigger radius/extension byte / TriggerRadiusOrExtensionPartialNoGo
+0x244int32 LEdialogue ID / DialogueIdConfirmeddefinition/reference validation required
+0x281uint8disk executed-state seed / runtime executed state byte / ExecutedSeedConfirmed active byteNoGo
+0x29..+0x2B3raw bytesconventional 0xCC disk tail in normal records;不是强制 parser checksumConfirmed convention / not validationraw-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 LinkedEventDelay

Event 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+13Confirmed
0x01-13Confirmed
0x02-23Confirmed
0x03-33Confirmed

执行链:

text
Event +0x14 CountryRecordId
-> resolve Country
-> walk Country-owned Tile chain
-> read each Tile primary Unit
-> FUN_004773D4(unit, moraleDelta, 3)
-> refresh presentation

event50101 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 Event ActionType

这两个 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..+0x2B00 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 长尾语义中当前较大的剩余块,重点包括:

  1. 全部 TriggerType 原版 dispatch 与参数 union;
  2. Trigger 0x05 radius/filter 完整语义;
  3. 全部 ActionType switch 分支;
  4. 每个 Action 的 +0x10/+0x14/+0x18 参数解释;
  5. linked Event 延迟、循环、重复、missing target 的完整调度边界;
  6. Event executed/disabled state 的初始化、重复执行和续关行为;
  7. reinforcement/ownership/airborne actions 的完整写集和失败行为;
  8. dialogue action 与 UI/presentation 的精确时序;
  9. 非法 Country/Event/Tile 引用的原版异常/跳过/反馈行为。

物理 0x2C record 已闭合;这里剩下的是 runtime union semantics,而不是文件长度问题。