Initial import of HEROLL source and design documents
This commit is contained in:
@@ -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"
|
||||
|
Reference in New Issue
Block a user