Skip to content

Unit Record 单位记录

状态:Authoritative Reference v1

1. 记录版本

Unit 有两种磁盘长度:

BTL 版本磁盘长度原版加载路径
v10x30FUN_0048052C 先扩展到 common 0x40 表示,再进入正常加载
v2/v30x40FUN_0048059C 直接消费 common 记录

原版 Unit 构造主链:

text
raw Unit record
-> resolve Tile from +0x00
-> resolve ArmySettings from Army/Country/Ranking/Formation inputs
-> allocate runtime Unit
-> FUN_00476580 initialize
-> FUN_0048059C apply disk state
-> attach to Tile and Country collections

因此本页描述的是 BTL 磁盘记录,不是 runtime Unit 对象布局。

当前 1.28.0 corpus:

text
Unit total = 127512
v1         = 17571
v2/v3      = 109941

主要证据:

text
reports/btl_v1280_so_recovery.md
reports/btl_editor/round4/field_write_whitelist_matrix.csv
reconstruction/src/WC4.Runtime.BattleData/BtlRecords.cs

2. 完整 byte map

说明:

  • Confirmed 表示该行所写的具体语义已确认,不代表所有值域和运行时后续写入都闭合;
  • Partial 表示用途范围已知但完整业务语义仍开放;
  • Unknown 表示不得用经验名称填空;
  • NoGo 写入状态表示当前 Reference 明确不授权按该解释修改;
  • 其余字段的实际写权限由当前 BTL writer 产品门禁另行裁决,本 Reference 不自动授予写权限。
OffsetSizeRaw type当前中文语义 / code name版本语义状态写入状态
+0x002uint16 LEUnit Tile ID / TileIdv1-v3ConfirmedNotAssessed
+0x021uint8Army bucket / ArmyTypeId,参与 ArmySettings 解析v1-v3ConfirmedNotAssessed
+0x031uint8Ranking / effective elite level raw / Level;不是普通 HUD 经验等级v1-v3ConfirmedNotAssessed
+0x041uint8编制 / Formationv1-v3ConfirmedNotAssessed
+0x051uint8朝向 / Directionv1-v3ConfirmedNotAssessed
+0x061int8初始移动/运行状态 / MovementRawv1-v3PartialNotAssessed
+0x071uint8初始回合/行动状态 / TurnStateRawv1-v3PartialNotAssessed
+0x082int16 LE未闭合 scalar / Stat08Rawv1-v3UnknownNoGo
+0x0A2int16 LE未闭合 scalar / Stat0ARawv1-v3UnknownNoGo
+0x0C2int16 LE初始当前 HP / CurrentHpv1-v3ConfirmedNotAssessed
+0x0E2int16 LE初始最大 HP / MaximumHpv1-v3ConfirmedNotAssessed
+0x102int16 LE将领 ID / GeneralIdv1-v3ConfirmedNotAssessed
+0x121uint8将领军衔 / GeneralRankv1-v3ConfirmedNotAssessed
+0x131uint8将领品质 / GeneralQualityv1-v3ConfirmedNotAssessed
+0x14..+0x163raw byteslegacy/unknown bytes;不是将领装备槽v1-v3UnknownNoGo
+0x171uint8技能等级槽 0v1-v3ConfirmedNotAssessed
+0x181uint8技能等级槽 1v1-v3ConfirmedNotAssessed
+0x191uint8技能等级槽 2v1-v3ConfirmedNotAssessed
+0x1A1uint8技能等级槽 3v1-v3ConfirmedNotAssessed
+0x1B1uint8技能等级槽 4v1-v3ConfirmedNotAssessed
+0x1C1int8单位目标标记 / ObjectiveMarkerv1-v3ConfirmedNotAssessed
+0x1D1uint8单位 AI mode raw / UnitAiModeRawv1-v3PartialNotAssessed
+0x1E1uint8运输限制/状态 raw / TransportRestrictionRawv1-v3PartialNotAssessed
+0x1F1int8signed AI priority / PriorityRawv1-v3ConfirmedNotAssessed
+0x202int16 LEtarget-Tile-like reference / TargetTileRawv1-v3PartialNoGo
+0x222int16 LEArmyAIConfig group ID / ArmyAiConfigurationIdv1-v3ConfirmedNotAssessed
+0x241int8behavior state / BehaviorStateRawv1-v3ConfirmedNotAssessed
+0x251uint8 rawBattleMode 6 / Frontier 相关 override gate/inputv1-v3PartialNoGo
+0x262int16 LEbehavior change round / BehaviorChangeRoundRawv1-v3ConfirmedNotAssessed
+0x281uint8初始士气状态 / MoraleRawv1-v3ConfirmedNotAssessed
+0x291uint8初始士气持续回合 / MoraleDurationRawv1-v3ConfirmedNotAssessed
+0x2A1int8死亡 Event ID / DeathEventIdv1-v3ConfirmedNotAssessed
+0x2B1packed uint8mixed active flags / PackedFlags2Bv1-v3PartialNoGo
+0x2C1uint8defensive-distance raw / DefensiveDistanceRawv1-v3PartialNoGo
+0x2D1raw byte已确认可加载到 runtime counter-qualification blocker;完整生命周期/含义未闭合v1-v3PartialNoGo
+0x2E1raw byte未闭合v1-v3UnknownNoGo
+0x2F1uint8 rawElite 条件下的 skin/variant selector rawv1-v3PartialNoGo
+0x301compressed uint8General equipment slot 0:medal-family codev2/v3ConfirmedNotAssessed
+0x311compressed uint8General equipment slot 1:medal-family codev2/v3ConfirmedNotAssessed
+0x321compressed uint8General equipment slot 2:medal-family codev2/v3ConfirmedNotAssessed
+0x331compressed uint8General equipment slot 3:ribbon-family codev2/v3ConfirmedNotAssessed
+0x341compressed uint8General equipment slot 4:ribbon-family codev2/v3ConfirmedNotAssessed
+0x351compressed uint8General equipment slot 5:ribbon-family codev2/v3ConfirmedNotAssessed
+0x361active extension byte原版会读取;精确语义未闭合v2/v3PartialNoGo
+0x371packed nibblesactive Feature slot0/slot1 cooldownv2/v3ConfirmedNoGo
+0x38..+0x3F8active extension bytes原版会读取,包含 signed/bitfield 等消费;逐字段完整语义未闭合v2/v3PartialNoGo

3. 关键字段详解

3.1 +0x02 不是简单的 ArmySettings.Type

+0x02 是 Army bucket 输入。最终 ArmySettings 解析还会结合 CountryDefinition、有效 Ranking 和 Formation。

因此旧工具若直接把 +0x02 显示为完整 ArmySettings.Type,会丢失真实解析关系。

3.2 +0x03 不是普通经验等级

当前证据支持它作为构造时 Ranking / effective elite level 类输入。它不能直接等同于 HUD 中玩家理解的普通“经验等级”。

当前 corpus:12 种值,范围 1..12

3.3 +0x0C/+0x0E 是 HP 对

text
+0x0C CurrentHp
+0x0E MaximumHp

当前 corpus:

text
CurrentHp  = 0..25000
MaximumHp  = 1..25000

两者虽然是独立磁盘 scalar,但作者工具修改时必须考虑 CurrentHp <= MaximumHp 以及模式/定义缩放;读取语义确认不自动授权任意写入。

3.4 +0x14..+0x16 不是勋章槽

社区/第三方编辑器曾把这三个字节候选解释为将领徽章/装备。

原版 FUN_0048059C 不把它们作为装备读取;真正的 v2+ 六个装备槽位于 +0x30..+0x35

语料还显示:

  • 全部 Unit:127512+0x14..+0x16 组合存在 251 条非零记录;
  • v2/v3 Unit:109941,这三个字节全部为零。

因此当前非零实例来自 legacy v1 范围,但其原版语义仍未闭合。“v2+ 恒零”不能升级成 padding 结论。

3.5 +0x20+0x22 必须区分

社区旧说法把 +0x22 称为 attack target。该说法已被原版 resolver 链否定。

text
+0x20 -> target-Tile-like short
+0x22 -> FUN_004BB7B4 -> ArmyAIConfig group lookup

因此:

  • +0x22ArmyAIConfig IDConfirmed
  • +0x20:确实具有目标 Tile 类引用性质,但 behavior-specific 完整语义仍为 Partial

3.6 +0x25:Frontier 相关输入,但不能直接叫 Frontier flag

+0x25 是一个独立 byte,不属于 +0x24

当前表现链已经确认:

text
BattleMode != 6
-> FrontierOverrideActive = false

BattleMode == 6 && Unit raw[0x25] == 0
-> FrontierOverrideActive = false

BattleMode == 6 && Unit raw[0x25] != 0
-> 继续依赖未闭合的 owner / feature gate
-> 当前必须 Deferred / Unknown

原版后续路径可以在条件满足时解析 replacement ArmyDefinition,再选择新的 Motion template。

因此 +0x25 当前安全描述是:

BattleMode 6 / Frontier 相关单位定义覆盖的 gate/input。

不能直接命名为:

  • Frontier flag;
  • Frontier Army ID;
  • skin ID。

证据:reconstruction/docs/rendering/static_unit_integration_report.md

3.7 +0x2D:已从纯 Unknown 前进到 Partial

早期 writer audit 将 +0x2D..+0x2F 整体保留为 Unknown。后续 Fight 证据已经确认一个具体映射:

text
BTL Unit record +0x2D
-> FUN_0048059C
-> runtime Unit counter-qualification blocker field

在已审计 selected Unit87 中,磁盘 +0x2D = 0 对应 runtime blocker Unit+0x104 = 0,并参与 Unit+0x104 <= 0 的 counter qualification。

但任意值域、其他 writer、生命周期和完整业务名称尚未闭合,所以仍为 Partial,不能把 selected-case 名称扩张成最终全局字段名。

证据:

text
reports/route5_fixed_seed_fight_recovery/fight_input_field_matrix.csv
reports/route5_fixed_seed_fight_recovery/final_counter_predicate_matrix.csv

3.8 +0x2F:Elite 条件 skin/variant selector

静态单位表现链确认:

text
skin = ArmyDefinition.IsElite ? UnitRaw[0x2F] : 0

随后该值进入 Unit 初始化的 skin/variant 状态。

这证明 +0x2F 不是安全 padding,但当前 Reference 仍保留 Partial,因为完整值域、所有 Elite 定义和其他消费者尚未形成全局闭合。

证据:reconstruction/docs/rendering/static_unit_integration_report.md

4. General equipment +0x30..+0x35

这些字段只存在于 v2/v3 0x40 Unit record;v1 0x30 磁盘记录没有该区域。

4.1 槽 0-2:medal-family

空槽:

text
raw == 0

默认解码:

text
type = raw
level = 1

扩展编码区 171..230

text
type  = (raw - 1) / 10
level = (raw - 1) % 10 + 1

原版槽族门:

text
Type 1..22
Type 40..43

此外 (Type, Level) 必须能解析到 GeneralMedalSettings

4.2 槽 3-5:ribbon-family

空槽:

text
raw == 0

非零解码:

text
type  = raw / 10 + 20
level = raw % 10

原版槽族门:

text
Type 23..39

同样必须存在对应定义。

4.3 Corpus

Slot非零次数不同 raw 值观察范围
01568381..229
11274421..226
2754621..230
370507631..195
468228331..195
552307932..195

所有审计到的非零值都能命中定义并通过对应槽族门。

详细证据:reconstruction/docs/btl_editor_round11_unit_medal_ribbon_field_audit_report.md

5. +0x37 active Feature cooldown packed byte

这是 +0x36..+0x3F 中目前闭合程度最高的字段。

v2+ 持久化格式:

text
low nibble  = active Feature slot0 cooldown
high nibble = active Feature slot1 cooldown

反序列化:

text
slot0 = packed & 0x0F
slot1 = packed >> 4

序列化:

text
packed = (slot1 << 4) | slot0

该结论已经跨 ARM64/x86 对齐:

  • 构造时两个 cooldown 清零;
  • runtime copy 会复制两槽;
  • v2+ load/save 使用 record+0x37
  • 正值在回合维护中递减;
  • active Feature 执行会写入对应槽 cooldown。

Type 0x5D death-protection 只是 slot0 cooldown 的一个消费者,不能因此把整个 +0x37 命名成“死亡保护冷却”。

主要证据:

text
reconstruction/docs/route5_fixed_seed_fight_round8_death_protection_report.md
reports/route5_fixed_seed_fight_recovery/death_protection_lifecycle_matrix.csv

6. +0x36..+0x3F 不得视为 padding

社区旧资料曾遗漏或把该区间视为 unused/unknown padding。原版 FUN_0048059C 实际会读取整个 v2+ extension range。

当前 109941 个 v2/v3 Unit 中有 440 条记录在该区间存在非零值;native consumer 已证明这里包含 signed、nibble 和 bitfield 数据。

目前只有部分子字段达到独立命名标准,尤其 +0x37 已闭合。其余字节仍应 raw-preserve,不能因为 Reference 尚未命名就删除、清零或批量编辑。

7. 当前 corpus 摘要

以下统计来自既有 field audit:

字段观察值摘要
+0x02 ArmyTypeId74 种,1..101
+0x03 Level12 种,1..12
+0x04 Formation5 种,0..4
+0x05 Direction2 种,0..1
+0x06 MovementRaw25 种,0..28
+0x07 TurnStateRaw当前 corpus 全 0
+0x08 Stat08Raw当前 corpus 全 0
+0x0A Stat0ARaw63 种,1..3000
+0x1F PriorityRaw-100..100
+0x20 TargetTileRaw-1..12006
+0x22 ArmyAIConfig ID0..529
+0x24 BehaviorStateRaw当前 corpus 全 0
+0x26 BehaviorChangeRoundRaw当前 corpus 全 0
+0x2A DeathEventId0..77
+0x2C DefensiveDistanceRaw0..200

这些是 观察范围,不是允许写入范围,也不是格式允许值域的上限证明。

8. 社区兼容结论

旧说法当前裁决
+0x22 = attack targetRefuted;实际为 ArmyAIConfig ID
+0x14..+0x16 = General equipmentRefuted
+0x30..+0x35 = medal/ribbonConfirmed with slot-family refinement
+0x36..+0x3F = padding/unusedRefuted

完整社区勘误见 ../community/corrections.md

9. 当前主要 Unknown / Partial backlog

优先级较高:

  1. +0x08 完整语义;
  2. +0x0A 完整语义;
  3. legacy +0x14..+0x16
  4. +0x1D 完整 AI mode enum;
  5. +0x1E 各 Army/运输类型状态矩阵;
  6. +0x20 behavior-specific target 语义;
  7. +0x25 非零值与 Frontier owner/feature gate 完整语义;
  8. +0x2B 全 bit mask;
  9. +0x2C defensive-distance 完整 consumer;
  10. +0x2D 完整生命周期与值域;
  11. +0x2E
  12. +0x2F 完整 Elite selector 值域;
  13. +0x36/+0x38..+0x3F 逐字段/逐 bit consumer。

这些条目应通过 native/corpus/runtime evidence 逐项闭合,不进行“合理化设计”。