Initial import of HEROLL source and design documents

This commit is contained in:
toshiocn
2026-10-26 16:05:39 +08:00
commit fdb55672c1
1846 changed files with 290692 additions and 0 deletions
@@ -0,0 +1,74 @@
# HEROLL 丹药与 Boss 循环逆向纠错报告
> 日期:2026-08-24
> 工具链:IL2CPP 元数据、runtime-decrypted `libil2cpp.so`、radare2 6.2.0、配置表、公开资料交叉检索、TypeScript/Playwright
> Scope:[case scope](../work/20260824-heroll-potion-gauge/scope.md) · [timeline](../work/20260824-heroll-potion-gauge/timeline.md)
## 结论
1. `potion.csv` 的 `HealLevel.value=50/80/110…650` 是固定 HP,不是最大生命百分比。独立的 `Potion_PercentHeal(valueA=10)` 才额外增加 10% 最大生命恢复。
2. Boss 循环按负责人实机确认实现:玩家 ROLL 2 次后开启 4 次 ROLL 倒计时;倒计时结束逐个把 4 个非祝福玩家地块变成怪物地块,然后回到 0/2。
3. 旧双击启动器闪退来自 LF-only UTF-8 CMD 与 Windows PowerShell 5.1 的 BOM-less UTF-8 解码问题;已改为 ASCII+CRLF CMD、UTF-8 BOM+CRLF PS1,并加入错误留窗和端到端自测。
## Evidence
| ID | 证据 | 复现 | Hash |
|---|---|---|---|
| E-001 | `potion.csv` 的 21 级曲线 | 见 [E-001](../work/20260824-heroll-potion-gauge/evidence/E-001.md) | `8049…EFA99` |
| E-002 | `GetPotionFinalHeal @ 0x5473568` native 方法体 | 见 [E-002](../work/20260824-heroll-potion-gauge/evidence/E-002.md) | `AC35…00DA` |
| E-003 | Gauge 更新、spawn 调用与清零链 | 见 [E-003](../work/20260824-heroll-potion-gauge/evidence/E-003.md) | `43CE…5CD` |
| E-004 | 公开资料没有精确基础公式 | 见 [E-004](../work/20260824-heroll-potion-gauge/evidence/E-004.md) | n/a |
| E-005 | 负责人实机 2+4+4 规则确认 | 见 [E-005](../work/20260824-heroll-potion-gauge/evidence/E-005.md) | n/a |
| E-006 | MVP、浏览器与启动器验收 | 见 [E-006](../work/20260824-heroll-potion-gauge/evidence/E-006.md) | n/a |
## Findings
| ID | 状态 | 置信度 | 结论 |
|---|---|---|---|
| F-001 | validated | high | HealLevel 是固定 HP;PercentHeal 是独立百分比加项 |
| F-002 | validated | high | Boss 是 2 ROLL 蓄势 + 4 ROLL 倒计时 + 转换 4 格 |
| F-003 | validated | high | 启动器故障由 CMD/PS1 编码与换行兼容性造成 |
完整字段见 [findings.md](../work/20260824-heroll-potion-gauge/findings.md)。
## Path
```mermaid
flowchart LR
cfg["HealLevel 固定值"] --> base["基础恢复 HP"]
pct["PercentHeal 10% Max HP"] --> add["额外恢复"]
base --> sum["相加"]
add --> sum
adaptive["Adaptive multiplier"] --> final["除以 100 后取整"]
sum --> final --> clamp["生命上限钳制"]
```
```mermaid
stateDiagram-v2
[*] --> Build0
Build0 --> Build1: ROLL 1
Build1 --> Countdown4: ROLL 2
Countdown4 --> Countdown3: ROLL 3
Countdown3 --> Countdown2: ROLL 4
Countdown2 --> Countdown1: ROLL 5
Countdown1 --> BossAction: ROLL 6
BossAction --> Convert4: 逐格感染动画
Convert4 --> Build0: 重置循环
```
完整调用路径见 [path.md](../work/20260824-heroll-potion-gauge/path.md)。
## 复现命令
```powershell
C:\Users\toshio\Tools\radare2\bin\radare2.exe -q -c "e asm.lines=false; s 0x5473568; af; pdf; q" work\heroll-stage-2-5\libil2cpp.runtime-decrypted.so
cd mvp
.\Validate-Heroll-MVP.ps1
cd ..
cmd.exe /d /c "set HEROLL_MVP_SELF_TEST=1&& call HEROLL_MVP_双击启动.cmd"
```
## 遗留边界
- `2 + 4 + 转换 4 格` 的精确时序来自负责人实机确认;bounded native 证据只闭环 Gauge 增量、范围、spawn 调用和清零。
- 其他丹药强化若需要宣称“原作完整还原”,仍应逐个恢复 native 消费者;当前 MVP 保留已实现的验证语义。
@@ -0,0 +1,49 @@
# HEROLL 丹药与 Boss 循环纠错报告
正式报告见项目文档:[`../../../docs/2026-08-24_逆向-HEROLL丹药与Boss循环-report.md`](../../../docs/2026-08-24_逆向-HEROLL丹药与Boss循环-report.md)。
## Findings
### F-001
- title: HealLevel values are fixed HP, not max-HP percentages
- severity: n/a_re
- category: reverse_algo
- status: validated
- evidence_ids: [E-001, E-002, E-004]
- location: PotionController.GetPotionFinalHeal @ 0x5473568
- impact: Interpreting 50 as 50% materially over-heals and collapses survival pacing.
- confidence: high
### F-002
- title: Boss gameplay contract is a 2-roll buildup plus 4-roll countdown cycle
- severity: n/a_re
- category: design
- status: validated
- evidence_ids: [E-003, E-005]
- location: Board movement post-resolution state
- impact: The previous immediate action after two rolls had the wrong pace and converted the wrong number of tiles.
- confidence: high
### F-003
- title: Windows launcher flash exit was caused by encoding and newline incompatibility
- severity: n/a_re
- category: other
- status: validated
- evidence_ids: [E-006]
- location: HEROLL_MVP_双击启动.cmd and Windows PowerShell 5.1 script decoding
- impact: cmd.exe split LF-only UTF-8 commands incorrectly; Windows PowerShell 5.1 also misread a BOM-less UTF-8 PS1.
- confidence: high
## Paths
### P-001
- title: Potion configuration to final heal callflow
- path_type: callflow
- start: potion.csv HEAL_LEVEL.value
- goal: resolved player HP delta
- steps:
1. Load fixed HealLevel value 50/80/110..650 — E-001, F-001.
2. GetPotionFinalHeal obtains that fixed value — E-002, F-001.
3. If Potion_PercentHeal exists, add maxHp × value/100 — E-002, F-001.
4. Apply the adaptive multiplier and clamp actual HP in the MVP — E-002, E-006, F-001.
- residual_risks: Other potion augments remain validation implementations unless separately closed by native analysis.
@@ -0,0 +1,12 @@
# 08-BOSS与局内结束
Boss Gauge、压力循环、丹药关联、最终Boss Floor与结束分支。
## 文件
- [2026-08-24_逆向-HEROLL丹药与Boss循环-report.md](./2026-08-24_%E9%80%86%E5%90%91-HEROLL%E4%B8%B9%E8%8D%AF%E4%B8%8EBoss%E5%BE%AA%E7%8E%AF-report.md) — report;来源:`docs/2026-08-24_逆向-HEROLL丹药与Boss循环-report.md`
- [boss_gauge_final_report.md](./boss_gauge_final_report.md) — report;来源:`HEROLL_STAGE_2_5_2_EVIDENCE/10_UPLOAD_TO_CHATGPT/boss_gauge_final_report.md`
- [HEROLL-potion-boss-report.md](./HEROLL-potion-boss-report.md) — report;来源:`work/20260824-heroll-potion-gauge/report/HEROLL-potion-boss-report.md`
- [stage-boss-rules.csv](./stage-boss-rules.csv) — table;来源:`analysis/stage-floor-rules/tables/stage-boss-rules.csv`
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
@@ -0,0 +1,24 @@
# Boss Gauge 最终报告
## 已确认的计数器运算
`BoardController.AddBossDiceNumber`(0x569A170):
`BossDiceCounter = BossDiceCounter + argument`
`BoardController.HandleBossDiceRolled`(0x569A19C):
`BossDiceCounter = BossDiceCounter - argument`
直接调用扫描仅在 `Boss19AttackHandler.<Execute>d__3.MoveNext` 发现对 `AddBossDiceNumber` 传入 -1 与 +1。这证明属性的通用加减语义,但不能证明它就是主流程的 Boss 生成 Gauge。
## 静态触发链
`<MoveTile>d__133.MoveNext` 静态调用:
- `TrySpawnBossTilesByGauge`(0x569FEC0);
- `TryRegisterMidBossByGaugeAsync`(0x569FF6C)。
对应状态机继续检查功能/模式/棋盘条件,并进入 Boss 注册或生成相关调用。`stageinfo.csv` 中存在 `bossSpawnRule=DiceGauge` 配置,但状态机内未发现对 `BossDiceCounter` 的直接读取或可确认的数值比较。
结论:移动后进入 Gauge 触发入口为 `INFERRED`;计数器是否就是生成 Gauge、每次增量、阈值比较符、触发后重置均为 `UNKNOWN`。Boss 关键帧仅为 `OBSERVED` 玩法表现。
@@ -0,0 +1,53 @@
"stage","StageFieldType","bossSpawnRule","bossSpawnRuleValue","midBossSpawnValues","midBossIDs","isBoss","bossID","skillID","attackCoolTime"
"0","Grass","Default","10","","","True","boss_0","skill_0","7"
"1","Desert","Default","10","","","True","boss_1","skill_1","8"
"2","Volcano","Default","13","","","True","boss_2","skill_2","6"
"3","Stone","Default","15","","","False","boss_r_3","skill_1","8"
"4","Grass","Default","15","","","True","boss_3","skill_3","8"
"5","Snow","DiceGauge","50","","","False","boss_r_5","skill_1","8"
"6","Snow","Default","15","","","True","boss_4","skill_4","5"
"7","Desert","DiceGauge","50","","","False","boss_r_7","skill_3","8"
"8","Desert","Default","13","","","True","boss_5","skill_5","5"
"9","Grass","DiceGauge","50","","","False","boss_r_9","skill_3","8"
"10","Abyss","Default","15","7","middle_boss_0","True","boss_6","skill_6","7"
"11","Stone","DiceGauge","50","20","middle_boss_0","False","boss_r_11","skill_4","5"
"12","Stone","Default","15","7","middle_boss_1","True","boss_7","skill_7","7"
"13","Grass","DiceGauge","50","20","middle_boss_1","False","boss_r_13","skill_4","5"
"14","Abyss","Default","15","7","middle_boss_20","True","boss_8","skill_8","7"
"15","Snow","DiceGauge","50","20","middle_boss_20","False","boss_r_15","skill_6","7"
"16","Snow","Default","13","7","middle_boss_4","True","boss_9","skill_9","7"
"17","Desert","DiceGauge","50","20","middle_boss_4","False","boss_r_17","skill_6","7"
"18","Stone","DiceGauge","50","20","middle_boss_4","False","boss_r_18","skill_1","8"
"19","Volcano","Default","15","7","middle_boss_2","True","boss_10","skill_10","7"
"20","Grass","DiceGauge","50","20","middle_boss_2","False","boss_r_20","skill_9","7"
"21","Abyss","DiceGauge","50","20","middle_boss_2","False","boss_r_21","skill_5","5"
"22","Abyss","Default","15","7","middle_boss_5","True","boss_11","skill_11","7"
"23","Grass","DiceGauge","50","20","middle_boss_5","False","boss_r_23","skill_9","7"
"24","Stone","DiceGauge","50","20","middle_boss_5","False","boss_r_24","skill_4","5"
"25","Desert","Default","15","7","middle_boss_3","True","boss_12","skill_12","7"
"26","Stone","DiceGauge","50","20","middle_boss_3","False","boss_r_26","skill_10","7"
"27","Volcano","Default","15","7","middle_boss_6","False","boss_r_27","skill_5","5"
"28","Abyss","Default","15","7","middle_boss_20","True","boss_13","skill_13","7"
"29","Grass","DiceGauge","50","20","middle_boss_20","False","boss_r_29","skill_10","7"
"30","Stone","Default","15","7","middle_boss_9","False","boss_r_30","skill_9","7"
"31","Abyss","Default","15","7","middle_boss_group_0","True","boss_14","skill_14","7"
"32","Desert","DiceGauge","50","20","middle_boss_8","False","boss_r_32","skill_11","7"
"33","Stone","Default","15","7","middle_boss_12","False","boss_r_33","skill_12","7"
"34","Grass","Default","15","7","middle_boss_1","False","boss_r_34","skill_1","8"
"35","Grass","Default","15","7","middle_boss_group_0","True","boss_15","skill_15","7"
"36","Desert","DiceGauge","50","20","middle_boss_21","False","boss_r_36","skill_3","8"
"37","Stone","Default","15","7","middle_boss_4","False","boss_r_37","skill_4","5"
"38","Abyss","Default","15","7","middle_boss_6","False","boss_r_38","skill_6","7"
"39","Abyss","Default","15","7","middle_boss_group_1","True","boss_16","skill_16","9"
"40","Grass","DiceGauge","50","20","middle_boss_6","False","boss_r_40","skill_9","7"
"41","Stone","Default","15","7","middle_boss_14","False","boss_r_41","skill_10","7"
"42","Abyss","Default","15","7","middle_boss_15","False","boss_r_42","skill_11","7"
"43","Abyss","Default","15","7","middle_boss_group_2","True","boss_17","skill_17","7"
"44","Grass","DiceGauge","50","20","middle_boss_15","False","boss_r_44","skill_12","7"
"45","Stone","Default","15","7","middle_boss_14","False","boss_r_45","skill_14","7"
"46","Abyss","Default","15","7","middle_boss_16","False","boss_r_46","skill_16","9"
"47","Abyss","Default","15","7","middle_boss_group_2","True","boss_18","skill_18","7"
"48","Grass","DiceGauge","50","20","middle_boss_16","False","boss_r_48","skill_1","8"
"49","Stone","Default","15","7","boss_11","False","boss_r_49","skill_3","8"
"50","Volcano","Default","15","7","boss_12","False","boss_r_50","skill_4","5"
"51","Abyss","Default","15","7","middle_boss_group_2","True","boss_19","skill_19","7"
1 stage StageFieldType bossSpawnRule bossSpawnRuleValue midBossSpawnValues midBossIDs isBoss bossID skillID attackCoolTime
2 0 Grass Default 10 True boss_0 skill_0 7
3 1 Desert Default 10 True boss_1 skill_1 8
4 2 Volcano Default 13 True boss_2 skill_2 6
5 3 Stone Default 15 False boss_r_3 skill_1 8
6 4 Grass Default 15 True boss_3 skill_3 8
7 5 Snow DiceGauge 50 False boss_r_5 skill_1 8
8 6 Snow Default 15 True boss_4 skill_4 5
9 7 Desert DiceGauge 50 False boss_r_7 skill_3 8
10 8 Desert Default 13 True boss_5 skill_5 5
11 9 Grass DiceGauge 50 False boss_r_9 skill_3 8
12 10 Abyss Default 15 7 middle_boss_0 True boss_6 skill_6 7
13 11 Stone DiceGauge 50 20 middle_boss_0 False boss_r_11 skill_4 5
14 12 Stone Default 15 7 middle_boss_1 True boss_7 skill_7 7
15 13 Grass DiceGauge 50 20 middle_boss_1 False boss_r_13 skill_4 5
16 14 Abyss Default 15 7 middle_boss_20 True boss_8 skill_8 7
17 15 Snow DiceGauge 50 20 middle_boss_20 False boss_r_15 skill_6 7
18 16 Snow Default 13 7 middle_boss_4 True boss_9 skill_9 7
19 17 Desert DiceGauge 50 20 middle_boss_4 False boss_r_17 skill_6 7
20 18 Stone DiceGauge 50 20 middle_boss_4 False boss_r_18 skill_1 8
21 19 Volcano Default 15 7 middle_boss_2 True boss_10 skill_10 7
22 20 Grass DiceGauge 50 20 middle_boss_2 False boss_r_20 skill_9 7
23 21 Abyss DiceGauge 50 20 middle_boss_2 False boss_r_21 skill_5 5
24 22 Abyss Default 15 7 middle_boss_5 True boss_11 skill_11 7
25 23 Grass DiceGauge 50 20 middle_boss_5 False boss_r_23 skill_9 7
26 24 Stone DiceGauge 50 20 middle_boss_5 False boss_r_24 skill_4 5
27 25 Desert Default 15 7 middle_boss_3 True boss_12 skill_12 7
28 26 Stone DiceGauge 50 20 middle_boss_3 False boss_r_26 skill_10 7
29 27 Volcano Default 15 7 middle_boss_6 False boss_r_27 skill_5 5
30 28 Abyss Default 15 7 middle_boss_20 True boss_13 skill_13 7
31 29 Grass DiceGauge 50 20 middle_boss_20 False boss_r_29 skill_10 7
32 30 Stone Default 15 7 middle_boss_9 False boss_r_30 skill_9 7
33 31 Abyss Default 15 7 middle_boss_group_0 True boss_14 skill_14 7
34 32 Desert DiceGauge 50 20 middle_boss_8 False boss_r_32 skill_11 7
35 33 Stone Default 15 7 middle_boss_12 False boss_r_33 skill_12 7
36 34 Grass Default 15 7 middle_boss_1 False boss_r_34 skill_1 8
37 35 Grass Default 15 7 middle_boss_group_0 True boss_15 skill_15 7
38 36 Desert DiceGauge 50 20 middle_boss_21 False boss_r_36 skill_3 8
39 37 Stone Default 15 7 middle_boss_4 False boss_r_37 skill_4 5
40 38 Abyss Default 15 7 middle_boss_6 False boss_r_38 skill_6 7
41 39 Abyss Default 15 7 middle_boss_group_1 True boss_16 skill_16 9
42 40 Grass DiceGauge 50 20 middle_boss_6 False boss_r_40 skill_9 7
43 41 Stone Default 15 7 middle_boss_14 False boss_r_41 skill_10 7
44 42 Abyss Default 15 7 middle_boss_15 False boss_r_42 skill_11 7
45 43 Abyss Default 15 7 middle_boss_group_2 True boss_17 skill_17 7
46 44 Grass DiceGauge 50 20 middle_boss_15 False boss_r_44 skill_12 7
47 45 Stone Default 15 7 middle_boss_14 False boss_r_45 skill_14 7
48 46 Abyss Default 15 7 middle_boss_16 False boss_r_46 skill_16 9
49 47 Abyss Default 15 7 middle_boss_group_2 True boss_18 skill_18 7
50 48 Grass DiceGauge 50 20 middle_boss_16 False boss_r_48 skill_1 8
51 49 Stone Default 15 7 boss_11 False boss_r_49 skill_3 8
52 50 Volcano Default 15 7 boss_12 False boss_r_50 skill_4 5
53 51 Abyss Default 15 7 middle_boss_group_2 True boss_19 skill_19 7