外观
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: a6073469da4fb1cdfd229dd38202e06861bb88d02. 从 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/rangeRaw08 只有与 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 | 顶层候选组 | 当前安全机制描述 | 解释性标签 |
|---|---|---|---|
0 | 0x1000, active 0x2000, 0x4000, possible 0x3000 | 原地、普通移动、全局战略推进、当前攻击补充的综合行为 | 常规综合型 A |
1 | active 0x2000, 0x4000, possible 0x3000 | 与 0 相比不先加入 0x1000 原地候选 | 无初始留守的推进型 |
2 | 与 0 相同的主要顶层组 | 0x4000 战略落脚只接受相邻一格,并使用独立的宽随机评分区间 | 分步战略推进型 |
3 | 0x1000, optional 0x3000, 0x6000, 0x8000 | 局部目标、staging、scripted target/path 组合 | 局部战术/脚本驱动型 |
4 | active 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) == 1ARM64 指令级证据:
text
004afb34 ldr w8,[x0,#0x13c]
004afb38 cmp w8,#0x2
004afb3c b.ne 004afb5c
...
004afb50 bl 0036cde4
004afb54 cmp w0,#0x1
004afb58 b.ne 004afc80FUN_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 在相同战略基础分下允许显著更大的向下扰动。
例子:
S | mode0 输出集合 | 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选择支援倍率:
| 附近友军 behavior | support scale |
|---|---|
0 | 8 |
1 | 1 |
2 | 15 |
3 | 20 |
4 | 12 |
因此:
text
nearby behavior2 friendly
-> 对正在执行 0x5000 的 behavior4 单位
-> 提供 support scale 15它不能反推:
text
behavior2 = Support AI因为 behavior2 自身正常 dispatcher 根本不执行 0x5000。
9. “抱团”至少有四种不同来源
从当前恢复机制看,视觉上相似的“单位聚在一起”不能统一解释成一种协同算法:
- mode0/1/2 可能因为选择相同或相近战略 anchor,长路径方向收敛;
- mode3 有独立 tactical staging / scripted path;
- mode4 有明确的 radius-6 friendly-support attraction;
- 可达格枚举、路径 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 主行为写入:
| mode | assignment rows | files |
|---|---|---|
0 | 5228 | 433 |
1 | 5784 | 440 |
2 | 222 | 63 |
3 | 100 | 43 |
4 | 34 | 10 |
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 的
0x4000adjacent 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
- Unit Record:
+0x1D/+0x1E/+0x20/+0x26的持久字段映射; - Behavior / ArmyAIConfig:Behavior 物理结构和 consumer-scoped action 解码;
- Event Record:
ActionType 0x06/0x08/0x09的运行时覆盖; - 运行语义索引:其他跨 Record/runtime 关系。