Skip to content

Fallback AI 主行为 0~4 ​

状态:Route 7 机制 Reference

本页解释 BTL 中的单位 AI 主行为如何进入原版 runtime fallback AI,以及主行为值 0..4 在候选生成、战略移动、战术集结和压力/支援站位中的已确认差异。

这里的 0..4 都是 runtime Unit+0x13C fallback main behavior。除非特别说明,本页给出的中文名称都是项目为了阅读方便使用的解释性标签,不是 EasyTech 原版正式枚举名。

1. 版本与证据边界 ​

主行为 dispatcher、候选组和 mode2 精确分支来自 Android 1.28.0 ARM64 native 静态恢复;mode2 的使用画像也来自 1.28.0 原版 BTL corpus。

当前 BTL Reference 的物理主基线已经推进到 1.30.0。因此:

  • Unit +0x1D -> runtime Unit+0x13C 等字段身份可以作为当前 Reference 使用;
  • 本页标为 1.28 corpus 的数量只描述 1.28,不冒充 1.29/1.30 重扫结果;
  • 原版 0..4 的正式 enum/UI 名仍为 Unknown。

主要研究 authority 位于同仓库历史:

text
Route7 mode2 characterization commit: f058406d46ed556e0317ba3d1d63439c3bfc7cc6
reconstruction/docs/route7_behavior_mode2_characterization_v1_report.md

Persistent AI field/scheduling recovery commit: a6073469da4fb1cdfd229dd38202e06861bb88d0

2. 从 BTL 到 runtime 主行为 ​

2.1 Unit 持久字段 ​

BTL Unit 的持久映射已经闭合:

text
BTL Unit +0x1D
<-> runtime Unit+0x13C
= fallback main behavior

所以 +0x1D 不是另一个独立的“AI mode”字段;它就是加载后被 fallback dispatcher 消费的主行为值。

与它相邻但必须区分的字段:

text
BTL Unit +0x1E <-> runtime Unit+0x140 LandSeaTransitionRestriction
BTL Unit +0x20 <-> runtime Unit+0x144 primary scripted target TileId
BTL Unit +0x26 <-> runtime Unit+0x134 ArmyAIConfig schedule counter

尤其 Unit+0x140 已经确认是海陆转换方向限制,不是 fallback behavior subtype。

2.2 ArmyAIConfig 调度 ​

Behavior / ArmyAIConfig 的三个 raw scalar 仍保持 raw-first 字段身份,但在原版 ArmyAIConfig consumer 内已经能做限定解码:

text
Raw04 = consumer-scoped action selector
Raw08 = activation counter
Raw0C = action value

与本页最相关的 action:

text
action 0 -> Unit+0x13C fallback main behavior
action 1 -> Unit+0x140 LandSeaTransitionRestriction
action 2 -> Unit+0x144 primary scripted target TileId
action 5 -> set Unit+0x154 behavior radius/range
action 6 -> add Unit+0x154 behavior radius/range

Raw08 只有与 runtime Unit+0x134 schedule counter 精确相等时才执行。原版新回合维护先递增这个 counter,再检查对应 ArmyAIConfig row。因此主行为可以在战斗进行中按作者配置切换,而不是单位终生固定的“人格”。

2.3 Event 运行时覆盖 ​

Event 还能绕过单位自身 ArmyAIConfig,对目标 Country 的 admitted primary Units 批量改写:

text
Event ActionType 0x06 -> Unit+0x13C fallback main behavior
Event ActionType 0x08 -> Unit+0x144 primary scripted target TileId
Event ActionType 0x09 -> Unit+0x140 LandSeaTransitionRestriction

所以某单位当前的主行为不一定等于它开局 BTL Unit+0x1D;运行中还可能被 ArmyAIConfig 或 Event 覆盖。

3. fallback 决策主链 ​

当前已恢复的核心链可简化为:

text
select eligible source Unit
-> FUN_004adc44 dispatch by Unit+0x13C
-> FUN_004adfdc generate group-specific candidates
-> FUN_004b0560 keep strict highest score
-> FUN_004aae28 convert winning candidate to ActionAssist output

候选选择有一个很重要的确定性规则:

FUN_004b0560 只在分数严格更高时替换当前 winner;同分时保留更早进入 vector 的候选。

因此候选枚举顺序、路径顺序和行为组生成顺序都可能造成稳定方向偏向,不能把所有同分现象解释成随机 tie-break。

4. 主行为 0~4 总表 ​

Value顶层候选组当前安全机制描述解释性标签
00x1000, active 0x2000, 0x4000, possible 0x3000原地、普通移动、全局战略推进、当前攻击补充的综合行为常规综合型 A
1active 0x2000, 0x4000, possible 0x3000与 0 相比不先加入 0x1000 原地候选无初始留守的推进型
2与 0 相同的主要顶层组0x4000 战略落脚只接受相邻一格,并使用独立的宽随机评分区间分步战略推进型
30x1000, optional 0x3000, 0x6000, 0x8000局部目标、staging、scripted target/path 组合局部战术/脚本驱动型
4active 0x5000 only在局部压力与友军支援场中选择站位压力/支援站位型

状态:上述控制流/机制达到 Confirmed 或 FunctionConfirmed;中文标签为 Characterized;官方名称均 Unknown。

5. 0x1000~0x8000 候选组 ​

5.1 0x1000:原地 / hold ​

候选形态:

text
{ currentTile, -1, score }

它让 mode0、mode2、mode3 有机会把“保持当前位置”作为正式候选。mode1 不先生成这一组,mode4 则走独立 0x5000。

评分会考虑当前位置局部价值、附近 hostile/attackable entity signal、Tile hazard、HP 比例等。behavior 3 在该组还有特殊低分处理。

5.2 0x2000:普通移动与移动后目标机会 ​

mode0、mode1、mode2 共用这组。

它不是 0x4000 的简化版:一部分候选按本回合可达空格和 tile/relation 价值选普通移动;另一部分会评估移动后能否形成有效目标机会。

这也是为什么下面的 mode2“一格限制”不能推广成 mode2 所有移动都只能走一格:mode2 的 0x2000 并没有读取 Unit+0x13C 做同样的一格过滤。

5.3 0x3000:当前位置攻击 ​

核心候选形态:

text
{ targetTile, -1, score }

它从当前站位寻找可攻击/可交互目标并评分。mode0/1/2 的公共尾部可以补入这一组;mode3 也可能按自身条件进入。

5.4 0x4000:全局战略推进 ​

这是理解 mode0/1/2 最重要的一组。

高层流程:

text
建立长距离 path context
-> 遍历非友方/可作为战略目标的 Country 及其关联 Tile
-> 为战略 anchor 评分
-> 选最高分战略目标
-> 枚举本回合可达 Tile
-> 将长距离 route 转换成本回合合法 landing Tile
-> 追加 {landingTile, -1, finalStrategicScore}

也就是说,它先决定“长期想往哪里去”,最后才把这个意图压缩成本回合实际落脚格。

5.5 0x5000:敌方压力 / 友军支援站位 ​

这是 behavior4 的专属主组。

对候选位置附近六格范围内的有效单位,核心 cost 关系可概括为:

text
非友方单位 -> 按 HP-like weight / distance 增加压力 cost
友方单位   -> 按 HP-like weight * supportScale / distance 降低 cost

candidate score = max(10000 - cost, 0)

它是当前明确恢复出的“友军靠近会直接提高位置吸引力”机制。

5.6 0x6000:behavior3 tactical staging ​

behavior3 在 Unit+0x154 radius 与目标可达性条件下寻找局部 target,再构造接敌/staging Tile。

它可以表现为局部集结,但机制不同于 mode4 的 pressure/support field,因此不能把 mode3 与 mode4 都简单叫“抱团 AI”。

5.7 0x7000:primary scripted target path ​

如果 Unit+0x144 有有效 scripted target,dispatcher 会在正常 0..4 主行为分派前优先尝试 0x7000。

因此 +0x144 是一个能抢在 main behavior 之前影响 fallback 的高优先级目标输入。

5.8 0x8000:behavior3 secondary scripted path ​

behavior3 还可以围绕 Unit+0x14C 的 secondary scripted target/path 生成固定分值路径候选,并与 0x6000、当前位置攻击等竞争。

Unit+0x14C 的完整持久 producer 不能从本页自行推导;这里只描述已经确认的 runtime consumer。

6. Mode 2:为什么会“一格一格”战略推进 ​

Mode2 最关键的专属分支就在 0x4000 landing candidate filter。

原版逻辑等价于:

text
if Unit+0x13C == 2:
    require hexDistance(candidateTile, currentTile) == 1

ARM64 指令级证据:

text
004afb34  ldr  w8,[x0,#0x13c]
004afb38  cmp  w8,#0x2
004afb3c  b.ne 004afb5c
...
004afb50  bl   0036cde4
004afb54  cmp  w0,#0x1
004afb58  b.ne 004afc80

FUN_0036cde4 已由独立地图/攻击距离研究确认是 parity-aware hex distance。

所以准确表述是:

当 behavior=2 走 0x4000 全局战略推进时,本回合 strategic landing 只能选当前格相邻的一格。

错误表述是:

“behavior 2 的单位每回合最多只能移动一格。”

因为同一个 mode2 单位仍先有机会通过 0x2000 ordinary movement 生成更远的本回合可达候选。

7. Mode 0 与 Mode 2 的战略评分差异 ​

令 0x4000 进入 behavior-specific finalization 前的正整数战略分数为 S。

7.1 Mode 0 ​

text
h = trunc_toward_zero(S / 2)
score0 = h + RNG(h)

在当前已确认安全输入域 S >= 2:

text
S = 2k   -> score0 in [k, 2k-1]
S = 2k+1 -> score0 in [k, 2k-1]

所以 mode0 大体把战略候选留在“上半段”随机区间。

7.2 Mode 2 ​

text
q = trunc_toward_zero(S / 4)
score2 = q + RNG(S - q)

对 S > 0:

text
score2 in [floor(S/4), S-1]

因此 mode2 在相同战略基础分下允许显著更大的向下扰动。

例子:

Smode0 输出集合mode2 输出集合
2{1}{0,1}
3{1}{0,1,2}
4{2,3}{1,2,3}
8{4,5,6,7}{2,3,4,5,6,7}
12{6..11}{3..11}

FUN_005b1ac4(n) 在已确认的 n>0 contract 下返回 [0,n-1] 随机整数。mode1 在这一步直接使用 deterministic S,不走 mode0/mode2 的这两个 RNG finalization 分支。

7.3 仍然 Unknown 的输入边界 ​

当前不能证明真实 0x4000 是否可能把以下值送进 RNG helper:

text
mode0: S = 0 or 1
mode2: S <= 0

所以 Reference 不人为添加“保护逻辑”,也不把 helper 在非正参数下的行为编造成游戏规则。

8. Mode 4 的支援权重为什么会提到 Mode 2 ​

0x5000 评价附近友军时,会根据附近友军自己的 Unit+0x13C选择支援倍率:

附近友军 behaviorsupport scale
08
11
215
320
412

因此:

text
nearby behavior2 friendly
-> 对正在执行 0x5000 的 behavior4 单位
-> 提供 support scale 15

它不能反推:

text
behavior2 = Support AI

因为 behavior2 自身正常 dispatcher 根本不执行 0x5000。

9. “抱团”至少有四种不同来源 ​

从当前恢复机制看,视觉上相似的“单位聚在一起”不能统一解释成一种协同算法:

  1. mode0/1/2 可能因为选择相同或相近战略 anchor,长路径方向收敛;
  2. mode3 有独立 tactical staging / scripted path;
  3. mode4 有明确的 radius-6 friendly-support attraction;
  4. 可达格枚举、路径 predecessor 和 strict tie retention 也会产生稳定空间偏向。

mode0/2 共享的 nearby signal 当前确认面向 hostile/attackable entity pressure/opportunity,不是另一套友军密度 attraction。

10. 1.28 原版 BTL 中 Mode 2 怎么被作者使用 ​

10.1 主行为 assignment 分布 ​

Android 1.28 原版 BTL corpus 的 ArmyAIConfig action 0 主行为写入:

modeassignment rowsfiles
05228433
15784440
222263
310043
43410

mode2 约占这套 corpus 主行为 assignment 的 1.95%。稀有度只能说明作者较少使用它,不能据此命名为“防守”“特殊单位”等。

10.2 Mode 2 通常不依赖 scripted target ​

222 个 mode2 logical group 中:

text
198 groups -> only action0
24 groups  -> action0 + action2 scripted target

所以 mode2 本身并不要求 Unit+0x144 scripted target 才成立。

10.3 大量样本是 Mode 3 -> Mode 2 的阶段切换 ​

在能直接绑定 mode2 配置的 181 个初始 Unit 中:

text
initial main behavior 3 = 177
initial main behavior 2 =   3
initial main behavior 0 =   1

这 177 个样本不是“另一个字段和 mode2 高度相关”,而是:

text
Unit 开局 +0x1D = 3
-> runtime Unit+0x13C = 3
-> ArmyAIConfig schedule counter 到达指定值
-> action0 再把同一个 Unit+0x13C 改为 2

至少还有 33 个 mode2 logical group 在更晚的 schedule step 再切换到 mode0 或 mode1。

因此 Mode 2 明确可以是阶段性启用的主行为。

10.4 不能把 Mode 2 当成某个兵种别名 ​

1.28 corpus 中,直接绑定 mode2 配置的初始 Unit 跨越多种 Army bucket、编制、是否携带 General、是否 ObjectiveMarker 等组合;同一 BTL 内还能找到其他静态属性相同但主行为不同的 mode0 对照单位。

当前证据因此反对:

text
mode2 = 某固定兵种
mode2 = 将领专用
mode2 = objective unit 专用

11. Event 也会直接制造 Mode 2 ​

1.28 Event ActionType 0x06 的参数值分布中已经出现全部 0..4:

text
mode0 = 676
mode1 = 961
mode2 =  46
mode3 =  87
mode4 = 160

所以 runtime 中的主行为切换不只来自 Unit 初始值和 ArmyAIConfig,Event 也能按 Country 批量改成 mode2 或其他值。

这些数量仍然只属于 1.28 corpus。

12. 当前最安全的 Mode 2 定性 ​

综合 native mechanism 与 authoring usage,当前项目采用:

分步战略推进型 / Stepwise Strategic Advance

这个标签只概括以下已经稳定的组合:

text
仍建立远程 strategic anchor / route
+ 仍保留 0x2000 ordinary movement 与当前攻击补充
+ 但 0x4000 strategic landing 只允许相邻一步
+ 0x4000 最终候选分数使用更宽、下界更低的 quarter-band 随机区间
+ 可通过 ArmyAIConfig / Event 阶段性启用

当前不采用这些主标签:

text
Defensive / 防守型
Cautious / 谨慎型
Slow / 慢速型
Random / 随机型
Support / 支援型
Retreat / 撤退型

原因是它们都会把某一个局部分支过度推广成整个 behavior 的设计目的。

13. 已确认与 Unknown ​

已确认:

  • Unit+0x13C 是 source Unit 的 fallback main behavior;
  • 正常值域至少包括原版使用的 0..4;
  • 0..4 的顶层 group 分派;
  • mode2 的 0x4000 adjacent landing gate;
  • mode0/mode2 的正分数 finalization 公式;
  • mode4 0x5000 的 pressure/support 定位和 support scale table;
  • ArmyAIConfig / Event 可以在 runtime 改写主行为;
  • 1.28 corpus 中 mode2 的阶段性 authoring pattern。

仍 Unknown:

  • EasyTech 原作者给 0..4 的正式 enum/UI 名;
  • mode0 的 S=0/1 和 mode2 的 S<=0 是否真实可达 RNG call;
  • support scale 8/1/15/20/12 的设计者命名与选择这些常数的原因;
  • 1.29 corpus 对 mode2 详细 assignment 分布是否与 1.28 完全一致;在没有重扫前不得沿用 1.28 数字宣称 1.29 统计。

14. 相关 Reference ​

除另有说明外,本站有权许可的原创文档采用 CC BY-SA 4.0;第三方内容除外。