Initial import of HEROLL source and design documents
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
"order","branch","phase","source_status","mvp_rule","skip_on_final_boss"
|
||||
"0","all","Start entry","source-aligned entry","Cross Start; lock dice and movement; store remainingSteps; finish any already-open equipment, blessing, event-reward, and shop UI before advancing the transaction.","false"
|
||||
"1","shop-eligible","shop judgment and interaction","MVP ordered override","Evaluate the every-3-Floor shop condition; build 3 fixed plus 3 non-duplicate random offers; open the shop and await close. TILE purchases enter purchasedTileQueue and are not installed yet.","false"
|
||||
"2","all","final Floor / Boss judgment","MVP ordered override","Evaluate Default final Floor or DiceGauge 50/50. On success replace all 44 positions with Boss Tile and retain remainingSteps.","false"
|
||||
"3","all","current Floor reward","MVP ordered override","Grant the completed-Floor reward exactly once. This step runs after Boss judgment and before any normal-loop mutation.","false"
|
||||
"4","normal non-final","loop commit and purchased Tile install","MVP ordered override","Increment loopIndex exactly once; install purchasedTileQueue entries in purchase order on legal ordinary small tiles. If the Boss branch was selected, roll back and do not charge uncommitted TILE purchases.","true"
|
||||
"5","normal non-final","Good injection","source call structure retained","Await AddRandomGoodTiles(loopIndex+2). The argument is attempt count, not guaranteed successful placement count.","true"
|
||||
"6","normal non-final","Enemy injection","source call structure retained","Await AddRandomEnemyTile(enemyTilesPerLoop,false); MVP default enemyTilesPerLoop=3 attempts.","true"
|
||||
"7","all surviving","spring heal","source relative position intentionally overridden","Heal 30% max HP after reward and normal refresh; clamp to max HP.","false"
|
||||
"8","all surviving","transaction completion","source-aligned completion","Restore camera/UI; write a safe checkpoint; unlock movement.","false"
|
||||
"9","normal or converted Boss board with remainingSteps","movement resume","MVP edge rule","Continue clockwise using remainingSteps. Only the new final landing tile resolves. On a Boss board, that landing starts the final Boss battle.","false"
|
||||
"10","converted Boss board without remainingSteps","next-roll Boss entry","MVP edge rule","Do not treat the standing position as a new landing. Require one more Roll; the next completed Boss-Tile landing starts the final Boss battle.","false"
|
||||
|
@@ -0,0 +1,252 @@
|
||||
# HEROLL 2.0.1 关卡楼层分布与刷新规则逆向报告
|
||||
|
||||
> 仅限本机内部玩法验证。本文描述 HEROLL 2.0.1 的逆向结果,不授予原作代码、配置或美术资源的发行权。
|
||||
|
||||
## 1. 结论摘要
|
||||
|
||||
此前“关卡楼层分布和刷新规则”的任务没有形成独立交付物;本报告补齐该任务,并覆盖旧 GDD 中“每层固定注入 2 个有益地块”等未经闭环的描述。
|
||||
|
||||
### 1.1 两套关卡终局规则
|
||||
|
||||
普通主线共有 52 个启用关卡,分成两类:
|
||||
|
||||
| 规则 | 关卡数 | 配置值 | 实际含义 |
|
||||
|---|---:|---:|---|
|
||||
| `Default` | 33 | 10 / 13 / 15 | 固定楼层数;与 `board.csv` 对应关卡的行数完全一致 |
|
||||
| `DiceGauge` | 19 | 50 | 每次合格的完整落地结算向实时 Boss Gauge 增加 50;不是“50 层”也不是直接阈值 |
|
||||
|
||||
`Default` 关卡的配置分布是:2 个 10 层关、3 个 13 层关、28 个 15 层关。所有 33 个关卡都满足:
|
||||
|
||||
```text
|
||||
bossSpawnRuleValue == board.csv 中该 Normal Stage 的楼层行数
|
||||
loop 索引范围 == 0 .. bossSpawnRuleValue - 1
|
||||
```
|
||||
|
||||
因此第 1 关的权威规则是:`stage=0`、`Default=10`、`loop=0..9`,完成第 10 层后进入 `boss_0`。`board.csv` 的每一行是对应楼层的敌方数值模板,不是地块布局表。
|
||||
|
||||
### 1.2 棋盘不是逐层重建,而是持续变异
|
||||
|
||||
玩家通过起点时进入下一层。换层状态机执行“增加新的有益地块和敌人”,而不是重新生成整张棋盘。官方商店页也明确描述为:每次经过起点,新的敌人与事件会被加入不断变化的棋盘。
|
||||
|
||||
核心调用顺序为:
|
||||
|
||||
```text
|
||||
经过起点 / 完成一圈
|
||||
→ AddNextLoopTiles(loopIndex)
|
||||
→ AddRandomGoodTiles(loopIndex + 2)
|
||||
→ 等待表现完成
|
||||
→ AddRandomEnemyTile(enemyTilesPerLoop, false)
|
||||
→ 等待新增敌人及地块表现完成
|
||||
```
|
||||
|
||||
注意:`loopIndex + 2` 是“有益地块元数据抽取/安装尝试次数”,不是无条件保证最终新增同样数量的可见地块。候选位置不足、地块保护规则或安装失败均可能使最终可见数量较少。
|
||||
|
||||
新局初始化是独立路径:
|
||||
|
||||
```text
|
||||
SpawnInitalTiles
|
||||
→ 执行初始地块生成(内部调用传入常量 3,但被调用方法的参数名未恢复)
|
||||
|
||||
InitNewGame
|
||||
→ SpawnInitalTiles
|
||||
→ SpawnAllCornerTiles
|
||||
→ AddRandomGoodTiles(8)
|
||||
```
|
||||
|
||||
`enemyTilesPerLoop` 是 `BoardController` 的序列化字段;本次 APK 表和已导出的场景资料没有恢复它的原始序列化数值。初始状态机中的常量 3 也不能在缺少方法参数名时直接等同为“3 个敌人”。因此可以准确实现调用结构,但不能把 3 或其他猜测值写成原作每层敌人数常量。
|
||||
|
||||
### 1.3 玩家有益地块不是固定事件池
|
||||
|
||||
`AddRandomGoodTiles(N)` 从玩家当前可用/装备的 `OutGameTile` 元数据牌组取 N 次,而不是直接从 `newtile.csv` 的全部 `GoodEvent` 等权抽取。
|
||||
|
||||
牌组规则已经从 `GetNextMetadata` 闭合:
|
||||
|
||||
1. 缓存 `_shuffledDeck` 与 `_currentDeckIndex`。
|
||||
2. 牌组为空或索引到尾时,以当前玩家可用的局外地块列表重建并洗牌,索引归零。
|
||||
3. 每次返回当前索引的一个元数据,然后索引加一。
|
||||
4. 因而同一轮牌组内不重复;请求次数超过牌组大小时会重新洗牌,跨轮可能再次抽到同类地块。
|
||||
5. 抽到的 `OutGameTile.refNewTileId` 再映射到 `NewTile`,播放 `PlayGoodFX` 并调用 `AddTileActEvent` 安装。
|
||||
|
||||
新账号有 8 个 `defaultEquip=True` 的稀有地块,刚好对应初始化的 8 次抽取:铁匠铺、恢复、传奇装备、英雄体、宝箱、抓娃娃、泡泡龙和 Spito。完整表见 `tables/default-good-tile-deck.csv`。
|
||||
|
||||
这意味着第 1 层初始化时,在牌组和位置均有效的前提下,默认 8 张会各抽到一次。后续层的抽取次数随传入的零基 `loopIndex` 增长。若 UI 楼层 `F` 以 1 开始,常规换层调用对应 `loopIndex=F-1`,则进入该层时的尝试数为 `F+1`;第 1 层仍走独立的固定 8 次初始化路径。
|
||||
|
||||
### 1.4 自然生成地块的资格过滤
|
||||
|
||||
`newtile.csv` 的关键字段含义由表头与运行时消费共同确认:
|
||||
|
||||
| 字段 | 规则 |
|
||||
|---|---|
|
||||
| `isEnabled` | 是否允许进入自然生成候选 |
|
||||
| `minStage` | 最低主线 Stage |
|
||||
| `minLoop` | 最低零基 Loop(楼层门槛) |
|
||||
| `ETileTypeV2` | Empty / NormalEnemy / GoodEvent / BadEvent / BossAttack / Corner 等分类 |
|
||||
| `maxCornerPerGame` | 单局同类角落地块上限;`-1` 表示该字段不设限 |
|
||||
|
||||
Stage 0 的自然候选在 `loop=0` 已包含 4 类普通敌人、6 类 GoodEvent、3 类 BadEvent、5 类 Corner、祝福、空地等;`loop=3` 解锁黑市、传送、彩票、21 点、Power Star、Dice Machine、泡泡龙,`loop=5` 解锁 Dice Catapult。`GoodEventGoldCarriage` 与 `GoodEventSpito` 还要求 `minStage=1`,因此不应在第 1 关自然生成。
|
||||
|
||||
这里必须区分两条入口:
|
||||
|
||||
- 自然生成:受 `newtile.isEnabled/minStage/minLoop` 过滤。
|
||||
- 玩家有益地块注入:以当前 `OutGameTile` 牌组及 `refNewTileId` 为源,再由安装位置保护规则决定能否落盘。
|
||||
|
||||
完整资格表见 `tables/enabled-tile-eligibility.csv`。
|
||||
|
||||
### 1.5 商店刷新
|
||||
|
||||
起点是换层触发点。公开玩法资料明确记录“商店每 3 层在起点出现”,与原作实机和既有 GDD 的第 3、6、9 层观察一致;原生 `BoardController` 同时存在 `shopPerLoop` 字段和换层状态机中的商店分支。
|
||||
|
||||
玩法验证实现应采用:
|
||||
|
||||
```text
|
||||
displayFloor % 3 == 0 → 起点显示商店
|
||||
```
|
||||
|
||||
商店不属于每层随机地块抽取;它依附起点,并由层间隔控制。商店内部商品刷新、费用和购买规则属于单独的商店逆向报告。
|
||||
|
||||
## 2. Boss 压力刷新
|
||||
|
||||
### 2.1 `Default` 关卡
|
||||
|
||||
`Default` 不使用实时压力 Gauge。以 `stageinfo.bossSpawnRuleValue` 作为总楼层数,读取 `board.csv` 的 `loop=0..N-1` 数值;最后一层完成后进入关卡 Boss。第 1 关为 10 层后 `boss_0`。
|
||||
|
||||
存在 `midBossSpawnValues` 时,`Default` 关卡用楼层进度注册中 Boss。配置值 7 与楼层中点一致,但原生比较中的零/一基显示转换没有恢复出托管变量名;因此只能把“7”作为原始门槛配置,验收时必须以原作录像校准 UI 层号和触发帧,不能直接断言是内部 `loop=7` 或用户可见“第 7 层”。
|
||||
|
||||
### 2.2 `DiceGauge` 关卡
|
||||
|
||||
每次合格的落地结算执行:
|
||||
|
||||
```ts
|
||||
runtimeBossGauge = clamp(
|
||||
runtimeBossGauge + stageInfo.bossSpawnRuleValue,
|
||||
0,
|
||||
100,
|
||||
);
|
||||
```
|
||||
|
||||
当前 19 个 `DiceGauge` 关卡的增量都为 50,所以正常路径两次完整掷骰/落地结算蓄满 100。`MoveTile` 随后依次检查 `TrySpawnBossTilesByGauge` 与 `TryRegisterMidBossByGaugeAsync`。
|
||||
|
||||
结合原生数据流和项目中已验证的原作实机观察,完整周期为:
|
||||
|
||||
```text
|
||||
Gauge 0
|
||||
→ 第 1 次完整落地:50
|
||||
→ 若配置 midBossSpawnValues=20,中 Boss Gauge 注册路径已具备数值条件(强推断)
|
||||
→ 第 2 次完整落地:100
|
||||
→ 进入 Boss 压力倒计时
|
||||
→ 后续 4 次玩家掷骰:4 → 3 → 2 → 1 → 0
|
||||
→ 随机转换 4 个互不重复、非祝福地块为 Boss 压力地块
|
||||
→ 实时 Gauge 清零,进入下一周期
|
||||
```
|
||||
|
||||
`BoardController.BossDiceCounter` 是倒计时显示字段,不是实时 Gauge。`AddBossDiceNumber(v)` 只做 `counter += v`,`HandleBossDiceRolled(v)` 只做 `counter -= v`;两者不得与 `runtimeBossGauge` 合并成同一个变量。`midBossSpawnValues=20` 被 `TryRegisterMidBossByGaugeAsync` 消费的总体语义可信,但被混淆的共享谓词没有恢复成可读比较式,所以精确的 `>=20` 运算符仍标为强推断。
|
||||
|
||||
原生证据能确认:Gauge 加 50、上下限 0/100、移动后进入 Boss 生成链、保存被替换前地块、生成后同一 Gauge 字段清零。4 次倒计时、4 个唯一非祝福地块来自原作运行时观察。以下边界仍未从静态代码恢复成可靠托管语义:
|
||||
|
||||
- 合格候选不足 4 个时的降级顺序;
|
||||
- 除祝福外是否还存在模式专属保护地块;
|
||||
- 被 Boss 压力覆盖的地块在攻击结束后是原样恢复还是按事件结果恢复。
|
||||
|
||||
玩法验证版应把这些边界做成可配置策略并记录 seed/候选列表;在获得对应录像前不得声称是原作精确规则。
|
||||
|
||||
## 3. 第 1 关开发用规则
|
||||
|
||||
| 项目 | 原作规则 | 来源/置信度 |
|
||||
|---|---|---|
|
||||
| Stage | `0`,Grass,Normal | 源码确认 / 高 |
|
||||
| 楼层 | 10 层,内部 `loop=0..9` | `stageinfo` 与 `board` 完全闭合 / 高 |
|
||||
| 最终 Boss | `boss_0`,`skill_0`,攻击冷却 7 | 源码确认 / 高 |
|
||||
| 敌人数值 | 严格逐行读取 `stage0-loop-enemy-stats.csv` | 源码确认 / 高 |
|
||||
| 初始角落 | `SpawnAllCornerTiles` | 原生调用确认 / 高 |
|
||||
| 初始有益地块 | `AddRandomGoodTiles(8)` | 原生常量确认 / 高 |
|
||||
| 默认有益牌组 | 8 个默认装备的 OutGameTile | 配置确认 / 高 |
|
||||
| 换层有益注入 | `AddRandomGoodTiles(loopIndex+2)` | 原生算术确认 / 高 |
|
||||
| 换层敌人注入 | `AddRandomEnemyTile(enemyTilesPerLoop,false)` | 原生调用确认;数量值未恢复 / 中高 |
|
||||
| 商店 | 起点每 3 个显示楼层出现 | 实机/社区交叉验证 + 原生字段 / 中高 |
|
||||
| Boss 压力 Gauge | 第 1 关不启用 | `Default` 配置 / 高 |
|
||||
| 通关 | 完成第 10 层后进入 `boss_0` | 配置与楼层表闭合 / 高 |
|
||||
|
||||
第 1 关 MVP 不应继续使用以下旧假设:
|
||||
|
||||
- 每层固定新增 2 个有益地块;
|
||||
- 六类事件每局强制各出现一次;
|
||||
- 全部 GoodEvent 从固定池等权抽取;
|
||||
- 第 1 关使用两掷蓄压、四掷 Boss 压力循环。
|
||||
|
||||
## 4. 实现伪代码
|
||||
|
||||
```ts
|
||||
function enterNewRun(stage: StageInfo, playerDeck: OutGameTileMeta[]) {
|
||||
loopIndex = 0;
|
||||
spawnInitialTiles(); // 内部常量 3 的参数语义仍需动态闭环
|
||||
spawnAllCornerTiles();
|
||||
addRandomGoodTiles(8, playerDeck);
|
||||
}
|
||||
|
||||
async function passStartTile() {
|
||||
loopIndex += 1;
|
||||
if (isDefaultStage && loopIndex >= stage.bossSpawnRuleValue) {
|
||||
enterFinalBoss(stage.bossID);
|
||||
return;
|
||||
}
|
||||
|
||||
await addRandomGoodTiles(loopIndex + 2, currentPlayerGoodTileDeck);
|
||||
await addRandomEnemyTiles(enemyTilesPerLoop, false);
|
||||
|
||||
const displayFloor = loopIndex + 1;
|
||||
if (displayFloor % shopPerLoop === 0) {
|
||||
showShopOnStartTile();
|
||||
}
|
||||
}
|
||||
|
||||
function drawGoodTileMeta(): OutGameTileMeta | null {
|
||||
if (eligiblePlayerDeck.length === 0) return null;
|
||||
if (!shuffledDeck || currentDeckIndex >= shuffledDeck.length) {
|
||||
shuffledDeck = shuffle(copy(eligiblePlayerDeck));
|
||||
currentDeckIndex = 0;
|
||||
}
|
||||
return shuffledDeck[currentDeckIndex++];
|
||||
}
|
||||
|
||||
function onQualifiedTileSettlement() {
|
||||
if (stage.bossSpawnRule !== 'DiceGauge') return;
|
||||
runtimeBossGauge = clamp(
|
||||
runtimeBossGauge + stage.bossSpawnRuleValue,
|
||||
0,
|
||||
100,
|
||||
);
|
||||
tryRegisterMidBossByGauge();
|
||||
trySpawnBossTilesByGauge();
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 证据链
|
||||
|
||||
| Evidence | Finding | Design/Path |
|
||||
|---|---|---|
|
||||
| E-STAGE-CONFIG-001 | 两类 Boss 规则;Default 值与楼层行数完全一致;地块门槛和默认牌组 | F-STAGE-001, F-TILE-001 |
|
||||
| E-STAGE-NATIVE-001 | 初始化 8 次、换层 `loop+2`、敌人字段注入、洗牌无放回、Gauge 加法/清零 | F-REFRESH-001, F-GAUGE-001 |
|
||||
| E-STAGE-RUNTIME-001 | DiceGauge 的 2 次蓄压、4 次倒计时、4 个非祝福覆盖 | F-GAUGE-002 |
|
||||
| E-STAGE-WEB-001 | 经过起点换层、每 3 层商店、每圈新增敌人与事件 | F-REFRESH-002 |
|
||||
|
||||
本地证据为主,互联网资料仅用于交叉验证玩家可观察语义;其中 Steam 页面属于同系列后续公开描述,不能替代 2.0.1 本地证据。外部参考:[Heroll Wiki Tiles](https://heroll.fandom.com/wiki/Tiles)、[Steam《HEROLL: IF》页面](https://store.steampowered.com/app/4838670/)。
|
||||
|
||||
## 6. 配套表格
|
||||
|
||||
- `tables/stage-boss-rules.csv`:52 个普通主线关卡的 Boss / 中 Boss 配置。
|
||||
- `tables/stage0-loop-enemy-stats.csv`:第 1 关 10 层敌方数值。
|
||||
- `tables/enabled-tile-eligibility.csv`:启用地块的 Stage / Loop 门槛与角落上限。
|
||||
- `tables/default-good-tile-deck.csv`:新账号 8 个默认有益地块元数据。
|
||||
|
||||
## 7. 验收用例
|
||||
|
||||
1. 对全部 33 个 `Default` 关卡校验 `boardRows == bossSpawnRuleValue`。
|
||||
2. 第 1 关只读取 `loop=0..9`;第 10 层后进入 `boss_0`,不得启用 DiceGauge。
|
||||
3. 新局固定调用 8 次有益地块抽取;在默认 8 张牌组下,首轮抽取不重复。
|
||||
4. 换层调用次数必须是 `loopIndex+2`,并记录“请求数 / 成功安装数 / 失败原因”。
|
||||
5. 同一洗牌轮不重复;耗尽后重洗,固定 seed 下结果可复现。
|
||||
6. `minStage/minLoop/isEnabled/maxCornerPerGame` 的自然生成过滤逐项测试。
|
||||
7. DiceGauge 关卡两次合格落地达到 100,之后四次掷骰倒计时,生成 4 个唯一非祝福候选并清零。
|
||||
8. Gauge 与 BossDiceCounter 使用两个字段,存档恢复时不得相互覆盖。
|
||||
9. 商店仅依附起点,并按显示楼层 3 的倍数触发。
|
||||
10. `enemyTilesPerLoop` 在恢复原作序列化值前标为外部配置,不得硬编码猜测值并标注“源码确认”。
|
||||
@@ -0,0 +1,14 @@
|
||||
# 01-关卡与棋盘
|
||||
|
||||
Stage、Floor、Start、棋盘刷新、Good牌组、Enemy注入与Boss规则。
|
||||
|
||||
## 文件
|
||||
|
||||
- [01-start-settlement-timeline.csv](./01-start-settlement-timeline.csv) — contract;来源:`analysis/mvp-rules-closure/01-start-settlement-timeline.csv`
|
||||
- [2026-08-31_逆向-HEROLL关卡楼层分布与刷新规则-report.md](./2026-08-31_%E9%80%86%E5%90%91-HEROLL%E5%85%B3%E5%8D%A1%E6%A5%BC%E5%B1%82%E5%88%86%E5%B8%83%E4%B8%8E%E5%88%B7%E6%96%B0%E8%A7%84%E5%88%99-report.md) — report;来源:`analysis/stage-floor-rules/2026-08-31_逆向-HEROLL关卡楼层分布与刷新规则-report.md`
|
||||
- [default-good-tile-deck.csv](./default-good-tile-deck.csv) — table;来源:`analysis/stage-floor-rules/tables/default-good-tile-deck.csv`
|
||||
- [enabled-tile-eligibility.csv](./enabled-tile-eligibility.csv) — table;来源:`analysis/stage-floor-rules/tables/enabled-tile-eligibility.csv`
|
||||
- [stage-boss-rules.csv](./stage-boss-rules.csv) — table;来源:`analysis/stage-floor-rules/tables/stage-boss-rules.csv`
|
||||
- [stage0-loop-enemy-stats.csv](./stage0-loop-enemy-stats.csv) — table;来源:`analysis/stage-floor-rules/tables/stage0-loop-enemy-stats.csv`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,9 @@
|
||||
"Id","StringId","refNewTileId","grade","unlockStage","skillUnlockLevel","ETileSkill"
|
||||
"100","GoodEventSmithy_RARE","GoodEventSmithy","RARE","-1","8","Skill_1"
|
||||
"103","GoodEventRecovery_RARE","GoodEventRecovery","RARE","-1","8","Skill_1"
|
||||
"106","GoodEventLegendGear_RARE","GoodEventLegendGear","RARE","-1","8","Skill_1"
|
||||
"109","GoodEventHeroBody_RARE","GoodEventHeroBody","RARE","-1","8","Skill_1"
|
||||
"112","GoodEventChest_RARE","GoodEventChest","RARE","-1","8","Skill_1"
|
||||
"124","GoodEventClawGrab_RARE","GoodEventClawGrab","RARE","-1","8","Skill_1"
|
||||
"133","GoodEventBubbleShooter_RARE","GoodEventBubbleShooter","RARE","-1","8","Skill_2"
|
||||
"136","GoodEventSpito_RARE","GoodEventSpito","RARE","-1","8","Skill_1"
|
||||
|
@@ -0,0 +1,47 @@
|
||||
"Id","StringId","ETileEvent","ETileTypeV2","minStage","minLoop","values","maxCornerPerGame"
|
||||
"100","Empty","Empty","Empty","0","0","0","-1"
|
||||
"101","NormalEnemy_1","NormalEnemy_1","NormalEnemy","0","0","0","-1"
|
||||
"102","NormalEnemy_2","NormalEnemy_2","NormalEnemy","0","0","0","-1"
|
||||
"103","NormalEnemy_3","NormalEnemy_3","NormalEnemy","0","0","0","-1"
|
||||
"104","NormalEnemy_4","NormalEnemy_4","NormalEnemy","0","0","0","-1"
|
||||
"105","BossAttackStrongEnemy","BossAttackStrongEnemy","BossAttack","0","0","0","-1"
|
||||
"106","BossAttackBerserk1","BossAttackBerserk1","BossAttack","0","0","0","-1"
|
||||
"110","BossAttackEvolve1","BossAttackEvolve1","BossAttack","0","0","0","-1"
|
||||
"111","BossAttackEvolve2","BossAttackEvolve2","BossAttack","0","0","0","-1"
|
||||
"112","BossAttackEvolve3","BossAttackEvolve3","BossAttack","0","0","0","-1"
|
||||
"113","BossAttackEvolve4","BossAttackEvolve4","BossAttack","0","0","0","-1"
|
||||
"114","BossAttackInfected","BossAttackInfected","BossAttack","0","0","0","-1"
|
||||
"115","BossAttackInfectedHost3","BossAttackInfectedHost3","BossAttack","0","0","0","-1"
|
||||
"116","BossAttackInfectedHost2","BossAttackInfectedHost2","BossAttack","0","0","0","-1"
|
||||
"117","BossAttackInfectedHost1","BossAttackInfectedHost1","BossAttack","0","0","0","-1"
|
||||
"118","MiniBoss","MiniBoss","MiniBoss","0","0","0","-1"
|
||||
"119","Boss","Boss","Boss","0","0","0","-1"
|
||||
"124","AugmentRandom","AugmentRandom","Augment","0","0","0","-1"
|
||||
"125","CornerKillOneLineEnemy","CornerKillOneLineEnemy","Corner","0","0","0","-1"
|
||||
"126","CornerDoubleStack","CornerDoubleStack","Corner","0","0","0","-1"
|
||||
"127","CornerRace","CornerRace","Corner","0","0","0","-1"
|
||||
"128","CornerOneLineChest","CornerOneLineChest","Corner","0","0","0","-1"
|
||||
"129","CornerDiceBuilding","CornerDiceBuilding","Corner","0","0","0","-1"
|
||||
"131","CornerBlackMarket","CornerBlackMarket","Corner","0","3","0","-1"
|
||||
"167","CornerDiceCatapult","CornerDiceCatapult","Corner","0","5","0","-1"
|
||||
"175","CornerWarp","CornerWarp","Corner","0","3","0","3"
|
||||
"132","Start","Start","Start","0","0","0","-1"
|
||||
"133","StartShop","StartShop","Start","0","0","0","-1"
|
||||
"134","BadEventJail","BadEventJail","BadEvent","0","0","0","-1"
|
||||
"135","BadEventPlusOneLineEnemy","BadEventPlusOneLineEnemy","BadEvent","0","0","0","-1"
|
||||
"137","GoodEventSmithy","GoodEventSmithy","GoodEvent","0","0","0","-1"
|
||||
"138","GoodEventRecovery","GoodEventRecovery","GoodEvent","0","0","0","-1"
|
||||
"139","GoodEventLegendGear","GoodEventLegendGear","GoodEvent","0","0","0","-1"
|
||||
"140","GoodEventHeroBody","GoodEventHeroBody","GoodEvent","0","0","0","-1"
|
||||
"141","GoodEventChest","GoodEventChest","GoodEvent","0","0","0","-1"
|
||||
"142","GoodEventLotto","GoodEventLotto","GoodEvent","0","3","0","-1"
|
||||
"143","GoodEventBlackJack","GoodEventBlackJack","GoodEvent","0","3","3,10,2.5,5,10","-1"
|
||||
"144","GoodEventPowerStar","GoodEventPowerStar","GoodEvent","0","3","0","-1"
|
||||
"151","GoodEventClawGrab","GoodEventClawGrab","GoodEvent","0","0","1,15","-1"
|
||||
"152","GoodEventGoldCarriage","GoodEventGoldCarriage","GoodEvent","1","3","4","-1"
|
||||
"164","GoodEventDiceMachine","GoodEventDiceMachine","GoodEvent","0","3","","-1"
|
||||
"166","GoodEventBubbleShooter","GoodEventBubbleShooter","GoodEvent","0","3","3,18,0,3,5,10","-1"
|
||||
"169","GoodEventSpito","GoodEventSpito","GoodEvent","1","3","30,10,1,10,50,40","-1"
|
||||
"170","SeasonEventRoulette","SeasonEventRoulette","Start","0","0","0","-1"
|
||||
"171","JokerEvent","JokerEvent","Start","0","0","0","-1"
|
||||
"177","BadEventNormalLock","BadEventNormalLock","BadEvent","0","0","0","-1"
|
||||
|
@@ -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"
|
||||
|
@@ -0,0 +1,11 @@
|
||||
"Stage","loop","monsterGroupIDs","monsterCount","monsterAtkReducePer","AttackPower","Health","Defense","AttackSpeed","Evasion","Aim","LifeSteal"
|
||||
"0","0","10","","","3","30","0","1","12","0","0"
|
||||
"0","1","10","","","6","38","1.5","1","23","7","0"
|
||||
"0","2","10","","","8","43","3","1","34","14","0"
|
||||
"0","3","10","","","12","58","4.5","1","45","21","0"
|
||||
"0","4","10","","","17","67","6","1","56","28","0"
|
||||
"0","5","10","","","22","80","7.5","1","67","35","0"
|
||||
"0","6","10","","","30","109","9","1","78","42","0"
|
||||
"0","7","10","","","39","125","10.5","1","89","49","0"
|
||||
"0","8","10","","","46","141","12","1","100","56","0"
|
||||
"0","9","10","","","60","159","13.5","1","111","63","0"
|
||||
|
@@ -0,0 +1,136 @@
|
||||
# HEROLL 2.0.1 Good Tile 与 Corner 规则逆向报告
|
||||
|
||||
> 仅限本机内部玩法验证。本文只分析 HEROLL;其他项目资料不构成证据。
|
||||
|
||||
## 结论摘要
|
||||
|
||||
用户指定的六个 Good Tile 已闭合为六套独立状态机:Chest、Forge、Dice Battle、Lucky Scratch、Claw Machine、Dicereel。用户所说的“四类 Corner”不是 `newtile.csv` 中全部 Corner,而是 `ingamereward.csv` 基础四项 `126–129`:Piggy Bank、Race、Flower Garden、Housing Support。原作另有 Wall of Thorns、Black Market、Dice Catapult、Warp;本文列出它们用于防止配置误归类,但不把它们伪装成基础四类。
|
||||
|
||||
最重要的纠错:
|
||||
|
||||
- Chest 一次生成 **3 件**随机局内装备,不是旧验证表中的 1 件。
|
||||
- Dice Battle 没有“支付 3 点下注”的证据。配置 `3,10,2.5,5,10` 与原生字段更支持“开局 3 骰、首胜 10 点、连胜倍率 2.5/5/10”。
|
||||
- Lucky Scratch 对应 `GoodEventSpito(169)`,不是 `GoodEventLotto(142)`;后者是另一个 Drawing Lots/抽签事件。
|
||||
- Claw 2.0.1 配置为基础 `1` 次、`15` 秒;截图中的 2 次处于额外继续入口。社区资料所称“两次基础抓取”属于版本冲突,开发还原以本 APK 为准。
|
||||
- Dicereel 的 `value` 列不是概率。奖励由三骰配对/三连模式决定;不能拿 `20,25,50...` 归一化成掉率。
|
||||
|
||||
完整结构化规则见 [good-tile-rules.csv](tables/good-tile-rules.csv)、[corner-rules.csv](tables/corner-rules.csv) 与 [event-reward-tables.csv](tables/event-reward-tables.csv)。
|
||||
|
||||
## 1. 统一进入与退出框架
|
||||
|
||||
```text
|
||||
完成普通移动
|
||||
→ HandlePlayerTileLanding(tile)
|
||||
→ GetETileEvent(ETileEvent)
|
||||
→ ExecuteAsync(tile)
|
||||
→ 锁定下一次掷骰/移动
|
||||
→ 事件 UI 或被动 Corner 状态机
|
||||
→ 结果写入角色/棋盘状态
|
||||
→ 完成动画与回调
|
||||
→ ExecuteAsync 返回
|
||||
→ 恢复棋盘操作
|
||||
```
|
||||
|
||||
自然生成资格先受 `newtile.isEnabled/minStage/minLoop` 过滤;玩家安装地块则来自 `OutGameTile.refNewTileId` 牌组。两条入口进入的是同一事件执行器。`minLoop` 为零基索引,因此 `minLoop=3` 对应内部第 4 个 Loop,而不是可随意解释为 UI 第 3 层。
|
||||
|
||||
原作普遍使用 `isClick/isPicking/isRolling/canGrab/isResetting` 做重复输入保护。没有证据显示 2.0.1 会给局内小游戏建立独立、可恢复的事务快照;因此“进程被杀后精确恢复半局小游戏”不能写成原作规则。复刻时应在结果 RNG 产生后、表现前保存 `eventInstanceId + result + committed`,但这是工程防护,不是逆向确认的原作功能。
|
||||
|
||||
## 2. Good Tile 详细规则
|
||||
|
||||
### 2.1 Chest(141)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=0`;默认 Good Tile 牌组也包含其 Rare 版本。
|
||||
- 操作:打开宝箱;一次生成 3 个独立装备实例。装备使用正常局内生成器,因此等级、品质、词条仍服从装备掉落报告,而不是 Chest 专属固定表。
|
||||
- 成败:必定完成,无空奖失败分支。
|
||||
- 奖励:3 件装备同时进入常规掉落/比较流程;是否装备由玩家后续决定,未选择项按正常掉落处理。
|
||||
- 退出:三次生成与飞入表现结束后,事件回调返回;不能在只生成 1–2 件时恢复棋盘。
|
||||
- 异常:打开按钮需幂等;如果资产或生成器异常,原生只有空引用防崩路径,没有补偿表。复刻应把三件实例作为一个原子批次保存。
|
||||
|
||||
### 2.2 Forge(137)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=0`;落地创建一件 Normal 候选装备。
|
||||
- 操作:玩家在“直接领取”和“挑战强化”之间选择。强化成功后仍可领取或继续挑战。
|
||||
- 概率:当前 2.0.1/GDD 证据链采用 `80% → 50% → 30% → 10%` 四步。它支持从 Normal 逐步向更高品质推进;Arcane 是否可由 Forge 获得没有闭环,不能擅自加入。
|
||||
- 成功:候选装备升一档,继续显示下一档概率。
|
||||
- 失败:候选销毁,事件立即结束,不获得该装备。
|
||||
- 奖励:只有“直接领取”或最终停止时的当前候选装备。
|
||||
- 异常:强化点击必须在 RNG 结果写入后锁死;返回/重复点击不得重投。社区旧页记录 `80/50/10`,与当前四步版本冲突,本文不采用旧页覆盖 APK。
|
||||
|
||||
### 2.3 Dice Battle(143)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=3`;落地打开 `BlackJackView`。
|
||||
- 操作:玩家初始掷 3 颗 D6;可反复 `HIT` 增加一颗或 `STAND`。对手随后自动行动。
|
||||
- 判定:目标是不超过 21 且比对手更接近 21。玩家超过 21 立即失败。原生只有 `UserWin/DealerWin` 两个终局函数,未发现独立 Push 奖励;平局进入 DealerWin 是强推断,需一条平局录像才能升级为确认。
|
||||
- 奖励:首次连胜基础 10 点;`GetCalculatedReward = baseReward × GetStreakMultiplier + accumulatedBonus`。配置提供 2.5、5、10 三档连胜倍率。胜利后可领取或继续;失败丢失尚未领取的连胜奖励。
|
||||
- 退出:领取提交并关闭;继续会重置双方本手、保留 winStreak;失败关闭且无领取。
|
||||
- 异常:`isRolling` 时 HIT/STAND 禁用。奖励在领取时计算,不能在每次胜利同时发放再允许重试,否则会重复产出。
|
||||
|
||||
### 2.4 Lucky Scratch(169)
|
||||
|
||||
- 条件:`minStage=1/minLoop=3`;这也解释了它不会在第 1 关 Stage 0 自然出现。
|
||||
- 操作:奖励先按权重选定,玩家拖动擦除遮罩。`ScratchPainter` 达到 prefab 的 `revealThreshold` 后只触发一次 `OnRevealed`。
|
||||
- 奖励:一等奖 30 点/权重 10,二等奖 10 点/权重 50,三等奖 1 点/权重 40。总权重 100,无空奖。
|
||||
- 退出:揭示并展示奖励后回调结束。局内版本不应把 `GoodEventLotto` 的五次抽签成本带进来。
|
||||
- 异常:`isRevealed` 防重复;`OnDestroy` 清理渲染纹理和订阅。遮罩阈值是 prefab 序列化字段,当前归档没有给出可靠数字,必须以原资产值或实机标定,不能填造百分比。
|
||||
|
||||
### 2.5 Claw Machine(151)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=0`;进入时创建物理柜和胶囊。
|
||||
- 操作:抓钩自动横移;15 秒内按一次 `GRAB`,执行下落、闭爪、回程与投放。
|
||||
- 次数:2.0.1 基础值为 1。参考图中的“2 次”属于额外继续按钮;不应当作基础次数。
|
||||
- 胶囊:源表注明布局 20 个胶囊;一件 Legendary 装备为 guaranteed-good,位于底部。其余普通池按 `empty 40 / point 70 / potion 14 / Normal gear 40` 加权。Rare、Epic、祝福、药水祝福基础权重为 0,只有技能/额外状态可注入。
|
||||
- 成功:胶囊进入收集触发器才发对应奖励。夹起后途中掉落仍算失败。
|
||||
- 失败:时间到、回程无胶囊或抽到 empty 均不发奖。
|
||||
- 异常:`canGrab/isResetting` 阻止二次抓取,`OnDisable` 取消移动,奖励在 `OnCapsuleCollected` 触发,不在按键时预发。
|
||||
|
||||
### 2.6 Dicereel(164)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=3`。
|
||||
- 操作:启动三格骰面转轮;结果使用 1–6 六种图标。逻辑按任意一对或三连归类,三颗均不同为空奖。
|
||||
- 奖励:完整 13 行映射见 `event-reward-tables.csv`。三连优先于对子;对子行的 `-1` 表示第三颗必须不参与该对,而不是通配后把三连重复结算。
|
||||
- 免费结果:面 3 的对子给 1 次免费转,三连给 2 次;免费次数回到同一状态机,不重复进入地块。
|
||||
- 退出:本次结果动画完成且免费次数为 0 后结束。`isClick/isAnyFail` 防止重复停止或重复发奖。
|
||||
|
||||
## 3. 基础四类 Corner
|
||||
|
||||
### Piggy Bank(126)
|
||||
|
||||
它是跨回合被动容器。只要该 Corner 存在,每次正常双骰掷出对子 `A,A`,向罐内加入 **A** 点,而不是骰子和 `2A`。玩家落到 Piggy Bank 时一次性领取余额并清零。非对子没有失败提示,也不改变余额。
|
||||
|
||||
### Race(127)
|
||||
|
||||
落地后启动 3-roll 计数。玩家继续执行普通棋盘掷骰;在三次内到达/跨过 Start 即成功,获得 1 件 Legendary 局内装备。第三次结算后仍未到达则失败、无奖励。`TryAddCornerRace` 表明竞速不能叠加创建;成功或失败均清除覆盖层与计数。
|
||||
|
||||
### Flower Garden(128)
|
||||
|
||||
落地后把“前方下一整行”所有可转换普通格改成 Chest。它没有骰子判定、失败率或额外领取按钮。Corner、Start 与受保护地块不是转换目标。公开说明的“every tile”应理解为该行可变地块,而不是覆盖角落/起点控制格。
|
||||
|
||||
### Housing Support(129)
|
||||
|
||||
落地后玩家掷两颗独立 D6,以和 `A+B` 作为建房尝试数,在下一行的可用格建房;实际数量受可用格上限限制。随后按实际建成数给点数。原生分支确认双骰、位置映射、逐项建造和奖励阶段,但 APK 暴露表中没有房屋数到点数的可读映射,本地化 bundle 也只含空壳 `New Table_en`;因此“每房 1 点”只能作为实现候选,不能标成原作确认值。该项是本报告唯一会影响奖励量的残余未知。
|
||||
|
||||
## 4. 异常与恢复验收矩阵
|
||||
|
||||
| 场景 | 原作证据支持的行为 | 复刻验收要求 |
|
||||
|---|---|---|
|
||||
| 连点进入/结果按钮 | 各视图有 click/rolling/picking 状态锁 | 同一事件实例只生成一次结果 |
|
||||
| 切后台 | 异步状态仍等待;Claw 可取消移动 | 恢复时显示既定结果,不重抽 |
|
||||
| 动画中退出 | 原作无独立安全点证据 | 表现可重播,资源不可重发 |
|
||||
| 奖励生成异常 | 原生以空对象检查为主,无补偿表 | 保持事件未提交并允许安全重试 |
|
||||
| Claw 夹取途中销毁视图 | OnDisable 取消、未进收集区不发奖 | 不根据“抓钩曾接触”发奖 |
|
||||
| Scratch 重复达到阈值 | isRevealed 单次触发 | OnRevealed 必须幂等 |
|
||||
| Race 中断 | 未发现独立 race checkpoint | 复刻需保存 rollsLeft/active/rewarded |
|
||||
| Corner 批量改格中断 | 未发现半批次恢复 | 目标列表和改格结果应原子提交 |
|
||||
|
||||
## 5. 证据、冲突与残余未知
|
||||
|
||||
Evidence → Finding → Design:
|
||||
|
||||
1. `newtile/outgametile/outgametileskill` 与三个小游戏配置表 → 事件 ID、门槛、基础值、奖励映射 → 结构化规则表。
|
||||
2. IL2CPP metadata 与 31 个 ARM64 方法切片 → 独立事件类、输入锁、状态回调、奖励函数 → 状态机与异常矩阵。
|
||||
3. 用户 `局内说明/局内_part4` → Chest 三装备、Forge 80% UI、Scratch 30/10/1、Claw 额外次数层级 → 纠正旧 GDD 假设。
|
||||
4. 社区 Tiles 页 → 自然语言名称、Race 三次、Corner 效果、Chest 三件与旧版 Claw/Forge 文本 → 仅作语义交叉验证,不覆盖 2.0.1 配置。
|
||||
|
||||
残余未知只有两项:Housing Support 的精确点数换算;Dice Battle 平局是否由 DealerWin 处理。它们已明确标记,未用近似值冒充逆向结论。
|
||||
|
||||
公开交叉资料:[Heroll Wiki – Tiles](https://heroll.fandom.com/wiki/Tiles)。
|
||||
@@ -0,0 +1,12 @@
|
||||
# 02-地块与事件
|
||||
|
||||
Good Tile、Corner、事件奖励及运行规则。
|
||||
|
||||
## 文件
|
||||
|
||||
- [2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md](./2026-09-01_%E9%80%86%E5%90%91-HEROLL-GoodTile%E4%B8%8ECorner%E8%A7%84%E5%88%99-report.md) — report;来源:`analysis/tile-event-rules/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md`
|
||||
- [corner-rules.csv](./corner-rules.csv) — table;来源:`analysis/tile-event-rules/tables/corner-rules.csv`
|
||||
- [event-reward-tables.csv](./event-reward-tables.csv) — table;来源:`analysis/tile-event-rules/tables/event-reward-tables.csv`
|
||||
- [good-tile-rules.csv](./good-tile-rules.csv) — table;来源:`analysis/tile-event-rules/tables/good-tile-rules.csv`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,9 @@
|
||||
tile_id,source_id,display_name,group,min_stage,min_loop,entry,player_input,success_failure,reward_or_effect,exit_exception,confidence
|
||||
126,CornerDoubleStack,Piggy Bank,core_four,0,0,"corner exists on board; doubles are observed globally while it is present","none while charging; land on the bank to collect","no fail state; a non-double adds nothing","each double A=A adds A points to the bank, not 2A; landing transfers the full stored balance to player points and resets it to zero","passive state survives ordinary tile events; collection is one settlement; duplicate receipt must not pay twice",high
|
||||
127,CornerRace,Race,core_four,0,0,"landing starts a race only when no race is already active","make normal board rolls and reach/pass the Start tile within the next 3 rolls","success on reaching Start within 3 rolls; fail when the third roll ends without reaching Start","success gives one Legendary in-run gear; failure gives nothing","TryAddCornerRace prevents stacking; success/fail clears race overlay and counter; interrupted run has no separately proven race checkpoint",high
|
||||
128,CornerOneLineChest,Flower Garden,core_four,0,0,"landing resolves the next board row/line","no choice; transformation animation plays","no random failure","every transformable ordinary tile in the upcoming row becomes Chest; corner/start/protected tiles are not targets","event ends after line transformation; if no eligible target, it completes with zero changes; partial-animation crash behavior is not source-confirmed",high for effect; medium for empty-candidate fallback
|
||||
129,CornerDiceBuilding,Housing Support,core_four,0,0,"landing opens its two-dice construction event","roll two independent D6 once","no random failure; constructed count is capped by eligible spaces in the upcoming row","attempt to build A+B houses in the upcoming row and grant points according to actual houses constructed; exact point lookup/multiplier was not recoverable from exposed CSV/localization","dice/result input is single-flight; finishes after construction/reward animation; seed and chosen positions must be persisted in a reproduction",high for construction; partial for point amount
|
||||
125,CornerKillOneLineEnemy,Wall of Thorns,additional,0,0,"landing resolves upcoming row","none","no fail state","reduce enemy count on every Enemy tile in upcoming row by 1; zero-enemy tiles are not decremented below zero","immediate callback after mutation",high
|
||||
131,CornerBlackMarket,Black Market,additional,0,3,"eligible from zero-based loop 3; landing opens market","buy with points or exit","purchase only if affordable and not sold out","higher-price shop inventory; no reroll","purchase updates total and inventory; close cleans listeners",high
|
||||
167,CornerDiceCatapult,Dice Catapult,additional,0,5,"eligible from zero-based loop 5","event-specific launch input","not part of the requested core four; detailed reward path remains outside this work item","see source event class","normal event callback",not analyzed
|
||||
175,CornerWarp,Warp,additional,0,3,"eligible from zero-based loop 3; at most 3 per game by config","none","no fail state","move hero to a random board space and resolve warp movement rules","movement uses WarpTile visual/state path; destination-event chaining requires focused capture",medium-high
|
||||
|
@@ -0,0 +1,22 @@
|
||||
event,key,condition,reward,amount_or_weight,source
|
||||
Lucky Scratch,first_prize,preselected weighted result,point,30 at weight 10,newtile.csv values 30|10|1|10|50|40
|
||||
Lucky Scratch,second_prize,preselected weighted result,point,10 at weight 50,newtile.csv
|
||||
Lucky Scratch,third_prize,preselected weighted result,point,1 at weight 40,newtile.csv
|
||||
Claw Machine,guaranteed_good,one per layout,Legendary gear,1,newtile.csv plus clawcraneminigame.csv
|
||||
Claw Machine,normal_empty,normal capsule sample,none,weight 40,clawcraneminigame.csv
|
||||
Claw Machine,normal_point,normal capsule sample,point 1,weight 70,clawcraneminigame.csv
|
||||
Claw Machine,normal_potion,normal capsule sample,potion 1,weight 14,clawcraneminigame.csv
|
||||
Claw Machine,normal_gear,normal capsule sample,Normal gear 1,weight 40,clawcraneminigame.csv
|
||||
Dicereel,pair_face_1,exactly one pair,point,5,dicemachine.csv id0
|
||||
Dicereel,triple_face_1,triple,point,20,dicemachine.csv id6
|
||||
Dicereel,pair_face_2,exactly one pair,Normal gear,1,dicemachine.csv id1
|
||||
Dicereel,triple_face_2,triple,Rare gear,1,dicemachine.csv id7
|
||||
Dicereel,pair_face_3,exactly one pair,free spin,1,dicemachine.csv id2
|
||||
Dicereel,triple_face_3,triple,free spin,2,dicemachine.csv id8
|
||||
Dicereel,pair_face_4,exactly one pair,blessing,1,dicemachine.csv id3
|
||||
Dicereel,triple_face_4,triple,blessing,2,dicemachine.csv id9
|
||||
Dicereel,pair_face_5,exactly one pair,Good Tile,1,dicemachine.csv id4
|
||||
Dicereel,triple_face_5,triple,Good Tile,3,dicemachine.csv id10
|
||||
Dicereel,pair_face_6,exactly one pair,potion,1,dicemachine.csv id5
|
||||
Dicereel,triple_face_6,triple,potion,3,dicemachine.csv id11
|
||||
Dicereel,no_match,three distinct faces,none,0,dicemachine.csv id12
|
||||
|
@@ -0,0 +1,7 @@
|
||||
tile_id,source_id,display_name,min_stage,min_loop,entry,player_input,success,failure,reward,exit,exception_handling,confidence
|
||||
141,GoodEventChest,Chest,0,0,"land on installed/eligible tile; board movement is suspended","open chest; inspect three generated gear items; equip or leave each item","chest opening completes and all three gear instances are generated",none,"3 random in-run gear instances through the normal gear generator","event callback returns after spawn animation; gear decisions remain in the normal drop UI","open is debounced; no reward is committed before generation; no source evidence for mid-event crash restoration",high
|
||||
137,GoodEventSmithy,Forge,0,0,"land on installed/eligible tile; a new Normal gear instance is created","claim current item or challenge the next rarity; after success choose again","upgrade roll passes the current 80/50/30/10 step and the same item advances one rarity","failed upgrade destroys the candidate and ends the event","claimed candidate gear; failed candidate gives no gear","claim or failure resolves callback and returns to board","challenge is single-flight; result must be stored before animation; current binary exposes four steps but Arcane eligibility is not proven",high
|
||||
143,GoodEventBlackJack,Dice Battle,0,3,"tile is naturally eligible from zero-based loop 3; landing opens Deoksoon view","start with 3 dice; choose HIT to add one D6 or STAND; after a win collect or rematch","not bust and final total beats dealer while approaching 21","sum over 21 loses; native has only UserWin/DealerWin and no independent push reward path","first consecutive win 10 points; later wins use streak multipliers 2.5x/5x/10x; losing forfeits unclaimed streak reward","collect closes and commits; rematch resets hand but preserves streak; loss closes without reward","isRolling disables duplicate HIT/STAND; reward is calculated at claim; dealer tie policy is strong inference to DealerWin, pending one focused capture",medium-high
|
||||
169,GoodEventSpito,Lucky Scratch,1,3,"only Stage >=1 and zero-based loop >=3; landing opens a single scratch card","drag over the cover until ScratchPainter reaches revealThreshold","cover threshold reached; preselected prize is revealed","no losing outcome; the lowest prize is 1 point","30 points at 10%; 10 points at 50%; 1 point at 40%","reveal invokes the completion callback; tap/close returns after reward display","isRevealed prevents duplicate callbacks; OnDestroy releases scratch resources; prefab revealThreshold remains unresolved; no mid-card crash recovery evidence",high
|
||||
151,GoodEventClawGrab,Claw Machine,0,0,"land on installed/eligible tile; cabinet creates its capsule layout","within 15 seconds press GRAB once while claw auto-moves; drop/close/return is automatic","a capsule crosses the collection trigger and its payload is granted","timer expires or claw returns without a capsule; empty capsule also grants nothing","20-capsule source pool; one guaranteed Legendary gear capsule at the bottom; remaining normal pool weights empty40/point70/potion14/common gear40; base attempt 1","after return/reset and no remaining attempts, event callback returns","canGrab/isResetting debounce input; OnDisable cancels movement; reward commits only on collection trigger; community two-play text conflicts with current 1,15 config",high for current APK
|
||||
164,GoodEventDiceMachine,Dicereel,0,3,"tile is naturally eligible from zero-based loop 3; landing opens three reels","press reel control; three faces resolve; free-spin results repeat the same flow","pair or triple pattern matches a dicemachine row","all three faces different grants none","pair/triple: face1 point5/20; face2 Normal gear1/Rare gear1; face3 free spin1/2; face4 blessing1/2; face5 good tile1/3; face6 potion1/3","when result animation and any free spins finish, confirm/end callback returns to board","isClick/isAnyFail prevent duplicate finish; rewards spawn by typed dispatch; no source evidence for restoring a partially spinning reel after process death",high
|
||||
|
@@ -0,0 +1,27 @@
|
||||
"key","original_status","mvp_default","type","range","rationale","source","label"
|
||||
"enemyTilesPerLoop","serialized field confirmed; original scene value not recovered","3 attempts per normal loop","integer","0..40","keeps the board playable while preserving the real configuration entry","BoardController field + AddNextLoopTiles native call","DEMO default"
|
||||
"blackMarketSurchargePercent","formula confirmed; percentage unknown","50","integer percent","0..300","reproduces the former 1.5x demo while keeping the source formula","Black Market price native path","DEMO default"
|
||||
"bossPressureTargetCountWhenShort","normal target=4; shortage behavior unknown","require exactly 4 eligible distinct non-AUGMENT tiles; if fewer than 4, delay with no partial conversion and keep gauge full","rule","exactly 4","MVP does not downgrade the pressure action","DiceGauge reverse report + v0.2.8 design decision","MVP frozen"
|
||||
"bossPressureResolvedTile","restoration behavior unknown","convert resolved pressure tile to Empty; do not restore overwritten tile","enum","Empty","deterministic and avoids resurrecting consumed rewards","residual risk in stage-floor report","DEMO default"
|
||||
"bossPressureGaugeCycle","source normal path is 0->50->100","enter stage at 50; add 25 per completed player action; at 100 start 4-roll countdown; after pressure action reset to 0","rule","0..100","creates the approved initial 2-action then repeating 4-action pressure cycle","source reverse + v0.2.8 intentional deviation","MVP frozen"
|
||||
"bossPressureCounterUI","exact original presentation unknown","warning icon plus 4/3/2/1 countdown; never replace visible 0/50 progress","UI rule","hidden/off or warning","keeps three state variables distinct","runtime observation + reverse report","DEMO default"
|
||||
"combatDropDisplayCapacity","finite capacity confirmed; exact count unknown","10; when the 11th arrives replace the oldest unhandled drop FIFO with explicit feedback","integer","10","separates four equipped slots from the ten-item drop display","runtime observation + v0.2.8 design decision","MVP frozen"
|
||||
"randomShopDraw","3 random slots confirmed; full weighting/exclusion not closed","equal weight, without replacement, 3 offers","rule","0..3 visible","exclude disabled, sold-out, owned unique and unmet dependency offers","shop metadata/native partial","DEMO default"
|
||||
"shopTileInstallTarget","purchase exists; exact target selection not closed","random legal ordinary small tile; block purchase and do not charge if none","rule","eligible small tiles","atomic transaction and no reward loss","shop catalog + unresolved consumer","DEMO default"
|
||||
"augmentCandidateDraw","31 enabled all prob=10; runtime exclusion order partial","filter first, equal-weight without replacement, show exactly 3; if fewer than 3 treat as configuration error and block resolution","rule","exactly 3 visible","never fill with duplicates; all definitions return to the pool after selection and are filtered again next time","augment.csv + v0.2.8 design decision","MVP frozen"
|
||||
"augmentRerollNoRepeat","exact replacement exclusion unknown","replace all three; avoid the currently displayed IDs where pool permits","rule","once per event if enabled","prevents a no-op reroll","MVP interaction rule","DEMO default"
|
||||
"goodDeckFailedInstallConsumption","draw/deck behavior confirmed; failure consumption edge unknown","consume the drawn metadata attempt; reshuffle only after deck exhaustion","rule","boolean","preserves attempt semantics and deterministic RNG","GetNextMetadata/AddRandomGoodTiles partial","DEMO default"
|
||||
"integerAffixRandom","min/max formula confirmed; endpoint behavior not closed","uniform real draw over inclusive conceptual range, then round half up to integer","RNG rule","rounded integer","uses one explicit rounding policy","equipment reverse residual + v0.2.8 design decision","MVP frozen"
|
||||
"floatAffixRandom","one-decimal precision confirmed; endpoint behavior not closed","uniform real draw over inclusive conceptual range, then round half up to 0.1","RNG rule","rounded to 0.1","matches displayed precision","weaponstatus.csv + v0.2.8 design decision","MVP frozen"
|
||||
"maxHpDecreaseCurrentHp","consumer edge behavior unknown","currentHP=min(currentHP,newMaxHP), no damage/death event","rule","clamp","prevents equipment swap from triggering combat damage hooks","unresolved runtime edge","DEMO default"
|
||||
"attackSpeedChangeTiming","source uses real-time cooldown scheduling","apply to the next cooldown scheduled after the current attack completes; do not retroactively rescale an active attack or cooldown","rule","next cooldown","preserves deterministic scheduling in the source-aligned real-time model","combat native reverse + v0.2.8 decision","source-aligned edge rule"
|
||||
"bossMidFightDropHp","mid-fight drop observed; exact threshold/phase unknown","first crossing to HP <= 50%, once per boss fight","percent","1..99","documented v0.2.7 validation value","runtime observation","DEMO default"
|
||||
"normalEnemyDeathReward","death-time generation path confirmed; probabilities unknown","one weighted result: gear 95, potion 4, points 1","relative weights","95:4:1","stable validation economy","v0.2.7 frozen reward pacing","DEMO default"
|
||||
"eliteEnemyDeathReward","exact elite rule unknown","1 gear plus one extra result from potion:points=5:2","rule","fixed + weighted","stable elite differentiation","v0.2.7 frozen reward pacing","DEMO default"
|
||||
"floorPointReward","original loop rewards use different resources; MVP mapping is not source","10 + 5 * displayedFloor points","integer formula",">=15","closed local-run economy","v0.2.7 design","DEMO default"
|
||||
"originalRewardFloatRounding","stage multiplier rows confirmed; rounding unknown","floor after multiplication","rounding","nonnegative integer","single deterministic policy","ingamereward.csv residual","DEMO default"
|
||||
"finalStartRemainingSteps","boss branch exists; overflow movement edge not fully observed","preserve remainingSteps on boss-floor conversion; if zero require one additional Roll before Boss battle","rule",">=0","implements the approved Boss-board landing semantics","Start branch + v0.2.8 design decision","MVP frozen"
|
||||
"diceBattleTie","tie consumer not fully closed","dealer wins ties","enum","dealer/player/retry","standard house-edge fallback and single-exit state","GoodEventDiceBattle partial","DEMO default"
|
||||
"luckyScratchRevealThreshold","gesture completion threshold not recovered","65% revealed area","percent","50..90","prevents pixel-perfect scratching","GoodEventSpito UI residual","DEMO default"
|
||||
"forgeMaxQuality","80/50/30/10 steps confirmed; Arcane transition not closed","cap at Myth; Arcane cannot be forged","enum","Myth","four transitions from Normal align with four probabilities","Forge config/runtime residual","DEMO default"
|
||||
"housingRewardPerHouse","Housing Support rolls two independent D6 and rewards by actual houses built; exact house-to-point mapping is not recovered","1 spirit stone per successfully built house","integer","1","closes the construction event economy without presenting the value as an original rule","CornerDiceBuilding reverse + v0.2.8 design decision","DEMO default"
|
||||
|
@@ -0,0 +1,14 @@
|
||||
"key","value","execution_rule","source_status","source"
|
||||
"buildingCarrier","exterior house layer","A house is attached to a small tile's exterior slot and never replaces its movement tile, event, or enemy content","MVP frozen","v0.2.8 building-module decision"
|
||||
"exteriorSlotCapacity","1 per ordinary small tile","A slot is eligible only when it has no house and belongs to the configured upcoming board side","MVP frozen","v0.2.8 building-module decision"
|
||||
"housingSupportTileId","129","Landing on Housing Support opens the construction event and performs one two-die construction roll","source-aligned","newtile.csv + CornerDiceBuilding reverse"
|
||||
"baseConstructionAttempts","D6_A + D6_B","Roll two independent six-sided dice once; their sum is the number of base construction attempts","source-aligned","CornerDiceBuilding reverse"
|
||||
"urbanPlanningBlessingId","152","If owned, add 2 construction attempts once per Housing Support event; the blessing is unique and does not stack","source structure + MVP consumer freeze","augment.csv EmptyTripleBuild"
|
||||
"placementOrder","next clockwise board side","Starting after the Housing Support Corner, collect empty exterior slots on the following side and choose distinct slots without replacement using the run RNG seed","MVP executable edge","v0.2.8 geometry freeze"
|
||||
"actualBuiltCount","min(totalAttempts, eligibleSlotCount)","Every selected eligible slot succeeds; unused attempts are discarded","source-aligned cap + MVP edge","CornerDiceBuilding reverse + v0.2.8"
|
||||
"reward","actualBuiltCount * 1 spirit stone","Grant the reward after placement animation; the exact original reward conversion remains unknown","DEMO default","04-unknown-parameter-mvp-defaults.csv"
|
||||
"zeroEligibleSlots","build 0 and reward 0","Show a no-space result, complete the event, and do not reroll or relocate to another side","MVP frozen","v0.2.8 building-module decision"
|
||||
"persistence","until final Boss Floor","Houses survive loop/Floor progression and Good/Enemy/Empty mutations of the underlying tile because the exterior layer is independent","MVP frozen","v0.2.8 building-module decision"
|
||||
"ongoingEffect","none","A built house has no passive income, combat bonus, or tile-trigger modification in MVP","MVP scope freeze","v0.2.8 building-module decision"
|
||||
"finalBossCleanup","clear every exterior house","Clear houses in the same board-conversion transaction that replaces all 44 positions with Boss Tiles","MVP frozen","v0.2.8 final Boss rule"
|
||||
"saveState","slot occupancy + construction RNG result","Persist occupied slot IDs, both dice values, selected slot IDs, reward, seed, and ruleset version at the event safety point","MVP frozen","v0.2.8 determinism requirement"
|
||||
|
@@ -0,0 +1,136 @@
|
||||
# HEROLL 2.0.1 Good Tile 与 Corner 规则逆向报告
|
||||
|
||||
> 仅限本机内部玩法验证。本文只分析 HEROLL;其他项目资料不构成证据。
|
||||
|
||||
## 结论摘要
|
||||
|
||||
用户指定的六个 Good Tile 已闭合为六套独立状态机:Chest、Forge、Dice Battle、Lucky Scratch、Claw Machine、Dicereel。用户所说的“四类 Corner”不是 `newtile.csv` 中全部 Corner,而是 `ingamereward.csv` 基础四项 `126–129`:Piggy Bank、Race、Flower Garden、Housing Support。原作另有 Wall of Thorns、Black Market、Dice Catapult、Warp;本文列出它们用于防止配置误归类,但不把它们伪装成基础四类。
|
||||
|
||||
最重要的纠错:
|
||||
|
||||
- Chest 一次生成 **3 件**随机局内装备,不是旧验证表中的 1 件。
|
||||
- Dice Battle 没有“支付 3 点下注”的证据。配置 `3,10,2.5,5,10` 与原生字段更支持“开局 3 骰、首胜 10 点、连胜倍率 2.5/5/10”。
|
||||
- Lucky Scratch 对应 `GoodEventSpito(169)`,不是 `GoodEventLotto(142)`;后者是另一个 Drawing Lots/抽签事件。
|
||||
- Claw 2.0.1 配置为基础 `1` 次、`15` 秒;截图中的 2 次处于额外继续入口。社区资料所称“两次基础抓取”属于版本冲突,开发还原以本 APK 为准。
|
||||
- Dicereel 的 `value` 列不是概率。奖励由三骰配对/三连模式决定;不能拿 `20,25,50...` 归一化成掉率。
|
||||
|
||||
完整结构化规则见 [good-tile-rules.csv](tables/good-tile-rules.csv)、[corner-rules.csv](tables/corner-rules.csv) 与 [event-reward-tables.csv](tables/event-reward-tables.csv)。
|
||||
|
||||
## 1. 统一进入与退出框架
|
||||
|
||||
```text
|
||||
完成普通移动
|
||||
→ HandlePlayerTileLanding(tile)
|
||||
→ GetETileEvent(ETileEvent)
|
||||
→ ExecuteAsync(tile)
|
||||
→ 锁定下一次掷骰/移动
|
||||
→ 事件 UI 或被动 Corner 状态机
|
||||
→ 结果写入角色/棋盘状态
|
||||
→ 完成动画与回调
|
||||
→ ExecuteAsync 返回
|
||||
→ 恢复棋盘操作
|
||||
```
|
||||
|
||||
自然生成资格先受 `newtile.isEnabled/minStage/minLoop` 过滤;玩家安装地块则来自 `OutGameTile.refNewTileId` 牌组。两条入口进入的是同一事件执行器。`minLoop` 为零基索引,因此 `minLoop=3` 对应内部第 4 个 Loop,而不是可随意解释为 UI 第 3 层。
|
||||
|
||||
原作普遍使用 `isClick/isPicking/isRolling/canGrab/isResetting` 做重复输入保护。没有证据显示 2.0.1 会给局内小游戏建立独立、可恢复的事务快照;因此“进程被杀后精确恢复半局小游戏”不能写成原作规则。复刻时应在结果 RNG 产生后、表现前保存 `eventInstanceId + result + committed`,但这是工程防护,不是逆向确认的原作功能。
|
||||
|
||||
## 2. Good Tile 详细规则
|
||||
|
||||
### 2.1 Chest(141)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=0`;默认 Good Tile 牌组也包含其 Rare 版本。
|
||||
- 操作:打开宝箱;一次生成 3 个独立装备实例。装备使用正常局内生成器,因此等级、品质、词条仍服从装备掉落报告,而不是 Chest 专属固定表。
|
||||
- 成败:必定完成,无空奖失败分支。
|
||||
- 奖励:3 件装备同时进入常规掉落/比较流程;是否装备由玩家后续决定,未选择项按正常掉落处理。
|
||||
- 退出:三次生成与飞入表现结束后,事件回调返回;不能在只生成 1–2 件时恢复棋盘。
|
||||
- 异常:打开按钮需幂等;如果资产或生成器异常,原生只有空引用防崩路径,没有补偿表。复刻应把三件实例作为一个原子批次保存。
|
||||
|
||||
### 2.2 Forge(137)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=0`;落地创建一件 Normal 候选装备。
|
||||
- 操作:玩家在“直接领取”和“挑战强化”之间选择。强化成功后仍可领取或继续挑战。
|
||||
- 概率:当前 2.0.1/GDD 证据链采用 `80% → 50% → 30% → 10%` 四步。它支持从 Normal 逐步向更高品质推进;Arcane 是否可由 Forge 获得没有闭环,不能擅自加入。
|
||||
- 成功:候选装备升一档,继续显示下一档概率。
|
||||
- 失败:候选销毁,事件立即结束,不获得该装备。
|
||||
- 奖励:只有“直接领取”或最终停止时的当前候选装备。
|
||||
- 异常:强化点击必须在 RNG 结果写入后锁死;返回/重复点击不得重投。社区旧页记录 `80/50/10`,与当前四步版本冲突,本文不采用旧页覆盖 APK。
|
||||
|
||||
### 2.3 Dice Battle(143)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=3`;落地打开 `BlackJackView`。
|
||||
- 操作:玩家初始掷 3 颗 D6;可反复 `HIT` 增加一颗或 `STAND`。对手随后自动行动。
|
||||
- 判定:目标是不超过 21 且比对手更接近 21。玩家超过 21 立即失败。原生只有 `UserWin/DealerWin` 两个终局函数,未发现独立 Push 奖励;平局进入 DealerWin 是强推断,需一条平局录像才能升级为确认。
|
||||
- 奖励:首次连胜基础 10 点;`GetCalculatedReward = baseReward × GetStreakMultiplier + accumulatedBonus`。配置提供 2.5、5、10 三档连胜倍率。胜利后可领取或继续;失败丢失尚未领取的连胜奖励。
|
||||
- 退出:领取提交并关闭;继续会重置双方本手、保留 winStreak;失败关闭且无领取。
|
||||
- 异常:`isRolling` 时 HIT/STAND 禁用。奖励在领取时计算,不能在每次胜利同时发放再允许重试,否则会重复产出。
|
||||
|
||||
### 2.4 Lucky Scratch(169)
|
||||
|
||||
- 条件:`minStage=1/minLoop=3`;这也解释了它不会在第 1 关 Stage 0 自然出现。
|
||||
- 操作:奖励先按权重选定,玩家拖动擦除遮罩。`ScratchPainter` 达到 prefab 的 `revealThreshold` 后只触发一次 `OnRevealed`。
|
||||
- 奖励:一等奖 30 点/权重 10,二等奖 10 点/权重 50,三等奖 1 点/权重 40。总权重 100,无空奖。
|
||||
- 退出:揭示并展示奖励后回调结束。局内版本不应把 `GoodEventLotto` 的五次抽签成本带进来。
|
||||
- 异常:`isRevealed` 防重复;`OnDestroy` 清理渲染纹理和订阅。遮罩阈值是 prefab 序列化字段,当前归档没有给出可靠数字,必须以原资产值或实机标定,不能填造百分比。
|
||||
|
||||
### 2.5 Claw Machine(151)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=0`;进入时创建物理柜和胶囊。
|
||||
- 操作:抓钩自动横移;15 秒内按一次 `GRAB`,执行下落、闭爪、回程与投放。
|
||||
- 次数:2.0.1 基础值为 1。参考图中的“2 次”属于额外继续按钮;不应当作基础次数。
|
||||
- 胶囊:源表注明布局 20 个胶囊;一件 Legendary 装备为 guaranteed-good,位于底部。其余普通池按 `empty 40 / point 70 / potion 14 / Normal gear 40` 加权。Rare、Epic、祝福、药水祝福基础权重为 0,只有技能/额外状态可注入。
|
||||
- 成功:胶囊进入收集触发器才发对应奖励。夹起后途中掉落仍算失败。
|
||||
- 失败:时间到、回程无胶囊或抽到 empty 均不发奖。
|
||||
- 异常:`canGrab/isResetting` 阻止二次抓取,`OnDisable` 取消移动,奖励在 `OnCapsuleCollected` 触发,不在按键时预发。
|
||||
|
||||
### 2.6 Dicereel(164)
|
||||
|
||||
- 条件:启用,`minStage=0/minLoop=3`。
|
||||
- 操作:启动三格骰面转轮;结果使用 1–6 六种图标。逻辑按任意一对或三连归类,三颗均不同为空奖。
|
||||
- 奖励:完整 13 行映射见 `event-reward-tables.csv`。三连优先于对子;对子行的 `-1` 表示第三颗必须不参与该对,而不是通配后把三连重复结算。
|
||||
- 免费结果:面 3 的对子给 1 次免费转,三连给 2 次;免费次数回到同一状态机,不重复进入地块。
|
||||
- 退出:本次结果动画完成且免费次数为 0 后结束。`isClick/isAnyFail` 防止重复停止或重复发奖。
|
||||
|
||||
## 3. 基础四类 Corner
|
||||
|
||||
### Piggy Bank(126)
|
||||
|
||||
它是跨回合被动容器。只要该 Corner 存在,每次正常双骰掷出对子 `A,A`,向罐内加入 **A** 点,而不是骰子和 `2A`。玩家落到 Piggy Bank 时一次性领取余额并清零。非对子没有失败提示,也不改变余额。
|
||||
|
||||
### Race(127)
|
||||
|
||||
落地后启动 3-roll 计数。玩家继续执行普通棋盘掷骰;在三次内到达/跨过 Start 即成功,获得 1 件 Legendary 局内装备。第三次结算后仍未到达则失败、无奖励。`TryAddCornerRace` 表明竞速不能叠加创建;成功或失败均清除覆盖层与计数。
|
||||
|
||||
### Flower Garden(128)
|
||||
|
||||
落地后把“前方下一整行”所有可转换普通格改成 Chest。它没有骰子判定、失败率或额外领取按钮。Corner、Start 与受保护地块不是转换目标。公开说明的“every tile”应理解为该行可变地块,而不是覆盖角落/起点控制格。
|
||||
|
||||
### Housing Support(129)
|
||||
|
||||
落地后玩家掷两颗独立 D6,以和 `A+B` 作为建房尝试数,在下一行的可用格建房;实际数量受可用格上限限制。随后按实际建成数给点数。原生分支确认双骰、位置映射、逐项建造和奖励阶段,但 APK 暴露表中没有房屋数到点数的可读映射,本地化 bundle 也只含空壳 `New Table_en`;因此“每房 1 点”只能作为实现候选,不能标成原作确认值。该项是本报告唯一会影响奖励量的残余未知。
|
||||
|
||||
## 4. 异常与恢复验收矩阵
|
||||
|
||||
| 场景 | 原作证据支持的行为 | 复刻验收要求 |
|
||||
|---|---|---|
|
||||
| 连点进入/结果按钮 | 各视图有 click/rolling/picking 状态锁 | 同一事件实例只生成一次结果 |
|
||||
| 切后台 | 异步状态仍等待;Claw 可取消移动 | 恢复时显示既定结果,不重抽 |
|
||||
| 动画中退出 | 原作无独立安全点证据 | 表现可重播,资源不可重发 |
|
||||
| 奖励生成异常 | 原生以空对象检查为主,无补偿表 | 保持事件未提交并允许安全重试 |
|
||||
| Claw 夹取途中销毁视图 | OnDisable 取消、未进收集区不发奖 | 不根据“抓钩曾接触”发奖 |
|
||||
| Scratch 重复达到阈值 | isRevealed 单次触发 | OnRevealed 必须幂等 |
|
||||
| Race 中断 | 未发现独立 race checkpoint | 复刻需保存 rollsLeft/active/rewarded |
|
||||
| Corner 批量改格中断 | 未发现半批次恢复 | 目标列表和改格结果应原子提交 |
|
||||
|
||||
## 5. 证据、冲突与残余未知
|
||||
|
||||
Evidence → Finding → Design:
|
||||
|
||||
1. `newtile/outgametile/outgametileskill` 与三个小游戏配置表 → 事件 ID、门槛、基础值、奖励映射 → 结构化规则表。
|
||||
2. IL2CPP metadata 与 31 个 ARM64 方法切片 → 独立事件类、输入锁、状态回调、奖励函数 → 状态机与异常矩阵。
|
||||
3. 用户 `局内说明/局内_part4` → Chest 三装备、Forge 80% UI、Scratch 30/10/1、Claw 额外次数层级 → 纠正旧 GDD 假设。
|
||||
4. 社区 Tiles 页 → 自然语言名称、Race 三次、Corner 效果、Chest 三件与旧版 Claw/Forge 文本 → 仅作语义交叉验证,不覆盖 2.0.1 配置。
|
||||
|
||||
残余未知只有两项:Housing Support 的精确点数换算;Dice Battle 平局是否由 DealerWin 处理。它们已明确标记,未用近似值冒充逆向结论。
|
||||
|
||||
公开交叉资料:[Heroll Wiki – Tiles](https://heroll.fandom.com/wiki/Tiles)。
|
||||
@@ -0,0 +1,12 @@
|
||||
# 03-建筑
|
||||
|
||||
地块外侧房屋、营造司掷骰、都市计划、建设奖励、持久化与终局清理。
|
||||
|
||||
## 文件
|
||||
|
||||
- [04-unknown-parameter-mvp-defaults.csv](./04-unknown-parameter-mvp-defaults.csv) — contract;来源:`analysis/mvp-rules-closure/04-unknown-parameter-mvp-defaults.csv`
|
||||
- [06-building-rules.csv](./06-building-rules.csv) — contract;来源:`analysis/mvp-rules-closure/06-building-rules.csv`
|
||||
- [corner-rules.csv](./corner-rules.csv) — table;来源:`analysis/tile-event-rules/tables/corner-rules.csv`
|
||||
- [Housing Support逆向依据.md](./Housing%20Support%E9%80%86%E5%90%91%E4%BE%9D%E6%8D%AE.md) — report;来源:`analysis/tile-event-rules/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,9 @@
|
||||
tile_id,source_id,display_name,group,min_stage,min_loop,entry,player_input,success_failure,reward_or_effect,exit_exception,confidence
|
||||
126,CornerDoubleStack,Piggy Bank,core_four,0,0,"corner exists on board; doubles are observed globally while it is present","none while charging; land on the bank to collect","no fail state; a non-double adds nothing","each double A=A adds A points to the bank, not 2A; landing transfers the full stored balance to player points and resets it to zero","passive state survives ordinary tile events; collection is one settlement; duplicate receipt must not pay twice",high
|
||||
127,CornerRace,Race,core_four,0,0,"landing starts a race only when no race is already active","make normal board rolls and reach/pass the Start tile within the next 3 rolls","success on reaching Start within 3 rolls; fail when the third roll ends without reaching Start","success gives one Legendary in-run gear; failure gives nothing","TryAddCornerRace prevents stacking; success/fail clears race overlay and counter; interrupted run has no separately proven race checkpoint",high
|
||||
128,CornerOneLineChest,Flower Garden,core_four,0,0,"landing resolves the next board row/line","no choice; transformation animation plays","no random failure","every transformable ordinary tile in the upcoming row becomes Chest; corner/start/protected tiles are not targets","event ends after line transformation; if no eligible target, it completes with zero changes; partial-animation crash behavior is not source-confirmed",high for effect; medium for empty-candidate fallback
|
||||
129,CornerDiceBuilding,Housing Support,core_four,0,0,"landing opens its two-dice construction event","roll two independent D6 once","no random failure; constructed count is capped by eligible spaces in the upcoming row","attempt to build A+B houses in the upcoming row and grant points according to actual houses constructed; exact point lookup/multiplier was not recoverable from exposed CSV/localization","dice/result input is single-flight; finishes after construction/reward animation; seed and chosen positions must be persisted in a reproduction",high for construction; partial for point amount
|
||||
125,CornerKillOneLineEnemy,Wall of Thorns,additional,0,0,"landing resolves upcoming row","none","no fail state","reduce enemy count on every Enemy tile in upcoming row by 1; zero-enemy tiles are not decremented below zero","immediate callback after mutation",high
|
||||
131,CornerBlackMarket,Black Market,additional,0,3,"eligible from zero-based loop 3; landing opens market","buy with points or exit","purchase only if affordable and not sold out","higher-price shop inventory; no reroll","purchase updates total and inventory; close cleans listeners",high
|
||||
167,CornerDiceCatapult,Dice Catapult,additional,0,5,"eligible from zero-based loop 5","event-specific launch input","not part of the requested core four; detailed reward path remains outside this work item","see source event class","normal event callback",not analyzed
|
||||
175,CornerWarp,Warp,additional,0,3,"eligible from zero-based loop 3; at most 3 per game by config","none","no fail state","move hero to a random board space and resolve warp movement rules","movement uses WarpTile visual/state path; destination-event chaining requires focused capture",medium-high
|
||||
|
@@ -0,0 +1,182 @@
|
||||
# HEROLL 2.0.1 战斗规则与 Double 影响逆向报告
|
||||
|
||||
> 分析日期:2026-08-28
|
||||
> 目标:HEROLL : Dice Roguelike 2.0.1(Android / Unity IL2CPP / ARM64)
|
||||
> 结论用途:HEROLL 本地玩法验证 MVP
|
||||
> 证据标签:`NATIVE_CONFIRMED` 原生指令闭合;`CONFIG_CONFIRMED` 源表确认;`VIDEO_CONFIRMED` 录像确认;`COMMUNITY_CROSSCHECK` 社区交叉验证;`PARTIAL` 仍有未闭合分支。
|
||||
|
||||
## 1. 执行摘要
|
||||
|
||||
本次从解密后 `libil2cpp.runtime-decrypted.so` 的真实 ARM64 方法体、IL2CPP 方法地址表、CSV 配置和原作录像中重建了主线战斗核心。可以直接用于 MVP 的闭合结论是:
|
||||
|
||||
1. 玩家基础攻击取最终攻击力;敌人攻击在自身攻击区间上叠加 `EnemyDamgeRange=15` 的浮动。
|
||||
2. 命中、暴击和反击是三次独立判定,不能共用一个随机结果。旧报告把 `0x549B934` 误当暴击 RNG;该点实际是命中/闪避 RNG。
|
||||
3. 暴击率判定为 `CR > RandomInt(0,101)`;基础暴伤为 150%,暴击伤害为 `damage * criticalDamagePercent / 100`。
|
||||
4. 防御是线性减伤:`max(0, 防御前伤害 - 最终防御)`,不是比例减伤。
|
||||
5. 攻速换算为 `攻击间隔秒 = 100 / 最终攻速`;裸装攻速 100 对应 1.0 秒基础间隔。
|
||||
6. 吸血为 `ceil(本次最终伤害 * 吸血% / 100)`,只要计算值为正,最低恢复 1 HP。
|
||||
7. Double 的基础含义只是“两骰相等”并广播 Double 事件;移动仍为 `diceA + diceB`,不会自动再×2,也没有无条件伤害倍率。
|
||||
8. Double 对战斗的影响来自已获得的遗物、Joker、宠物或武器封印等条件消费者,不是全局基础规则。
|
||||
|
||||
## 2. 目标与范围
|
||||
|
||||
- 授权与边界:[`work/heroll-stage-2-5/scope.md`](../../work/heroll-stage-2-5/scope.md)
|
||||
- 主样本:`work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so`
|
||||
- SHA-256:`AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA`
|
||||
- 工具:radare2 6.2.0;IDA 启动脚本已实际执行,但本机未配置 `IDADIR` 且未发现 IDA Pro,因此未伪造 IDA 输出。
|
||||
- 网络:本地证据不足以恢复遗物的用户文案时,使用 Heroll Wiki 和玩家实测帖交叉验证;互联网证据不替代原生证据。
|
||||
|
||||
## 3. 可实现的战斗公式
|
||||
|
||||
| 环节 | 原作规则 / 公式 | 边界与取整 | 证据 | 置信度 |
|
||||
|---|---|---|---|---|
|
||||
| 裸装初始值 | ATK 20,HP 500,AIM 1.5,DEF 10,EVA 1,Counter 10,Attack Speed 100,Crit Rate 10,Life Steal 0 | 浮点状态 | `battleplayerdefaultstat.csv` | 高 |
|
||||
| 最终属性 | 常规路径为 `independentBonus + flatSum * (100 + percentBonus) / 100`,再经特殊模式修正 | 某些调用可请求“仅 flat+independent”或扣除特定层 | `CharacterStatus.GetFinalStatus @ 0x5409B54` | 中高 |
|
||||
| 玩家基础伤害 | `baseDamage = GetFinalStatus(ATTACK_POWER)` | 此阶段不做随机浮动 | `BaseActor.GetBaseDamageAndConvertWithPlayerDamage @ 0x5494CD8` | 高 |
|
||||
| 敌人基础伤害 | 根据攻击状态上/下界做浮点随机;配置浮动为 ±15% | 随机边界由浮点 Range 实现 | 同上 + `EnemyDamgeRange=15` | 高 |
|
||||
| 命中 | `hit = hitPercent > RandomInt(0,101)` | RNG 为 0..100;`hitPercent<=roll` 失败;负的 hitPercent 先归 0 | `BaseMonoCharacter.HitAndGetResult @ 0x549B2CC` | 高(判定)/中(hitPercent 合成) |
|
||||
| 暴击 | `critical = finalCritRate > RandomInt(0,101)` | 0..100,严格大于;10 对应 10/101≈9.901% | `BaseMonoPlayer.OnBeforeAttack @ 0x55A95EC` | 高 |
|
||||
| 暴击伤害 | `damage = damage * GetCriticalDamagePercent() * 0.01` | `BaseCritical=150`,即裸配 1.5×;常数 `0x1EB7214=0.01f` | `0x55A9704..0x55A9728` | 高 |
|
||||
| 防御减伤 | `finalDamage = max(0, preDefenseDamage - finalDefense)` | 伤害保留 float;字体/日志可单独取整 | `0x549BB14..0x549BD9C` | 高 |
|
||||
| HP 扣除 | `targetHP = targetHP - finalDamage` | 证据中未见在扣 HP 前对伤害做整数化 | `0x549BE7C..0x549BE94` | 高 |
|
||||
| 攻速 | `interval = 1 / (finalAttackSpeed * 0.01) = 100/finalAttackSpeed` | 协程再减去已经过的时间;剩余时间≤0 则立即继续 | `<WaitAttackCooldown>d__45.MoveNext @ 0x5497280` | 高 |
|
||||
| 吸血 | `heal = ceil(finalDamage * finalLifeSteal * 0.01)` | `heal>0` 时最低 1;调用 `CharacterStatus.Heal` | `BaseMonoPlayer.OnAfterAttack @ 0x55A9908`, `0x55A9E48..0x55A9EC0` | 高 |
|
||||
| 反击触发 | `counter = finalCounterRate >= RandomInt(1,101)` | RNG 为 1..100,因此 10 就是精确 10% | `BaseMonoPlayer.OnCounterAttack @ 0x55ABEE0` | 高 |
|
||||
| 反击伤害 | 以本次敌方攻击/受到伤害链构建反击 `DamageMeta`,再走命中、暴击和对方防御 | 玩家仍承受原伤害;无伤害护盾可不触发;玩家实测表明反击不触发吸血 | 原生部分闭合 + 社区实测 | 中高 |
|
||||
|
||||
### 3.1 概率边界必须照原作实现
|
||||
|
||||
原作没有统一使用“0..99 小于百分比”。三种判定的边界不同:
|
||||
|
||||
```text
|
||||
命中: hitPercent > random(0..100)
|
||||
暴击: critRate > random(0..100)
|
||||
反击: counterRate >= random(1..100)
|
||||
```
|
||||
|
||||
因此 MVP 若用 `Math.random()*100 < rate` 同时替代三者,会产生边界差异。特别是暴击率 100 在原作中仍会在 roll=100 时失败;只有大于 100 才能在该路径保证暴击。
|
||||
|
||||
### 3.2 伤害数据流
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AP["最终攻击力 / 敌人浮动攻击"] --> META["DamageMeta.damage"]
|
||||
META --> HIT{"命中判定"}
|
||||
HIT -- "miss" --> ZERO["0 伤害"]
|
||||
HIT -- "hit" --> CRIT{"暴击判定"}
|
||||
CRIT -- "yes" --> CMUL["× 暴伤% / 100"]
|
||||
CRIT -- "no" --> HOOK["攻击/受击钩子"]
|
||||
CMUL --> HOOK
|
||||
HOOK --> DEF["max(0, damage - 最终DEF)"]
|
||||
DEF --> HP["HP -= finalDamage"]
|
||||
HP --> LS["ceil(finalDamage × 吸血% / 100)"]
|
||||
```
|
||||
|
||||
注:`TOTAL_DAMAGE`、`TRUE_DAMAGE`、装备/遗物钩子会在链中插入修正,但不应在没有闭合每个消费者时压成一条伪精确的总公式。
|
||||
|
||||
## 4. Double 对战斗的真实影响
|
||||
|
||||
### 4.1 Double 基础规则
|
||||
|
||||
1. `dicerate.csv` 包含 36 个有序 D6 组合,APK 内置权重全为 10。原生代码按 `weight/sum(weight)` 抽取。在没有远程覆盖时,每个有序结果为 1/36,自然 Double 概率为 6/36=1/6。
|
||||
2. `isDouble = (diceA == diceB) OR forcedDoubleBranch`。原作存在独立的强制 Double 分支,但当前启用内容中 `Potion_GuaranteedDouble` 为禁用。
|
||||
3. `moveCount = diceA + diceB`。录像中 1+1 显示总点数 2,不是 4。
|
||||
4. Double 发生后,第一枚骰子的值传入 `BoardController.TryAddDoubleStack(diceA)`;录像中 1+1 后显示“Double 点数 +1”。这是“累计骰面点数”,不应实现成每次 Double 固定 +1。
|
||||
5. `EventManager.TriggerOnDiceDouble` 会广播事件,各个已装备内容自行订阅;基础战斗公式中没有“Double 直接伤害×2”。
|
||||
|
||||
### 4.2 条件性战斗效果
|
||||
|
||||
| 来源 | 配置技能 | Double 效果 | 数值 | 证据等级 |
|
||||
|---|---|---|---:|---|
|
||||
| Scissors(剪刀)遗物 | `DoubleAttack` | Double 时对敌人发动一次基于 ATK 的攻击 | 100% ATK | 配置 + Wiki |
|
||||
| Scissors 传奇效果 | `DoubleAttackEnforce` | Double 时按骰面点数增加额外攻击次数 | 次数与 dot count 相关 | Wiki;精确次数还需动态验证 |
|
||||
| Chilled Tome(寒冰书) | `DoubleFreeze` | Double 时冻结敌人 | 1 s | 配置 + Wiki |
|
||||
| Chilled Tome 传奇效果 | `DoubleFreezeEnforce` | 增加 Double 冻结时长 | +1 s | 配置 + Wiki |
|
||||
| Battleship Horn(号角) | `DoubleAspdUp` | Double 时攻速提高 | +30% | 配置 + Wiki;持续时间未静态闭合 |
|
||||
| Gas Mask(防毒面具) | `DoubleShield` | Double 时有概率获得护盾 | 50% 触发概率 | 配置 + Wiki;护盾量未闭合 |
|
||||
| Rejuvenate Tea(恢复茶) | `DoubleBonusStat` | Double 时永久提升一项随机基础属性 | +10% | 配置 + Wiki |
|
||||
| Monster Dice(怪物骰子) | `DoubleExecute` | Double 后抵达敌人格时,概率处决 1 个敌人 | 35% | 配置 + Wiki |
|
||||
| Joker | `DoubleRollPoints` | Double 时获得额外点数,可间接与 `PointToAttackPower` 构筑联动 | Normal +2 / Hero +5 / Legend +10 | `joker.csv` + `OnDiceDoubleHandler` |
|
||||
| 宠物 | `BasePet.CheckDoubleDice` / `Pet_DoubleAttack` | 部分宠物在 Double 后进入自身攻击链 | 取决于宠物 | 元数据方法链,数值未闭合 |
|
||||
| 武器封印负面事件 | `OnWeaponSealDoubleHandler` | Double 增加解封计数 | 取决于事件配置 | 元数据方法链 |
|
||||
|
||||
### 4.3 不应加入 MVP 的伪规则
|
||||
|
||||
- 不要把 Double 做成移动点数×2。
|
||||
- 不要把 Double 做成无条件伤害×2。
|
||||
- 不要把“随机基础属性 +10%”与“下次战斗先攻”做成全局 Double 规则。前者是 Rejuvenate Tea 遗物的稀有效果;当前证据不支持后者是原作基础规则。
|
||||
- 不要将 `DoubleHeal` 名称直接解读为“骰子 Double 回血”。该 Augment 的现有调用链没有证明其订阅 `OnDiceDouble`;更可能是“治疗事件二次结算概率”,在未闭合前不纳入 Double 基础链。
|
||||
|
||||
## 5. 对现有 GDD / MVP 的覆盖修正
|
||||
|
||||
| 位置 | 现有内容 | 覆盖结论 |
|
||||
|---|---|---|
|
||||
| `Heroll_Gameplay_Validation_GDD.md` Double 段 | 对子统一触发“机缘”、随机属性 +10%和下次先攻 | 与原作不符。删除全局规则;将 +10% 放回 Rejuvenate Tea 遗物条件。 |
|
||||
| `formula-fit.csv` 吸血 | `floor(finalDamage*lifeStealPct/100)` | 改为 `ceil(finalDamage*lifeStealPct/100)`,正数最低 1。 |
|
||||
| `formula-fit.csv` 攻速 | 候选 `max(0.15,1/(attackSpeed/100))` | 原生主干已证明 `100/attackSpeed`;未见全局 0.15 s 下限,不应擅自加 clamp。 |
|
||||
| 暴击 RNG 旧结论 | `0x549B934` | 该地址是命中 RNG;暴击在 `0x55A96C4..0x55A98C0`。 |
|
||||
|
||||
## 6. Evidence → Finding → Path
|
||||
|
||||
### 6.1 Evidence
|
||||
|
||||
| E-id | source_ref | 可复现内容 | content_hash |
|
||||
|---|---|---|---|
|
||||
| E-COMBAT-001 | `libil2cpp.runtime-decrypted.so` + `all_method_addresses.csv` | 用 radare2 按 RVA 反汇编 `GetFinalStatus` / `HitAndGetResult` / `OnBeforeAttack` / `OnAfterAttack` / `OnCounterAttack` | SO SHA-256 见第 2 节 |
|
||||
| E-COMBAT-002 | `analysis/combat-rules/native-slices/` | 独立 ARM64 切片;例:`radare2 -q -a arm -b 64 -m 0x5412454 -c "pd 253" CharacterStatus_GetPlayerEvasionPercent.bin` | 各切片 SHA-256 见目录中文件固定值 |
|
||||
| E-COMBAT-003 | `battleplayerdefaultstat.csv`, `gameconfig.csv` | 裸装数值、`BaseCritical=150`、`EnemyDamgeRange=15` | `35DAC0A6...32D8`, `A57510DE...E3D` |
|
||||
| E-DOUBLE-001 | `dicerate.csv` + `<CheckLastTile>d__130.MoveNext` + 原作录像 00:03:35 | 等权 36 对、相等判 Double、移动取和、1+1→2且累计 +1 | 已有 Stage 2.5 证据包固定值 |
|
||||
| E-DOUBLE-002 | `relic.csv`, `equipskill.csv`, `joker.csv` | Double 消费者名称与 100/1/30/50/10/35、2/5/10 数值 | `relic.csv E396B478...BE9`; `equipskill.csv EB8A8674...75C2` |
|
||||
| E-WEB-001 | Heroll Wiki Relics | 遗物用户可见语义,用于解释本地 localization key | n/a |
|
||||
| E-WEB-002 | Reddit 玩家反击实测 | 反击基于敌方攻击,可暴击/未命中,仍受伤,不吸血 | n/a |
|
||||
|
||||
### 6.2 Findings
|
||||
|
||||
| F-id | 结论 | evidence_ids | confidence | location | status |
|
||||
|---|---|---|---|---|---|
|
||||
| F-COMBAT-001 | 暴击与命中 RNG 已分离,旧地址归属错误 | E-COMBAT-001, E-COMBAT-002 | high | `0x549B934`, `0x55A96C4` | validated |
|
||||
| F-COMBAT-002 | 防御线性减伤、攻速取倒数、吸血向上取整 | E-COMBAT-001, E-COMBAT-003 | high | 见第 3 节 | validated |
|
||||
| F-DOUBLE-001 | Double 不倍增移动,不内建伤害倍率 | E-DOUBLE-001 | high | `<CheckLastTile>d__130.MoveNext` | validated |
|
||||
| F-DOUBLE-002 | Double 的战斗价值由遗物/Joker/宠物/事件订阅者提供 | E-DOUBLE-001, E-DOUBLE-002, E-WEB-001 | high | `TriggerOnDiceDouble` 消费链 | validated |
|
||||
| F-DOUBLE-003 | Double Stack 的完整阈值、清空时机和终点奖励仍未闭合 | E-DOUBLE-001 | medium | `TryAddDoubleStack` async state machine | candidate |
|
||||
|
||||
### 6.3 Path
|
||||
|
||||
**P-COMBAT-001 — 一次普通攻击的原生调用流**
|
||||
|
||||
1. `RunAttackSequence` 调用攻击者 `OnBeforeAttack`,建立伤害与暴击标志 — E-COMBAT-001 — F-COMBAT-001。
|
||||
2. `HitAndGetResult` 获得 AIM/目标命中百分比并执行 0..100 判定 — E-COMBAT-001。
|
||||
3. 命中后进入受击钩子,执行 `max(0, damage-DEF)` 并扣 HP — E-COMBAT-001 — F-COMBAT-002。
|
||||
4. `OnAfterAttack` 以最终伤害计算吸血 — E-COMBAT-001 — F-COMBAT-002。
|
||||
5. `WaitAttackCooldown` 用 `100/AttackSpeed` 计算下一次攻击时间 — E-COMBAT-001 — F-COMBAT-002。
|
||||
|
||||
**P-DOUBLE-001 — Double 到战斗效果的事件流**
|
||||
|
||||
1. `DiceRate` 加权抽取有序骰子对 — E-DOUBLE-001。
|
||||
2. 两骰相等或命中强制分支后置 `isDouble` — E-DOUBLE-001 — F-DOUBLE-001。
|
||||
3. 仍以 `A+B` 移动,同时把 A 送入 Double Stack — E-DOUBLE-001 — F-DOUBLE-001。
|
||||
4. `TriggerOnDiceDouble` 广播,已装备遗物/Joker/宠物/事件按各自规则结算 — E-DOUBLE-002 — F-DOUBLE-002。
|
||||
|
||||
## 7. 未闭合与建议最小实测
|
||||
|
||||
下列内容不影响核心 MVP 公式,但如要 1:1 实现全部构筑,需补录:
|
||||
|
||||
1. 命中百分比的完整 `AIM/EVA/宠物/遗物` 合成顺序:同一敌人下使用 3 组已知 AIM,每组至少 200 次攻击。
|
||||
2. Battleship Horn +30% 攻速的持续时间和叠加方式:录制 Double 前后至少 10 次攻击时间戳。
|
||||
3. Gas Mask 护盾量和刷新规则:连续触发两次 Double,记录护盾 UI 数值。
|
||||
4. Scissors 传奇追加攻击次数:分别强制 1+1..6+6,记录攻击段数。
|
||||
5. Double Stack:连续强制不同骰面 Double,记录累计值、阈值、奖励与清空时机。
|
||||
|
||||
## 8. Timeline 摘要
|
||||
|
||||
- 2026-08-19:建立授权范围,重建 IL2CPP 地址映射和解密 SO。
|
||||
- 2026-08-19:提取 93 个有边界的原生方法体,封存 Stage 2.5.1 证据。
|
||||
- 2026-08-28:复核主线战斗、纠正暴击地址,闭合攻速/吸血/反击边界,完成 Double 战斗消费者矩阵。
|
||||
|
||||
## 9. 互联网交叉资料
|
||||
|
||||
- [Heroll Wiki — Relics](https://heroll.fandom.com/wiki/Relics)
|
||||
- [Reddit r/heroll — Counter attack?](https://www.reddit.com/r/heroll/comments/1l20mkh/counter_attack/)
|
||||
- [Reddit r/heroll — Slightly in-depth mechanics and interactions](https://www.reddit.com/r/heroll/comments/1l3sn2n/)
|
||||
- [Google Play — Heroll : Dice Roguelike](https://play.google.com/store/apps/details?id=com.percent.aos.rollinghero)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# 03-战斗
|
||||
|
||||
实时冷却行动模型、命中、暴击、防御、吸血、反击与Double消费者。
|
||||
|
||||
## 文件
|
||||
|
||||
- [2026-08-28_逆向-HEROLL战斗规则-report.md](./2026-08-28_%E9%80%86%E5%90%91-HEROLL%E6%88%98%E6%96%97%E8%A7%84%E5%88%99-report.md) — report;来源:`analysis/combat-rules/2026-08-28_逆向-HEROLL战斗规则-report.md`
|
||||
- [combat-formulas.csv](./combat-formulas.csv) — table;来源:`analysis/combat-rules/combat-formulas.csv`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,17 @@
|
||||
formula_id,system,formula_or_rule,rounding_or_boundary,source_tag,native_location,implementation_status
|
||||
COMBAT-STAT-001,final_status,"independentBonus + flatSum * (100 + percentBonus) / 100; special query modes may exclude layers","float; mode-dependent branches",NATIVE_CONFIRMED,CharacterStatus.GetFinalStatus@0x5409B54,IMPLEMENT_CORE
|
||||
COMBAT-DMG-001,player_base_damage,GetFinalStatus(ATTACK_POWER),float,NATIVE_CONFIRMED,BaseActor.GetBaseDamageAndConvertWithPlayerDamage@0x5494CD8,IMPLEMENT
|
||||
COMBAT-DMG-002,enemy_base_damage,"Random(attackLower*(1-rangePct),attackUpper*(1+rangePct)); rangePct=0.15","float Range",NATIVE_AND_CONFIG_CONFIRMED,BaseActor.GetBaseDamageAndConvertWithPlayerDamage@0x5494CD8,IMPLEMENT
|
||||
COMBAT-HIT-001,hit,"hitPercent > RandomInt(0,101)","roll 0..100; negative hitPercent clamped to 0",NATIVE_CONFIRMED,BaseMonoCharacter.HitAndGetResult@0x549B2CC,IMPLEMENT
|
||||
COMBAT-CRIT-001,critical,"finalCriticalRate > RandomInt(0,101)","roll 0..100; strict greater-than",NATIVE_CONFIRMED,BaseMonoPlayer.OnBeforeAttack@0x55A95EC,IMPLEMENT
|
||||
COMBAT-CRIT-002,critical_damage,"damage * criticalDamagePercent * 0.01","float; BaseCritical=150",NATIVE_AND_CONFIG_CONFIRMED,BaseMonoPlayer.OnBeforeAttack@0x55A9704,IMPLEMENT
|
||||
COMBAT-DEF-001,defense,"max(0,preDefenseDamage-finalDefense)",float,NATIVE_CONFIRMED,BaseMonoCharacter.HitAndGetResult@0x549BD18,IMPLEMENT
|
||||
COMBAT-HP-001,hp,"targetHp-finalDamage","float; display rounding separate",NATIVE_CONFIRMED,BaseMonoCharacter.HitAndGetResult@0x549BE7C,IMPLEMENT
|
||||
COMBAT-ASPD-001,attack_speed,"100/finalAttackSpeed","seconds; subtract elapsed; no global 0.15 clamp observed",NATIVE_CONFIRMED,<WaitAttackCooldown>d__45.MoveNext@0x5497280,IMPLEMENT
|
||||
COMBAT-LS-001,life_steal,"ceil(finalDamage*finalLifeSteal*0.01)","only if positive; minimum heal 1",NATIVE_CONFIRMED,BaseMonoPlayer.OnAfterAttack@0x55A9E48,IMPLEMENT
|
||||
COMBAT-COUNTER-001,counter_chance,"finalCounterRate >= RandomInt(1,101)","roll 1..100; inclusive",NATIVE_CONFIRMED,BaseMonoPlayer.OnCounterAttack@0x55AC048,IMPLEMENT
|
||||
DOUBLE-001,natural_double,diceA==diceB,"built-in 36 pairs equal weight => 1/6 absent override",NATIVE_CONFIG_VIDEO_CONFIRMED,<CheckLastTile>d__130.MoveNext,IMPLEMENT
|
||||
DOUBLE-002,double_movement,diceA+diceB,"never multiply by 2 solely because Double",NATIVE_VIDEO_CONFIRMED,<CheckLastTile>d__130.MoveNext,IMPLEMENT
|
||||
DOUBLE-003,double_stack,TryAddDoubleStack(diceA),"accumulate face value; threshold/reward/reset unresolved",NATIVE_VIDEO_PARTIAL,BoardController.TryAddDoubleStack@0x56A4BE0,IMPLEMENT_ACCUMULATION_ONLY
|
||||
DOUBLE-004,double_combat,"no unconditional damage multiplier; dispatch TriggerOnDiceDouble to equipped consumers",event-driven,NATIVE_CONFIG_CONFIRMED,EventManager.TriggerOnDiceDouble@0x51AEDEC,IMPLEMENT
|
||||
|
||||
|
@@ -0,0 +1,208 @@
|
||||
# HEROLL 2.0.1 局内装备等级、词条、星级与 Boss 中途掉落逆向报告
|
||||
|
||||
> 范围:仅 HEROLL 2.0.1 Unity IL2CPP 版本;仅用于本机内部玩法验证。
|
||||
> 标签:`[源码确认]` 可直接还原;`[实机观察]` 来自用户/录像;`[验证版新增]` 是原作证据不足时的明确设计选择。
|
||||
> 样本:`libil2cpp.runtime-decrypted.so`,SHA-256 `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA`。
|
||||
|
||||
## 结论摘要
|
||||
|
||||
| 问题 | 可实施结论 | 证据等级 |
|
||||
|---|---|---|
|
||||
| 装备等级 | `GearLevel = max(1, Floor + Δ)`;普通主线 `Δ={0,1,2}`,权重 `90:5:1`,即 `93.75% / 5.2083% / 1.0417%` | `[源码确认]` |
|
||||
| 六品质影响 | 品质不使用全局倍率直接放大局内装备;它决定副词条数、星级分配,且仅 Myth 主属性多 1 个有效等级 | `[源码确认]` |
|
||||
| 部位词条池 | 四个局内部位共用同一组 9 个副词条,抽取不重复;没有发现部位过滤 | `[源码确认]` |
|
||||
| 星级维度 | 星级是每条 `Status.plusLevel`,不是装备等级、品质或另一套 Affix Tier;每星把该词条的有效等级提高 1 | `[源码确认]` |
|
||||
| Boss 中途掉装 | 已观察存在,但未恢复 `boss_0` 可审计阈值;验证版采用首次向下越过 50% HP 时追加 1 件 | `[实机观察] + [验证版新增]` |
|
||||
|
||||
## 1. 装备等级公式
|
||||
|
||||
配置 `gameconfig.csv` 给出:
|
||||
|
||||
```text
|
||||
LoopRatio = 90, 5, 1
|
||||
```
|
||||
|
||||
`BattleController.GetWeaponLoop @ 0x55BE240` 构造三项权重并抽取偏移;函数尾部把当前零基圈数加一,再加抽到的偏移。因此普通主线可写为:
|
||||
|
||||
\[
|
||||
Floor = LoopIndex + 1
|
||||
\]
|
||||
|
||||
\[
|
||||
GearLevel = \max(1, Floor + \Delta)
|
||||
\]
|
||||
|
||||
| Δ | 权重 | 归一化概率 | Floor 10 示例 |
|
||||
|---:|---:|---:|---:|
|
||||
| 0 | 90 | 93.7500% | Lv.10 |
|
||||
| 1 | 5 | 5.2083% | Lv.11 |
|
||||
| 2 | 1 | 1.0417% | Lv.12 |
|
||||
|
||||
这与实机观察“Floor 10 不低于 Lv.10、最高 Lv.12”一致。原生函数还含模式/研究相关的下限或上限分支;本地玩法验证版没有局外研究,故应使用上表作为普通主线基线,不引入元成长修正。
|
||||
|
||||
## 2. 品质、主属性和副词条
|
||||
|
||||
### 2.1 六品质
|
||||
|
||||
| enum | 品质 | 基础权重 | 基础概率 | 副词条数 | 主属性特殊规则 |
|
||||
|---:|---|---:|---:|---:|---|
|
||||
| 0 | Normal / 灰 | 210 | 68.4039% | 0 | 无 |
|
||||
| 1 | Rare / 绿 | 60 | 19.5440% | 1 | 无 |
|
||||
| 2 | Epic / 蓝 | 28 | 9.1205% | 2 | 无 |
|
||||
| 3 | Legend / 金 | 4 | 1.3029% | 3 | 无 |
|
||||
| 4 | Myth / 彩 | 1 | 0.3257% | 3 | 主属性有效等级 +1 |
|
||||
| 5 | Arcane / 红 | 4 | 1.3029% | 3 | 无;一条副词条带 Arcane 隐藏/观察标记 |
|
||||
|
||||
这些百分比是无其他修正时的基础品质分布。`GrageMultiplier=1,2,4,8,16` 虽存在于 `gameconfig.csv`,但没有进入本报告追踪到的局内 `GetMonoWeaponData → GetStatus` 数值路径,不能把它当作局内品质乘区。
|
||||
|
||||
### 2.2 四部位主属性
|
||||
|
||||
| 局内部位 | 固定主属性 |
|
||||
|---|---|
|
||||
| Ingame_Weapon | ATTACK_POWER |
|
||||
| Ingame_Ring | HEALTH |
|
||||
| Ingame_Gauntlet | AIM |
|
||||
| Ingame_Boots | DEFENSE |
|
||||
|
||||
先抽 40 件装备之一,再独立生成品质、等级和属性;装备 ID 与品质不是预组合的独立掉落项。
|
||||
|
||||
### 2.3 属性值公式
|
||||
|
||||
对 `weaponstatus.csv` 中任意属性 `s`:
|
||||
|
||||
\[
|
||||
EffectiveLevel_{main}=GearLevel-1+MythBonus+ResearchBonus
|
||||
\]
|
||||
|
||||
其中 `MythBonus=1` 仅品质 enum 4 生效;验证版 `ResearchBonus=0`。
|
||||
|
||||
\[
|
||||
EffectiveLevel_{affix}=GearLevel+Star-1
|
||||
\]
|
||||
|
||||
\[
|
||||
MinValue=BaseMin_s+PlusValue_s\times EffectiveLevel
|
||||
\]
|
||||
|
||||
\[
|
||||
MaxValue=BaseMax_s+PlusValue_s\times EffectiveLevel
|
||||
\]
|
||||
|
||||
随后在 `[MinValue, MaxValue]` 内取随机值。`isFloat=true` 保留 1 位小数,`isFloat=false` 取整数。源码内部生成两个有间距的候选值,当前调用链采用第一个;要做逐 seed 精确复刻时,必须保持原随机流调用次数。
|
||||
|
||||
## 3. 四部位允许的随机副词条
|
||||
|
||||
原生生成器显式建立枚举集合 `{6,5,7,8,9,10,11,12,13}`,对应下列 9 项;四个部位均使用此池,单件装备内无重复。
|
||||
|
||||
| 副词条 | Base 范围 | 每星 Plus | 百分比 | 小数 |
|
||||
|---|---:|---:|---|---|
|
||||
| EVASION | 14–20 | 7 | 否 | 否 |
|
||||
| REGEN_PER_SECOND | 1–2 | 2.4 | 否 | 是 |
|
||||
| TOTAL_DAMAGE | 1–2 | 1 | 否 | 是 |
|
||||
| TRUE_DAMAGE | 1–2.5 | 1.7 | 否 | 否 |
|
||||
| KILL_HEAL | 6–9 | 2.5 | 否 | 否 |
|
||||
| COUNTER_ATTACK | 7–9 | 1.5 | 是 | 否 |
|
||||
| ATTACK_SPEED | 7–9 | 1.4 | 是 | 否 |
|
||||
| CRITICAL_RATE | 10–12 | 1.5 | 是 | 否 |
|
||||
| LIFE_STEAL | 4.5–7.5 | 1.5 | 是 | 否 |
|
||||
|
||||
注意:`HEALTH` 不是随机副词条,而是 Ring 固定主属性;`ATTACK_POWER/AIM/DEFENSE` 同理属于各自部位主属性。
|
||||
|
||||
## 4. 星级的真实含义及品质分配
|
||||
|
||||
运行时数据没有独立 `AffixTier` 字段。每条属性使用 `Status.plusLevel` 表达星级;因此实现中不要再叠加一套隐藏 T1/T2/T3。
|
||||
|
||||
| 品质 | 生成结果(副词条星级) | 精确规则 |
|
||||
|---|---|---|
|
||||
| Normal | 无 | 0 条副词条 |
|
||||
| Rare | `[1]` | 1 条,初始 1 星 |
|
||||
| Epic | `[1,1]` | 2 条,各 1 星 |
|
||||
| Legend | `[2,1,1]` | 3 条各 1 星,再随机给其中一条 +1 |
|
||||
| Myth | 见下表 | 3 条各 1 星,再独立随机分配 3 个星点,可重复命中 |
|
||||
| Arcane | `[4,1,1]` | 3 条各 1 星;随机选一条集中获得 +3,并设置 Arcane 标记 |
|
||||
|
||||
Myth 的排序后分布:
|
||||
|
||||
| 星级组合 | 概率 |
|
||||
|---|---:|
|
||||
| `[4,1,1]` | 1/9 = 11.1111% |
|
||||
| `[3,2,1]` | 2/3 = 66.6667% |
|
||||
| `[2,2,2]` | 2/9 = 22.2222% |
|
||||
|
||||
原生额外星点循环调用 `Common.Roll(1.0)`;该条件恒真,所以 Legend 精确增加 1 点,Myth/Arcane 精确增加 3 点,不是“最多增加”。Arcane 被选中的 4 星词条还会设置 `isHideStatusIndex=true`、`arcaneWatchIndex=0`;本报告不把尚未闭环的 UI 揭示时序扩写成规则。
|
||||
|
||||
## 5. Boss HP 中途追加装备
|
||||
|
||||
用户实机观察表明 Boss 在战斗中 HP 降低到某阶段时会追加 1 件装备。当前逆向可以确认多个 `SpawnRandomWeapon` 调用入口,也能确认 `GoldCarriageEnemy` 有独立阈值奖励结构,但没有恢复到足以证明 `boss_0` HP 百分比的专属调用链。因此不能把任意百分比标成原作事实。
|
||||
|
||||
玩法验证版采用以下覆盖规则:
|
||||
|
||||
```text
|
||||
[验证版新增] boss_0 首次由 HP > 50% 向下越过 HP <= 50% 时,追加生成 1 件装备。
|
||||
midBossGearDropped 为单场战斗幂等标记;复活不重置。
|
||||
若一击同时越过 50% 并致死,先产生中途装备,再执行死亡结算。
|
||||
Boss 死亡掉落与该追加掉落是两个独立来源。
|
||||
```
|
||||
|
||||
这个选择可见、易测、不会伪装成原作恢复结论。若未来动态 Hook 得到真实阈值,只替换配置,不改变事务结构。
|
||||
|
||||
## 生成流程图
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[当前 Floor] --> B[GetWeaponLoop]
|
||||
B --> C{Δ 加权抽取 90:5:1}
|
||||
C --> D[GearLevel = Floor + Δ]
|
||||
D --> E[抽 40 件装备之一]
|
||||
E --> F[抽六品质]
|
||||
F --> G[部位固定主属性]
|
||||
F --> H[按品质确定副词条数]
|
||||
H --> I[四部位共享 9 词条池\n单件不重复]
|
||||
I --> J[按品质分配 plusLevel 星级]
|
||||
G --> K[GetStatus 数值区间]
|
||||
J --> K
|
||||
K --> L[按 isFloat 整数或 1 位小数]
|
||||
```
|
||||
|
||||
## Evidence → Finding → Path
|
||||
|
||||
### Findings
|
||||
|
||||
- `F-DROP-001`(validated,高):普通主线装备等级为 `Floor + Weighted(0,1,2; 90,5,1)`。`evidence_ids: [E-DROP-LEVEL-001]`
|
||||
- `F-DROP-002`(validated,高):六品质通过副词条数量、星级分配和 Myth 主属性 +1 有效等级影响属性,不在此路径使用全局品质倍率。`evidence_ids: [E-DROP-AFFIX-001]`
|
||||
- `F-DROP-003`(validated,高):四局内部位共用 9 项无重复副词条池。`evidence_ids: [E-DROP-AFFIX-001]`
|
||||
- `F-DROP-004`(validated,高):星级等于每条 `Status.plusLevel`,每星提升该词条一个有效等级;没有独立 Affix Tier。`evidence_ids: [E-DROP-AFFIX-001]`
|
||||
- `F-DROP-005`(partial,中):Boss 中途追加装备被实机观察支持,但 `boss_0` 精确 HP 阈值尚未由静态调用链闭环;50% 是验证版新增。`evidence_ids: [E-DROP-BOSS-001]`
|
||||
|
||||
### Path
|
||||
|
||||
- `P-DROP-001`
|
||||
- `path_type: callflow`
|
||||
- steps: `gameconfig.LoopRatio → BattleController.GetWeaponLoop → GetMonoWeaponData → status generator → GetStatus → GetRandomValues`
|
||||
- `evidence_ids: [E-DROP-LEVEL-001, E-DROP-AFFIX-001]`
|
||||
|
||||
## 复现入口
|
||||
|
||||
```powershell
|
||||
rg -n "LoopRatio|GrageMultiplier" HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/gameconfig.csv
|
||||
rg -n "ATTACK_POWER|EVASION|LIFE_STEAL" HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/weaponstatus.csv
|
||||
radare2 -q -c "s 0x55BE240; pd 420" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
radare2 -q -c "s 0x55BDCC0; pd 1450" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
radare2 -q -c "s 0x55C0840; pd 360" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
radare2 -q -c "s 0x55C0D70; pd 320" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
```
|
||||
|
||||
## 互联网交叉检索
|
||||
|
||||
公开资料没有给出上述局内精确权重或公式。Google Play 只描述掷骰、战斗和装备循环;社区 Wiki 的 Equipment 页面主要是局外持久装备系统,不能与本报告的局内 `MonoWeaponData/Status.plusLevel` 混用。社区讨论“等级通常比稀有度更重要”仅与本报告的线性等级增长方向相容,不构成公式证据。
|
||||
|
||||
- Google Play:https://play.google.com/store/apps/details?hl=en_SG&id=com.percent.aos.rollinghero
|
||||
- Heroll Wiki Equipment:https://heroll.fandom.com/wiki/Equipment
|
||||
- Reddit 社区讨论:https://www.reddit.com/r/heroll/comments/1l1x8qx
|
||||
|
||||
## 限制
|
||||
|
||||
- Arcane 词条的完整 UI 揭示/观察生命周期尚未闭环,本报告只保留已确认字段语义。
|
||||
- `boss_0` 的原作中途掉落阈值尚未闭环;50% 仅为验证版配置。
|
||||
- 模式和局外研究可能给 `GetWeaponLoop/GetStatus` 增加修正;本报告的实现目标是无局外成长的主线玩法验证版。
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
# HEROLL 2.0.1 掉落规则逆向报告
|
||||
|
||||
> 样本:`com.percent.aos.rollinghero`,versionName `2.0.1`,versionCode `113296145`
|
||||
> 原始 XAPK SHA-256:`439D532704AFCCDBEBA8C01AF7869552387CDE31651963D0A45541F252B94E2F`
|
||||
> 结论等级:**确认**=配置或 Native 正文直接证明;**高置信推导**=多项独立证据闭合;**未知**=不得用于原作还原。
|
||||
|
||||
## 1. 核心结论
|
||||
|
||||
HEROLL 的局内装备生成不是一次抽完,而是至少拆成四步:
|
||||
|
||||
1. 从 `WeaponDrop` 的 40 条局内装备中随机选装备身份。
|
||||
2. 以六档相对权重生成品质,并叠加 Joker/局内效果及圈数相关修正。
|
||||
3. 另行生成 `loopGrade` 与随机属性。
|
||||
4. 检查封印等后处理,生成装备槽;槽满时先进入回收路径。
|
||||
|
||||
基础品质权重为:
|
||||
|
||||
`NORMAL : RARE : EPIC : LEGEND : MYTH : ARCANE = 210 : 60 : 28 : 4 : 1 : 4`
|
||||
|
||||
这些数值是**相对权重,不是百分比**。未激活任何动态修正时,总权重为 307,基线概率如下:
|
||||
|
||||
| 品质 | 权重 | 基线概率 |
|
||||
|---|---:|---:|
|
||||
| NORMAL | 210 | 68.4039% |
|
||||
| RARE | 60 | 19.5440% |
|
||||
| EPIC | 28 | 9.1205% |
|
||||
| LEGEND | 4 | 1.3029% |
|
||||
| MYTH | 1 | 0.3257% |
|
||||
| ARCANE | 4 | 1.3029% |
|
||||
|
||||
`ARCANE` 的基础权重确实高于 `MYTH`;这是样本原值,不能为了“看起来合理”而改写。
|
||||
|
||||
## 2. Native 生成链
|
||||
|
||||
### 2.1 装备身份
|
||||
|
||||
`BattleController.GetMonoWeaponData`(VA `0x55BDCC0`)读取 `WeaponDrop` 表的总行数,以随机整数索引取一条,再写入 `weaponStringId`。
|
||||
|
||||
`weapondrop.csv` 正好有 40 条数据:
|
||||
|
||||
| 槽位类型 | 数量 | 基础身份概率 |
|
||||
|---|---:|---:|
|
||||
| Ingame_Weapon | 10 | 25%(单件 2.5%) |
|
||||
| Ingame_Ring | 10 | 25%(单件 2.5%) |
|
||||
| Ingame_Gauntlet | 10 | 25%(单件 2.5%) |
|
||||
| Ingame_Boots | 10 | 25%(单件 2.5%) |
|
||||
|
||||
该等概率结论仅适用于走基础 `GetMonoWeaponData` 随机重载的奖励。`SpawnFixWeapon`、`SpawnTypeWeapon` 及其他带筛选参数的入口可以固定身份或限制类型,不能套用 2.5%。
|
||||
|
||||
### 2.2 品质
|
||||
|
||||
`BattleController.GetEWeaponGrade`(VA `0x55BDE8C`)执行以下流程:
|
||||
|
||||
```text
|
||||
weights = [210, 60, 28, 4, 1, 4]
|
||||
for gradeIndex in 0..5:
|
||||
weights[gradeIndex] *= JokerEffectController.GetWeaponProbMultiplier(gradeIndex)
|
||||
|
||||
apply_loop_or_grade_related_modifiers(weights)
|
||||
|
||||
if excludeNormal:
|
||||
weights[0] = 0
|
||||
|
||||
gradeIndex = Utils.GetRatioPercent(weights)
|
||||
```
|
||||
|
||||
`Utils.GetRatioPercent` 是加权选择器,因此最终概率为 `修正后本档权重 / 修正后总权重`。
|
||||
|
||||
当调用入口设置 `excludeNormal=true` 且没有其他修正时,归一化结果为:RARE 61.8557%、EPIC 28.8660%、LEGEND 4.1237%、MYTH 1.0309%、ARCANE 4.1237%。这不是普通掉落率,只是该特殊分支的数学基线。
|
||||
|
||||
### 2.3 `loopGrade`、属性与后处理
|
||||
|
||||
`BattleController.GetWeaponLoop`(VA `0x55BE240`)另建一个三项权重列表,经 `Utils.GetRatioPercent` 抽取并叠加圈数/品质相关值。它不是六档品质抽取。
|
||||
|
||||
随后 `GetMonoWeaponData` 继续生成状态值、检查封印并写入 `MonoWeaponData`。随机装备协程的已闭合调用链为:
|
||||
|
||||
```text
|
||||
CheckFullSlotRecycleFirstExtra
|
||||
-> GetMonoWeaponData
|
||||
-> MonoWeaponSlot.Spawn
|
||||
-> AddWeaponRewardForEventLog
|
||||
-> HandleJokerWeaponSpawnPostProcess
|
||||
```
|
||||
|
||||
因此以下行为已确认:
|
||||
|
||||
- 满槽会在生成前进入回收处理。
|
||||
- Joker 不只修正品质权重,装备生成后还有独立后处理。
|
||||
- `GetWeaponDropDestroyChance` 表明某些 Joker 效果可令掉落销毁;具体活动值取决于当前效果状态。
|
||||
|
||||
## 3. 掉落“出现机会”与“掉落品质”必须分开
|
||||
|
||||
`ingameWeaponDropRatio` 只证明**已经进入装备生成时的品质分布**,不等于“每只敌人有多少概率掉装备”。
|
||||
|
||||
当前静态证据能确认多个系统会调用随机、固定或类型限定装备生成接口,包括战斗相关奖励、宝箱/事件、碎片交互、小游戏和特殊祝福效果。但 APK 中没有发现一个可直接解释为“所有普通敌人的统一装备掉率”的全局配置。
|
||||
|
||||
两个启用的祝福配置会改变装备出现机会:
|
||||
|
||||
| ID | StringId | 关键配置 | 可确认内容 | 尚未确认内容 |
|
||||
|---:|---|---|---|---|
|
||||
| 124 | KillInTimeGetGear | `timeValue=2.5` | 祝福启用,名称指向限时击杀装备奖励 | 2.5 的精确单位、触发对象及是否必掉 |
|
||||
| 132 | KillForHeroGear | `Value=10` | 祝福启用,名称指向击杀换高品质装备 | “10”的计数/概率语义及品质下限 |
|
||||
|
||||
仅凭 StringId 不足以把这两项写成确定公式;需要继续闭合祝福消费者 Native 正文或做指定种子的动态采样。
|
||||
|
||||
## 4. 局内非装备奖励表
|
||||
|
||||
`ingamereward.csv` 配置了以下节点:
|
||||
|
||||
| 时机 | 奖励 | 配置 |
|
||||
|---|---|---|
|
||||
| `killStrong` | 钻石(item 101) | 数量 0、概率 0,等同关闭 |
|
||||
| `loopClear` | 钻石(item 101) | 数量 1、概率 80 |
|
||||
| `loopEndTileMove` | 金币(item 100) | 基数 10、概率 100、随目标关卡乘 `stageMult` |
|
||||
| `loopClear` | 金币(item 100) | 基数 330、概率 100、随目标关卡乘 `stageMult` |
|
||||
| `loopClear` | 四槽卷轴(119–122) | 各数量 1、配置概率数组均为 20 |
|
||||
| `loopClear` | 四槽强化材料(126–129) | 各数量 1、配置概率数组均为 20 |
|
||||
| `gameEnd` | 鱼饼(item 111) | 数量 1、概率 100 |
|
||||
|
||||
金币 `stageMult`:
|
||||
|
||||
| 目标关卡索引 | stageMult |
|
||||
|---|---:|
|
||||
| -1–16 | 0.30 |
|
||||
| 17–21 | 0.29 |
|
||||
| 22–25 | 0.28 |
|
||||
| 26–30 | 0.27 |
|
||||
| 31–33 | 0.26 |
|
||||
| 34–37 | 0.25 |
|
||||
| 38–44 | 0.24 |
|
||||
| 45–99 | 0.23 |
|
||||
|
||||
表中 `itemCount × stageMult` 的小数取整规则尚未由消费者正文证明,不应自行选择 floor、round 或 ceil。四项 `20` 是配置事实,但“各自独立判定”还是“先选一项再判空”也需 Native 消费者闭合。
|
||||
|
||||
## 5. 抓娃娃掉落配置
|
||||
|
||||
`clawcraneminigame.csv` 说明场内出现 20 个胶囊,配置项包括:
|
||||
|
||||
| 奖励 | 普通 Prob | goodProb |
|
||||
|---|---:|---:|
|
||||
| 空 | 40 | 0 |
|
||||
| 点数 | 70 | 0 |
|
||||
| 药水 | 14 | 0 |
|
||||
| NORMAL 装备 | 40 | 0 |
|
||||
| RARE 装备 | 0 | 0 |
|
||||
| EPIC 装备 | 0 | 0 |
|
||||
| LEGEND 装备 | 0 | 1 |
|
||||
| 祝福 | 0 | 0 |
|
||||
| 药水祝福 | 0 | 0 |
|
||||
|
||||
这些是胶囊生成器的输入权重/概率字段,不应直接归一化为单次抓取概率;胶囊层级、20 个场内对象、好胶囊分支和物理抓取成功率都会影响最终获得率。
|
||||
|
||||
## 6. 保底与重复保护
|
||||
|
||||
结论:**未发现局内 `BattleController` 装备品质抽取的保底计数器或重复品排除逻辑。**
|
||||
|
||||
搜索到的保底实现属于其他系统:
|
||||
|
||||
- `gachaceildata.csv`:局外抽卡保底。
|
||||
- `IdleDungeonController.RollGuaranteedIdleDungeonEquipmentGrade`:挂机地牢装备保底。
|
||||
- `DestinyStatPage.RollGuaranteedHighGrade`:命运属性重掷保底。
|
||||
|
||||
它们不能迁移为普通局内装备掉落规则。公开社区所说的“20 抽保底”和 S 级装备抽取率也属于 Mimic Hunt/局外抽取,不是局内棋盘掉落。
|
||||
|
||||
## 7. 仍然未知的精确项
|
||||
|
||||
以下项目不应冒充已经还原:
|
||||
|
||||
1. 普通敌人自然产生一次装备奖励的基础触发率。
|
||||
2. `GetEWeaponGrade` 中圈数对 EPIC/LEGEND/MYTH/ARCANE 的完整倍率公式。
|
||||
3. 当前运行中各 Joker 的实际倍率、掉落销毁率及远程配置覆盖值。
|
||||
4. `GetWeaponLoop` 三项权重的语义名称及最终 `loopGrade` 分布。
|
||||
5. 卷轴/强化材料概率数组的精确判定顺序。
|
||||
6. 小数奖励数量的取整方式。
|
||||
|
||||
要闭合 1–4,最小动态采样方案是固定 seed,分别在无祝福、获取 ID 124、获取 ID 132、不同圈数及指定 Joker 状态下,Hook `GetEWeaponGrade` 的入参、六项修正后权重和返回值,并记录每个 `SpawnRandomWeapon` 的调用栈。互联网资料无法替代这一步。
|
||||
|
||||
## 8. 证据索引
|
||||
|
||||
| 证据 | SHA-256 | 用途 |
|
||||
|---|---|---|
|
||||
| `gameconfig.csv` | `A57510DEDE13DAF1A597DE1EE73E47B0ABD830D96719DAD24B2CA7370E8DFE3D` | 六档基础权重 |
|
||||
| `weapondrop.csv` | `AF8C97D022A83C1FF898D33FC541F157CAD1DC6C5732FF57D61A502E82914809` | 40 条局内装备身份 |
|
||||
| `ingamereward.csv` | `BCD0E607C0F31A378960F3CD3BA25518A3F3D72D377EEDE11064A276849A9A74` | 圈结算与关卡结束奖励 |
|
||||
| `augment.csv` | `E0B14AF4709E3F0D548973E124F679EF091589D7C99B0E35DE78C628A73D032A` | 装备掉落相关祝福 |
|
||||
| `clawcraneminigame.csv` | `AE52FA502303678DE55D910BF07CD222C29A6995D0A4D96A785E84C660035015` | 抓娃娃胶囊配置 |
|
||||
| `assembly-csharp.json` | `BA6D3F4BD91B0D3977EB1229AB46FE563118CC55793346796F93816BA7FEF526` | IL2CPP 类型、字段、方法映射 |
|
||||
| `libil2cpp.runtime-decrypted.so` | `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA` | Native 规则正文 |
|
||||
| `battlecontroller-drop-code.bin` | `DC28F8583A8AA60C2C3ED7CED8E5B9A60EDBF4A10E82370B32F2C169424FC0ED` | 原 SO 的只读函数区切片,便于 ARM64 复核 |
|
||||
|
||||
## 9. 互联网交叉检索结论
|
||||
|
||||
- [Heroll Wiki 的 Equipment 页面](https://heroll.fandom.com/wiki/Equipment)描述的是局外装备、Mimic Hunt、合成与升级,没有公开局内 `EMonoWeaponGrade` 的生成算法。
|
||||
- [Heroll 社区的 S Legendary 讨论](https://www.reddit.com/r/heroll/comments/1mtb15a/the_thing_about_s_legendary_equipment/)出现了玩家声称的 0.5964% 以及评论中的“20 抽保底”,上下文明确是局外抽取/合成,不可用于本报告的局内掉落率。
|
||||
|
||||
因此,互联网没有补上 Native 中尚缺的圈数倍率;本报告以 APK 2.0.1 本地证据为准。
|
||||
@@ -0,0 +1,15 @@
|
||||
# 04-局内装备
|
||||
|
||||
装备本体、品质、等级、主副词条、plusLevel与随机值公式。
|
||||
|
||||
## 文件
|
||||
|
||||
- [2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md](./2026-08-31_%E9%80%86%E5%90%91-HEROLL%E8%A3%85%E5%A4%87%E7%AD%89%E7%BA%A7%E8%AF%8D%E6%9D%A1%E6%98%9F%E7%BA%A7%E4%B8%8EBoss%E6%8E%89%E8%90%BD-report.md) — report;来源:`analysis/drop-rules/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md`
|
||||
- [equipment-catalog.csv](./equipment-catalog.csv) — catalog;来源:`analysis/catalog-reverse/tables/equipment-catalog.csv`
|
||||
- [gear-affix-pools.csv](./gear-affix-pools.csv) — table;来源:`analysis/drop-rules/gear-affix-pools.csv`
|
||||
- [gear-level-rules.csv](./gear-level-rules.csv) — table;来源:`analysis/drop-rules/gear-level-rules.csv`
|
||||
- [gear-rarity-affix-rules.csv](./gear-rarity-affix-rules.csv) — table;来源:`analysis/drop-rules/gear-rarity-affix-rules.csv`
|
||||
- [gear-value-formulas.csv](./gear-value-formulas.csv) — table;来源:`analysis/drop-rules/gear-value-formulas.csv`
|
||||
- [HEROLL_2.0.1_掉落规则.md](./HEROLL_2.0.1_%E6%8E%89%E8%90%BD%E8%A7%84%E5%88%99.md) — guide;来源:`analysis/drop-rules/HEROLL_2.0.1_掉落规则.md`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,41 @@
|
||||
catalog_id,string_id,name_zh_cn,name_en,slot,slot_zh_cn,main_stat,rarity_pool,rarity_weights,affix_pool,level_rule,icon,title_key,source_tag
|
||||
100,ingame_weapon_01,冒险者匕首,Adventurer Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_01,ingame_weapon_01_title,源码确认
|
||||
101,ingame_weapon_02,誓约匕首,Dagger of Oath,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_02,ingame_weapon_02_title,源码确认
|
||||
102,ingame_weapon_03,破碎匕首,Shattering Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_03,ingame_weapon_03_title,源码确认
|
||||
103,ingame_weapon_04,樵夫匕首,Lumberjack Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_04,ingame_weapon_04_title,源码确认
|
||||
104,ingame_weapon_05,亡者匕首,Dagger of the Dead,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_05,ingame_weapon_05_title,源码确认
|
||||
105,ingame_weapon_06,神圣匕首,Holy Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_06,ingame_weapon_06_title,源码确认
|
||||
106,ingame_weapon_07,霜光匕首,Frost Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_07,ingame_weapon_07_title,源码确认
|
||||
107,ingame_weapon_08,光之匕首,Light Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_08,ingame_weapon_08_title,源码确认
|
||||
108,ingame_weapon_09,祭坛匕首,Ritual Dagger,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_09,ingame_weapon_09_title,源码确认
|
||||
109,ingame_weapon_10,烈火匕首,Dagger of Blazing Ember,Ingame_Weapon,武器,ATTACK_POWER,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_weapon_icon_10,ingame_weapon_10_title,源码确认
|
||||
113,ingame_ring_01,冒险者戒指,Adventurer Ring,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_01,ingame_ring_01_title,源码确认
|
||||
114,ingame_ring_02,誓约戒指,Ring of Oath,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_02,ingame_ring_02_title,源码确认
|
||||
115,ingame_ring_03,星星戒指,Star Ring,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_03,ingame_ring_03_title,源码确认
|
||||
116,ingame_ring_04,樵夫戒指,Lumberjack Ring,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_04,ingame_ring_04_title,源码确认
|
||||
117,ingame_ring_05,亡者戒指,Ring of the Dead,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_05,ingame_ring_05_title,源码确认
|
||||
118,ingame_ring_06,龙之戒指,Dragon Ring,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_06,ingame_ring_06_title,源码确认
|
||||
119,ingame_ring_07,霜光戒指,Frost Ring,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_07,ingame_ring_07_title,源码确认
|
||||
120,ingame_ring_08,幸运戒指,Ring of Fortune,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_08,ingame_ring_08_title,源码确认
|
||||
121,ingame_ring_09,堕落戒指,Corrupted Ring,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_09,ingame_ring_09_title,源码确认
|
||||
122,ingame_ring_10,永存戒指,Ring of Eternity,Ingame_Ring,戒指,HEALTH,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_ring_icon_10,ingame_ring_10_title,源码确认
|
||||
129,ingame_gauntlet_01,冒险者手套,Adventurer Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_01,ingame_gauntlet_01_title,源码确认
|
||||
130,ingame_gauntlet_02,誓约手套,Gauntlet of Oath,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_02,ingame_gauntlet_02_title,源码确认
|
||||
131,ingame_gauntlet_03,古代手套,Ancient Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_03,ingame_gauntlet_03_title,源码确认
|
||||
132,ingame_gauntlet_04,樵夫手套,Lumberjack Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_04,ingame_gauntlet_04_title,源码确认
|
||||
133,ingame_gauntlet_05,神圣手套,Holy Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_05,ingame_gauntlet_05_title,源码确认
|
||||
134,ingame_gauntlet_06,龙之手套,Dragon Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_06,ingame_gauntlet_06_title,源码确认
|
||||
135,ingame_gauntlet_07,霜光手套,Frost Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_07,ingame_gauntlet_07_title,源码确认
|
||||
136,ingame_gauntlet_08,幸运手套,Gauntlet of Fortune,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_08,ingame_gauntlet_08_title,源码确认
|
||||
137,ingame_gauntlet_09,侏儒手套,Dwarven Gauntlet,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_09,ingame_gauntlet_09_title,源码确认
|
||||
138,ingame_gauntlet_10,永劫手套,Gauntlet of Eternity,Ingame_Gauntlet,护手,AIM,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_gauntlet_icon_10,ingame_gauntlet_10_title,源码确认
|
||||
145,ingame_boots_01,冒险者靴子,Adventurer Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_01,ingame_boots_01_title,源码确认
|
||||
146,ingame_boots_02,誓约靴子,Boots of Oath,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_02,ingame_boots_02_title,源码确认
|
||||
147,ingame_boots_03,古代靴子,Ancient Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_03,ingame_boots_03_title,源码确认
|
||||
148,ingame_boots_04,樵夫靴子,Lumberjack Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_04,ingame_boots_04_title,源码确认
|
||||
149,ingame_boots_05,神圣靴子,Holy Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_05,ingame_boots_05_title,源码确认
|
||||
150,ingame_boots_06,猎龙者靴子,Dragon Hunter's Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_06,ingame_boots_06_title,源码确认
|
||||
151,ingame_boots_07,霜光靴子,Frost Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_07,ingame_boots_07_title,源码确认
|
||||
152,ingame_boots_08,幸运靴子,Boots of Fortune,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_08,ingame_boots_08_title,源码确认
|
||||
153,ingame_boots_09,堕落靴子,Corrupted Boots,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_09,ingame_boots_09_title,源码确认
|
||||
154,ingame_boots_10,永劫靴子,Boots of Eternity,Ingame_Boots,鞋子,DEFENSE,Normal|Rare|Epic|Legend|Myth|Arcane,210|60|28|4|1|4,EVASION|REGEN_PER_SECOND|TOTAL_DAMAGE|TRUE_DAMAGE|KILL_HEAL|COUNTER_ATTACK|ATTACK_SPEED|CRITICAL_RATE|LIFE_STEAL,"Floor+Weighted(0,1,2;90,5,1)",ingame_boots_icon_10,ingame_boots_10_title,源码确认
|
||||
|
@@ -0,0 +1,11 @@
|
||||
status_enum,status,allowed_weapon,allowed_ring,allowed_gauntlet,allowed_boots,base_min,base_max,plus_per_star,is_percent,is_float,source_tag
|
||||
6,EVASION,true,true,true,true,14,20,7,false,false,源码确认
|
||||
5,REGEN_PER_SECOND,true,true,true,true,1,2,2.4,false,true,源码确认
|
||||
7,TOTAL_DAMAGE,true,true,true,true,1,2,1,false,true,源码确认
|
||||
8,TRUE_DAMAGE,true,true,true,true,1,2.5,1.7,false,false,源码确认
|
||||
9,KILL_HEAL,true,true,true,true,6,9,2.5,false,false,源码确认
|
||||
10,COUNTER_ATTACK,true,true,true,true,7,9,1.5,true,false,源码确认
|
||||
11,ATTACK_SPEED,true,true,true,true,7,9,1.4,true,false,源码确认
|
||||
12,CRITICAL_RATE,true,true,true,true,10,12,1.5,true,false,源码确认
|
||||
13,LIFE_STEAL,true,true,true,true,4.5,7.5,1.5,true,false,源码确认
|
||||
|
||||
|
@@ -0,0 +1,5 @@
|
||||
rule_id,scope,formula,delta,weight,probability,source_tag,native_entry,notes
|
||||
GL-001,normal_main_stage,"GearLevel=max(1,Floor+delta)",0,90,0.9375,源码确认,0x55BE240,Floor is one-based
|
||||
GL-002,normal_main_stage,"GearLevel=max(1,Floor+delta)",1,5,0.0520833333,源码确认,0x55BE240,Floor is one-based
|
||||
GL-003,normal_main_stage,"GearLevel=max(1,Floor+delta)",2,1,0.0104166667,源码确认,0x55BE240,Floor is one-based
|
||||
|
||||
|
@@ -0,0 +1,8 @@
|
||||
grade_enum,rarity_cn,rarity_en,base_weight,base_probability,affix_count,sorted_star_pattern,main_effect,source_tag
|
||||
0,灰,Normal,210,0.6840390879,0,none,none,源码确认
|
||||
1,绿,Rare,60,0.1954397394,1,"1",none,源码确认
|
||||
2,蓝,Epic,28,0.0912052117,2,"1|1",none,源码确认
|
||||
3,金,Legend,4,0.0130293160,3,"2|1|1",none,源码确认
|
||||
4,彩,Myth,1,0.0032573290,3,"4|1|1 OR 3|2|1 OR 2|2|2",main_effective_level_plus_1,源码确认
|
||||
5,红,Arcane,4,0.0130293160,3,"4|1|1",selected_affix_arcane_marked,源码确认
|
||||
|
||||
|
@@ -0,0 +1,8 @@
|
||||
kind,slot_or_status,formula,rounding,source_tag
|
||||
main,Ingame_Weapon,"ATTACK_POWER; effectiveLevel=GearLevel-1+(rarity==Myth?1:0)",integer,源码确认
|
||||
main,Ingame_Ring,"HEALTH; effectiveLevel=GearLevel-1+(rarity==Myth?1:0)",integer,源码确认
|
||||
main,Ingame_Gauntlet,"AIM; effectiveLevel=GearLevel-1+(rarity==Myth?1:0)",integer,源码确认
|
||||
main,Ingame_Boots,"DEFENSE; effectiveLevel=GearLevel-1+(rarity==Myth?1:0)",one_decimal,源码确认
|
||||
affix,all,"effectiveLevel=GearLevel+plusLevel-1; min=baseMin+plusValue*effectiveLevel; max=baseMax+plusValue*effectiveLevel",by_weaponstatus_isFloat,源码确认
|
||||
boss_mid_drop,boss_0,"first downward crossing HP<=50%; spawn 1 additional gear; idempotent per battle",n/a,验证版新增
|
||||
|
||||
|
@@ -0,0 +1,97 @@
|
||||
"offer_id","item_type","item_id","name_zh_cn","price","buy_limit","fixed_key","fixed_sort","source_catalog_loaded","mvp_enabled","pool","reason"
|
||||
"100","TILE","137","铁匠铺","6","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"101","TILE","138","恢復","9","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"102","TILE","139","来点节奏","7","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"103","TILE","140","勇士遗骸","4","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"104","TILE","141","宝箱","5","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"105","TILE","142","抽取","5","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"106","TILE","143","骰子对决","4","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"107","TILE","144","增幅星星","7","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"108","TILE","151","夹娃娃机","7","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"109","TILE","152","黄金马车","7","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"110","TILE","164","惊心骰子","5","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"111","TILE","166","史莱姆神射手","8","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"112","AUGMENT","100","守护一击","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"113","AUGMENT","102","吸血","14","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"114","AUGMENT","103","攻击弱点","10","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"115","AUGMENT","106","奇蹟骰子","27","1","","","true","false","random slot","Disabled system: revive or burn chain"
|
||||
"116","AUGMENT","108","起始一击","12","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"117","AUGMENT","109","攻击力加速","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"118","AUGMENT","110","攻击速度加速","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"119","AUGMENT","111","恢復骰子","23","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"120","AUGMENT","112","战斗狂","16","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"121","AUGMENT","113","祝福的开始","14","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"122","AUGMENT","114","快速迴避","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"123","AUGMENT","115","幸运骰子","14","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"124","AUGMENT","116","守护骰子","20","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"125","AUGMENT","117","吸收灵魂","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"126","AUGMENT","118","腐蚀一击","16","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"127","AUGMENT","121","多多益善","10","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"128","AUGMENT","122","奇数骰子","13","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"129","AUGMENT","124","掠夺者","19","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"130","AUGMENT","125","顽强生命","18","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"131","AUGMENT","126","呼唤闪电","16","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"132","AUGMENT","132","质重于量","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"133","AUGMENT","147","调整数量","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"134","AUGMENT","148","支援金","10","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"135","AUGMENT","149","补充骰子","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"136","AUGMENT","150","掠夺药水","19","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"137","AUGMENT","151","领袖气质","8","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"138","AUGMENT","152","都市计画","11","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"139","AUGMENT","153","刺激","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"140","AUGMENT","154","战后休息","24","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"141","AUGMENT","156","残火","16","1","","","true","false","random slot","Disabled system: revive or burn chain"
|
||||
"142","AUGMENT","157","点燃","18","1","","","true","false","random slot","Disabled system: revive or burn chain"
|
||||
"143","POTION","100","立即恢復药水","16","1","","","true","true","random slot","Only the healing potion family is retained"
|
||||
"144","POTION","101","持续恢復药水","15","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"145","POTION","103","攻击药水","15","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"146","POTION","104","命中药水","13","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"147","POTION","105","暴击药水","14","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"148","POTION","106","吸血药水","16","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"149","POTION","107","防禦药水","20","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"150","POTION","108","反击药水","19","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"151","POTION","109","迴避药水","13","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"152","STAT","100","攻击力","3","10","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"153","STAT","101","生命值上限","3","10","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"154","STAT","102","命中","5","5","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"155","STAT","103","防禦力","3","10","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"156","STAT","104","迴避","5","5","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"157","STAT","105","每秒恢復","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"158","STAT","106","整体攻击","9","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"159","STAT","107","固定伤害","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"160","STAT","108","击杀后恢復","7","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"161","STAT","109","反击","5","5","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"162","STAT","110","攻击速度","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"163","STAT","111","暴击率","7","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"164","STAT","112","吸血","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"165","FIXED","","药水持有量Lv.{0}","10","1","potionCount","0","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"166","FIXED","","药水持有量Lv.{0}","15","1","potionCount","1","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"167","FIXED","","药水持有量Lv.{0}","21","1","potionCount","2","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"168","FIXED","","药水持有量Lv.{0}","28","1","potionCount","3","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"169","FIXED","","药水持有量Lv.{0}","36","1","potionCount","4","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"170","FIXED","","药水持有量Lv.{0}","45","1","potionCount","5","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"171","FIXED","","药水持有量Lv.{0}","55","1","potionCount","6","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"172","FIXED","","药水持有量Lv.{0}","66","1","potionCount","7","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"173","FIXED","","药水持有量Lv.{0}","78","1","potionCount","8","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"174","FIXED","","药水恢復量Lv.{0}","7","1","potionHeal","0","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"175","FIXED","","药水恢復量Lv.{0}","11","1","potionHeal","1","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"176","FIXED","","药水恢復量Lv.{0}","15","1","potionHeal","2","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"177","FIXED","","药水恢復量Lv.{0}","20","1","potionHeal","3","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"178","FIXED","","药水恢復量Lv.{0}","25","1","potionHeal","4","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"179","FIXED","","药水恢復量Lv.{0}","30","1","potionHeal","5","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"180","FIXED","","药水恢復量Lv.{0}","35","1","potionHeal","6","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"181","FIXED","","药水恢復量Lv.{0}","40","1","potionHeal","7","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"182","FIXED","","药水恢復量Lv.{0}","45","1","potionHeal","8","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"183","FIXED","","药水恢復量Lv.{0}","50","1","potionHeal","9","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"184","FIXED","","药水恢復量Lv.{0}","55","1","potionHeal","10","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"185","FIXED","","药水恢復量Lv.{0}","60","1","potionHeal","11","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"186","FIXED","","药水恢復量Lv.{0}","65","1","potionHeal","12","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"187","FIXED","","药水恢復量Lv.{0}","70","1","potionHeal","13","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"188","FIXED","","药水恢復量Lv.{0}","75","1","potionHeal","14","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"189","FIXED","","药水恢復量Lv.{0}","80","1","potionHeal","15","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"190","FIXED","","药水恢復量Lv.{0}","85","1","potionHeal","16","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"191","FIXED","","药水恢復量Lv.{0}","90","1","potionHeal","17","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"192","FIXED","","药水恢復量Lv.{0}","95","1","potionHeal","18","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"193","FIXED","","药水恢復量Lv.{0}","100","1","potionHeal","19","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"194","FIXED","","补充药水","5","-1","potionAdd","0","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"195","LOTTO","","彩券","5","1","","","true","false","random slot","Lottery event is outside the frozen first-version scope"
|
||||
|
@@ -0,0 +1,12 @@
|
||||
# 05-商店
|
||||
|
||||
商品目录、槽位、刷新、购买、固定升级与黑市价格。
|
||||
|
||||
## 文件
|
||||
|
||||
- [03-shop-product-whitelist.csv](./03-shop-product-whitelist.csv) — contract;来源:`analysis/mvp-rules-closure/03-shop-product-whitelist.csv`
|
||||
- [祝福装备商店综合逆向报告.md](./%E7%A5%9D%E7%A6%8F%E8%A3%85%E5%A4%87%E5%95%86%E5%BA%97%E7%BB%BC%E5%90%88%E9%80%86%E5%90%91%E6%8A%A5%E5%91%8A.md) — report;来源:`analysis/catalog-reverse/2026-08-31_逆向-HEROLL祝福装备商店完整清单-report.md`
|
||||
- [shop-catalog.csv](./shop-catalog.csv) — catalog;来源:`analysis/catalog-reverse/tables/shop-catalog.csv`
|
||||
- [shop-mechanics.csv](./shop-mechanics.csv) — table;来源:`analysis/catalog-reverse/tables/shop-mechanics.csv`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,97 @@
|
||||
offer_id,string_id,item_type,item_id,name_zh_cn,effect_zh_cn_template,base_price_points,purchase_limit,fixed_key,fixed_sort,fixed_slot,is_sub_text,title_key,description_key,price_growth_rule,source_tag
|
||||
100,TILE_137,TILE,137,铁匠铺,于铁匠铺测试你的运气。,6,1,,,-1,False,tile_title_GoodEventSmithy,tile_desc_GoodEventSmithy,无自动涨价,源码确认
|
||||
101,TILE_138,TILE,138,恢復,获得随机数量的恢復药水。,9,1,,,-1,False,tile_title_GoodEventRecovery,tile_desc_GoodEventRecovery,无自动涨价,源码确认
|
||||
102,TILE_139,TILE,139,来点节奏,享受节奏,证明自己的实力。,7,1,,,-1,False,tile_title_GoodEventLegendGear,tile_desc_GoodEventLegendGear,无自动涨价,源码确认
|
||||
103,TILE_140,TILE,140,勇士遗骸,以往勇士的遗产正在沉睡当中。,4,1,,,-1,False,tile_title_GoodEventHeroBody,tile_desc_GoodEventHeroBody,无自动涨价,源码确认
|
||||
104,TILE_141,TILE,141,宝箱,寻找装着多项装备的宝箱。,5,1,,,-1,False,tile_title_GoodEventChest,tile_desc_GoodEventChest,无自动涨价,源码确认
|
||||
105,TILE_142,TILE,142,抽取,财富与名望正在等着你。,5,1,,,-1,False,tile_title_GoodEventLotto,tile_desc_GoodEventLotto,无自动涨价,源码确认
|
||||
106,TILE_143,TILE,143,骰子对决,以前村里流行的传统游戏。,4,1,,,-1,False,tile_title_GoodEventBlackJack,tile_desc_GoodEventBlackJack,无自动涨价,源码确认
|
||||
107,TILE_144,TILE,144,增幅星星,可强化持有装备。,7,1,,,-1,False,tile_title_GoodEventPowerStar,tile_desc_GoodEventPowerStar,无自动涨价,源码确认
|
||||
108,TILE_151,TILE,151,夹娃娃机,使用夹子夹取想要的奖励。,7,1,,,-1,False,tile_title_GoodEventClawGrab,tile_desc_GoodEventClawGrab,无自动涨价,源码确认
|
||||
109,TILE_152,TILE,152,黄金马车,有人偷走凤珠的宝物!,7,1,,,-1,False,tile_title_GoodEventGoldCarriage,tile_desc_GoodEventGoldCarriage,无自动涨价,源码确认
|
||||
110,TILE_164,TILE,164,惊心骰子,请骰动命运骰子。,5,1,,,-1,False,tile_title_GoodEventDiceMachine,tile_desc_GoodEventDiceMachine,无自动涨价,源码确认
|
||||
111,TILE_166,TILE,166,史莱姆神射手,发射史莱姆,获得奖励!,8,1,,,-1,False,tile_title_GoodEventBubbleShooter,tile_desc_GoodEventBubbleShooter,无自动涨价,源码确认
|
||||
112,AUGMENT_100,AUGMENT,100,守护一击,每攻击敌人{n}次,获得防护罩,17,1,,,-1,False,AttackShield_titleKey,AttackShield_desKey,无自动涨价,源码确认
|
||||
113,AUGMENT_102,AUGMENT,102,吸血,额外恢復{n}%暴击伤害,14,1,,,-1,False,CritHeal_titleKey,CritHeal_desKey,无自动涨价,源码确认
|
||||
114,AUGMENT_103,AUGMENT,103,攻击弱点,暴击攻击力+{n}%,10,1,,,-1,False,CritDamageUp_titleKey,CritDamageUp_desKey,无自动涨价,源码确认
|
||||
115,AUGMENT_106,AUGMENT,106,奇蹟骰子,濒临死亡危机, / 当骰子总和骰点大于{n},将復活,27,1,,,-1,False,Revive_titleKey,Revive_desKey,无自动涨价,源码确认
|
||||
116,AUGMENT_108,AUGMENT,108,起始一击,首次攻击伤害+{n}%,12,1,,,-1,False,FirstAttackDMGUp_titleKey,FirstAttackDMGUp_desKey,无自动涨价,源码确认
|
||||
117,AUGMENT_109,AUGMENT,109,攻击力加速,开始战斗3秒后,攻击力+{n}%,15,1,,,-1,False,DMGUpAfterSecond_titleKey,DMGUpAfterSecond_desKey,无自动涨价,源码确认
|
||||
118,AUGMENT_110,AUGMENT,110,攻击速度加速,开始战斗3秒后,攻击速度+{n}%,15,1,,,-1,False,ASPUpAfterSecond_titleKey,ASPUpAfterSecond_desKey,无自动涨价,源码确认
|
||||
119,AUGMENT_111,AUGMENT,111,恢復骰子,当骰子双倍时,恢復{n}%生命值,23,1,,,-1,False,DoubleHeal_titleKey,DoubleHeal_desKey,无自动涨价,源码确认
|
||||
120,AUGMENT_112,AUGMENT,112,战斗狂,每失去5%生命值,攻击速度+{n}%,16,1,,,-1,False,LowHPASPUp_titleKey,LowHPASPUp_desKey,无自动涨价,源码确认
|
||||
121,AUGMENT_113,AUGMENT,113,祝福的开始,战斗开始时,以{n}%机率恢復所有生命值,14,1,,,-1,False,BattleStartHeal_titleKey,BattleStartHeal_desKey,无自动涨价,源码确认
|
||||
122,AUGMENT_114,AUGMENT,114,快速迴避,被攻击时,以{n}%机率仅获得1伤害,15,1,,,-1,False,LuckyHit_titleKey,LuckyHit_desKey,无自动涨价,源码确认
|
||||
123,AUGMENT_115,AUGMENT,115,幸运骰子,当骰子总和骰点为7,攻击力+{n}%,14,1,,,-1,False,DiceSumDMGUp_titleKey,DiceSumDMGUp_desKey,无自动涨价,源码确认
|
||||
124,AUGMENT_116,AUGMENT,116,守护骰子,当骰子总和骰点为6以上,获得防护罩,20,1,,,-1,False,DiceSumShield_titleKey,DiceSumShield_desKey,无自动涨价,源码确认
|
||||
125,AUGMENT_117,AUGMENT,117,吸收灵魂,每当击杀敌人时,生命值永久增加{n},17,1,,,-1,False,KillHPUp_titleKey,KillHPUp_desKey,无自动涨价,源码确认
|
||||
126,AUGMENT_118,AUGMENT,118,腐蚀一击,每当攻击命中时,使敌人防禦力降低{n}%,16,1,,,-1,False,ReduceEnemyDEF_titleKey,ReduceEnemyDEF_desKey,无自动涨价,源码确认
|
||||
127,AUGMENT_121,AUGMENT,121,多多益善,战斗开始时,与敌人数量等比,使{stat}+{n}%,10,1,,,-1,False,EnemyCountStatUp_titleKey,EnemyCountStatUp_desKey,无自动涨价,源码确认
|
||||
128,AUGMENT_122,AUGMENT,122,奇数骰子,当所有骰子骰点为奇数时,暴击率+{n}%,13,1,,,-1,False,OddDiceCritUp_titleKey,OddDiceCritUp_desKey,无自动涨价,源码确认
|
||||
129,AUGMENT_124,AUGMENT,124,掠夺者,{sec}秒内击杀敌人时,获得装备,19,1,,,-1,False,KillInTimeGetGear_titleKey,KillInTimeGetGear_desKey,无自动涨价,源码确认
|
||||
130,AUGMENT_125,AUGMENT,125,顽强生命,开始战斗{sec}秒后,恢復{n}%失去的生命值,18,1,,,-1,False,HealAfterSecond_titleKey,HealAfterSecond_desKey,无自动涨价,源码确认
|
||||
131,AUGMENT_126,AUGMENT,126,呼唤闪电,每{sec}秒以{n}%机率召唤一次闪电,16,1,,,-1,False,LightingEverySec_titleKey,LightingEverySec_desKey,无自动涨价,源码确认
|
||||
132,AUGMENT_132,AUGMENT,132,质重于量,每击杀{n}个敌人,获得英雄阶级装备,17,1,,,-1,False,KillForHeroGear_titleKey,KillForHeroGear_desKey,无自动涨价,源码确认
|
||||
133,AUGMENT_147,AUGMENT,147,调整数量,移除所有各1个敌人,15,1,,,-1,False,KillAllEmeny_titleKey,KillAllEmeny_desKey,无自动涨价,源码确认
|
||||
134,AUGMENT_148,AUGMENT,148,支援金,该回合结束时,获得{n}点数,10,1,,,-1,False,PointSupply_titleKey,PointSupply_desKey,无自动涨价,源码确认
|
||||
135,AUGMENT_149,AUGMENT,149,补充骰子,当骰子总和骰点大于11,补充1个药水,17,1,,,-1,False,DicePotionGet_titleKey,DicePotionGet_desKey,无自动涨价,源码确认
|
||||
136,AUGMENT_150,AUGMENT,150,掠夺药水,每当击杀{n}个敌人时,获得1个药水,19,1,,,-1,False,KillPotionGet_titleKey,KillPotionGet_desKey,无自动涨价,源码确认
|
||||
137,AUGMENT_151,AUGMENT,151,领袖气质,每次进入商店时,增加{n}次免费更新,8,1,,,-1,False,ShopFreeReroll_titleKey,ShopFreeReroll_desKey,无自动涨价,源码确认
|
||||
138,AUGMENT_152,AUGMENT,152,都市计画,于空地建设时,额外建设{n}个建筑,11,1,,,-1,False,EmptyTripleBuild_titleKey,EmptyTripleBuild_desKey,无自动涨价,源码确认
|
||||
139,AUGMENT_153,AUGMENT,153,刺激,迴避时,恢復生命值上限的{n}%,15,1,,,-1,False,EvaHeal_titleKey,EvaHeal_desKey,无自动涨价,源码确认
|
||||
140,AUGMENT_154,AUGMENT,154,战后休息,战斗结束后,恢復生命值上限的{n}%,24,1,,,-1,False,BattleEndHeal_titleKey,BattleEndHeal_desKey,无自动涨价,源码确认
|
||||
141,AUGMENT_156,AUGMENT,156,残火,若受到<link='keyword_burn'><style=keyword>烧伤</style></link>的敌人死亡,将引起爆炸,对所有敌人造成攻击力{n}%的伤害。,16,1,,,-1,False,BurnEnemyDead_titleKey,BurnEnemyDead_desKey,无自动涨价,源码确认
|
||||
142,AUGMENT_157,AUGMENT,157,点燃,战斗开始时,以{n}%机率使所有敌人<link='keyword_burn'><style=keyword>烧伤</style></link>+1,18,1,,,-1,False,FirstEnemyAllBurn_titleKey,FirstEnemyAllBurn_desKey,无自动涨价,源码确认
|
||||
143,POTION_100,POTION,100,立即恢復药水,立即恢復{1}生命值,16,1,,,-1,False,potion_title_InstantHealPotion,potion_desc_InstantHealPotion,无自动涨价,源码确认
|
||||
144,POTION_101,POTION,101,持续恢復药水,花费{0}秒恢復{1}生命值,15,1,,,-1,False,potion_title_RegenerationPotion,potion_desc_RegenerationPotion,无自动涨价,源码确认
|
||||
145,POTION_103,POTION,103,攻击药水,持续{0}秒攻击力增加{1}%,15,1,,,-1,False,potion_title_AttackPotion,potion_desc_AttackPotion,无自动涨价,源码确认
|
||||
146,POTION_104,POTION,104,命中药水,-,13,1,,,-1,False,potion_title_AccuracyPotion,potion_desc_AccuracyPotion,无自动涨价,源码确认
|
||||
147,POTION_105,POTION,105,暴击药水,持续{0}秒暴击率增加{1}%,14,1,,,-1,False,potion_title_CriticalPotion,potion_desc_CriticalPotion,无自动涨价,源码确认
|
||||
148,POTION_106,POTION,106,吸血药水,持续{0}秒吸血增加{1}%,16,1,,,-1,False,potion_title_LifestealPotion,potion_desc_LifestealPotion,无自动涨价,源码确认
|
||||
149,POTION_107,POTION,107,防禦药水,持续{0}秒防禦力强化{1}%,20,1,,,-1,False,potion_title_DefensePotion,potion_desc_DefensePotion,无自动涨价,源码确认
|
||||
150,POTION_108,POTION,108,反击药水,持续{0}秒反击增加{1}%,19,1,,,-1,False,potion_title_CounterattackPotion,potion_desc_CounterattackPotion,无自动涨价,源码确认
|
||||
151,POTION_109,POTION,109,迴避药水,持续{0}秒迴避增加{1}%,13,1,,,-1,False,potion_title_EvadePotion,potion_desc_EvadePotion,无自动涨价,源码确认
|
||||
152,STAT_100,STAT,100,攻击力,直接增加 攻击力,3,10,,,-1,False,status_ATTACK_POWER,,无自动涨价,源码确认
|
||||
153,STAT_101,STAT,101,生命值上限,直接增加 生命值上限,3,10,,,-1,False,status_HEALTH,,无自动涨价,源码确认
|
||||
154,STAT_102,STAT,102,命中,直接增加 命中,5,5,,,-1,False,status_AIM,,无自动涨价,源码确认
|
||||
155,STAT_103,STAT,103,防禦力,直接增加 防禦力,3,10,,,-1,False,status_DEFENSE,,无自动涨价,源码确认
|
||||
156,STAT_104,STAT,104,迴避,直接增加 迴避,5,5,,,-1,False,status_EVASION,,无自动涨价,源码确认
|
||||
157,STAT_105,STAT,105,每秒恢復,直接增加 每秒恢復,8,3,,,-1,False,status_REGEN_PER_SECOND,,无自动涨价,源码确认
|
||||
158,STAT_106,STAT,106,整体攻击,直接增加 整体攻击,9,3,,,-1,False,status_TOTAL_DAMAGE,,无自动涨价,源码确认
|
||||
159,STAT_107,STAT,107,固定伤害,直接增加 固定伤害,8,3,,,-1,False,status_TRUE_DAMAGE,,无自动涨价,源码确认
|
||||
160,STAT_108,STAT,108,击杀后恢復,直接增加 击杀后恢復,7,3,,,-1,False,status_KILL_HEAL,,无自动涨价,源码确认
|
||||
161,STAT_109,STAT,109,反击,直接增加 反击,5,5,,,-1,False,status_COUNTER_ATTACK,,无自动涨价,源码确认
|
||||
162,STAT_110,STAT,110,攻击速度,直接增加 攻击速度,8,3,,,-1,False,status_ATTACK_SPEED,,无自动涨价,源码确认
|
||||
163,STAT_111,STAT,111,暴击率,直接增加 暴击率,7,3,,,-1,False,status_CRITICAL_RATE,,无自动涨价,源码确认
|
||||
164,STAT_112,STAT,112,吸血,直接增加 吸血,8,3,,,-1,False,status_LIFE_STEAL,,无自动涨价,源码确认
|
||||
165,FIXED_potionCount_0,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,10,1,potionCount,0,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
166,FIXED_potionCount_1,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,15,1,potionCount,1,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
167,FIXED_potionCount_2,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,21,1,potionCount,2,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
168,FIXED_potionCount_3,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,28,1,potionCount,3,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
169,FIXED_potionCount_4,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,36,1,potionCount,4,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
170,FIXED_potionCount_5,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,45,1,potionCount,5,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
171,FIXED_potionCount_6,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,55,1,potionCount,6,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
172,FIXED_potionCount_7,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,66,1,potionCount,7,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
173,FIXED_potionCount_8,FIXED,,药水持有量Lv.{0},药水持有上限数量增加<color=green>+{0}</color>,78,1,potionCount,8,1,True,potionCount_titleKey,potionCount_desKey,固定链下一档配置价,源码确认
|
||||
174,FIXED_potionHeal_0,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,7,1,potionHeal,0,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
175,FIXED_potionHeal_1,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,11,1,potionHeal,1,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
176,FIXED_potionHeal_2,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,15,1,potionHeal,2,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
177,FIXED_potionHeal_3,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,20,1,potionHeal,3,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
178,FIXED_potionHeal_4,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,25,1,potionHeal,4,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
179,FIXED_potionHeal_5,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,30,1,potionHeal,5,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
180,FIXED_potionHeal_6,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,35,1,potionHeal,6,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
181,FIXED_potionHeal_7,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,40,1,potionHeal,7,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
182,FIXED_potionHeal_8,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,45,1,potionHeal,8,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
183,FIXED_potionHeal_9,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,50,1,potionHeal,9,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
184,FIXED_potionHeal_10,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,55,1,potionHeal,10,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
185,FIXED_potionHeal_11,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,60,1,potionHeal,11,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
186,FIXED_potionHeal_12,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,65,1,potionHeal,12,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
187,FIXED_potionHeal_13,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,70,1,potionHeal,13,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
188,FIXED_potionHeal_14,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,75,1,potionHeal,14,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
189,FIXED_potionHeal_15,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,80,1,potionHeal,15,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
190,FIXED_potionHeal_16,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,85,1,potionHeal,16,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
191,FIXED_potionHeal_17,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,90,1,potionHeal,17,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
192,FIXED_potionHeal_18,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,95,1,potionHeal,18,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
193,FIXED_potionHeal_19,FIXED,,药水恢復量Lv.{0},药水恢復量增加<color=green>+{0}</color>,100,1,potionHeal,19,2,True,potionHeal_titleKey,potionHeal_desKey,固定链下一档配置价,源码确认
|
||||
194,FIXED_potionAdd_0,FIXED,,补充药水,补充<color=green>1</color>个药水,5,-1,potionAdd,0,0,True,potionAdd_titleKey,potionAdd_desKey,无自动涨价,源码确认
|
||||
195,Lotto,LOTTO,,彩券,测试运气。,5,1,,,-1,False,LOTTO_titleKey,LOTTO_tag_icon_tagKey,无自动涨价,源码确认
|
||||
|
@@ -0,0 +1,7 @@
|
||||
mechanic,formula,values,evidence,confidence
|
||||
付费刷新价格,cost=3+2*paidRerollCount,"3,5,7,9,...","gameconfig.shopRerollCost=3,2; IngameShopView 0x54E217C-0x54E219C",高
|
||||
免费刷新,freeRerollCount-=1; paidRerollCount unchanged,不扣点数且不推高下一次付费刷新价格,IngameShopView 0x54E22F0-0x54E23A4,高
|
||||
普通商品重复购买,remainBuyCount-=1; price unchanged,buyCount=-1 means unlimited; otherwise sold out at zero,IngameShopItemSlot.BuyItem 0x54DE724-0x54DE74C,高
|
||||
固定升级链,buy current fixedSort then expose next fixedSort,"prices are explicit per row, not a hidden multiplier",ingameshoplist.csv fixedKey/fixedSort/fixedSlot,高
|
||||
黑市附加价,price=base+trunc(base*surchargePercent/100),percentage is serialized priceSurchargePer; exact prefab value not recovered,IngameShopItemSlot.SetSurcharge 0x54DE0F4-0x54DE21C; IngameShopView isBlackMarket/priceSurchargePer,公式高/百分比未知
|
||||
商品槽,3 fixed slots + 3 random special slots,reroll replaces random slots; fixed upgrade progress persists,IngameShopView fixedSlots/specialSlots; source video and recovered iteration paths,高
|
||||
|
@@ -0,0 +1,168 @@
|
||||
# HEROLL 2.0.1 祝福、装备与局内商店逆向清单
|
||||
|
||||
> 范围:仅 HEROLL 2.0.1。结论来自本地 XAPK/Unity 配置、本地化资产及解密后的 `libil2cpp`;未混用其他项目资料。本文用于内部玩法验证,不代表发行授权。
|
||||
|
||||
## 1. 结论摘要
|
||||
|
||||
| 模块 | 逆向结论 | 置信度 |
|
||||
|---|---|---|
|
||||
| 祝福 | `augment.csv` 共 58 行,其中原作启用 31 条;名称和效果模板均已从原作简中本地化资产还原 | 高 |
|
||||
| 装备 | 局内装备 40 件,武器/戒指/护手/鞋子各 10 件;装备 ID 不绑定品质与随机词条 | 高 |
|
||||
| 品质 | 六档:灰/绿/蓝/金/彩/红;基础权重 `210/60/28/4/1/4`,副词条数 `0/1/2/3/3/3` | 高 |
|
||||
| 装备等级 | 普通关卡 `GearLevel = Floor + Weighted(0,1,2; 90,5,1)` | 高 |
|
||||
| 商店 | 源码商品 96 条:地块 12、祝福 31、药水 9、属性 13、固定升级 30、彩票 1 | 高 |
|
||||
| 刷新 | 商店打开时付费刷新计数归零;第 `k` 次付费刷新价格为 `3 + 2k`,所以依次为 3、5、7、9…… | 高 |
|
||||
| 重复购买 | 没有通用“重复购买涨价”。普通商品只减少剩余购买次数,价格不变;固定升级通过不同等级商品行形成预设价格链 | 高 |
|
||||
| 黑市 | 独立加价公式 `最终价 = 基础价 + trunc(基础价 × 加价百分比 / 100)`;当前样本未闭合序列化的百分比常量 | 中高 |
|
||||
|
||||
完整逐行数据见同目录的 `tables/` CSV 和 Excel 工作簿。
|
||||
|
||||
## 2. 启用祝福列表(31 条)
|
||||
|
||||
效果文字保留原作占位符:`{n}` 为数值、`{sec}` 为秒数、`{stat}` 为属性名。升级数组、可叠加标志、触发概率、图标和依赖字段在完整表中保留。
|
||||
|
||||
| ID | 祝福 | 原作简中效果模板 | 配置值 |
|
||||
|---:|---|---|---|
|
||||
| 100 | 守护一击 | 每攻击敌人 {n} 次,获得防护罩 | 6 |
|
||||
| 102 | 吸血 | 额外恢复 {n}% 暴击伤害 | 15/20/25/30 |
|
||||
| 103 | 攻击弱点 | 暴击攻击力 +{n}% | 30/35/40 |
|
||||
| 106 | 奇迹骰子 | 濒临死亡时,当骰子总和大于 {n},将复活 | 4 |
|
||||
| 108 | 起始一击 | 首次攻击伤害 +{n}% | 70/80/90 |
|
||||
| 109 | 攻击力加速 | 开始战斗 3 秒后,攻击力 +{n}% | 30 |
|
||||
| 110 | 攻击速度加速 | 开始战斗 3 秒后,攻击速度 +{n}% | 30 |
|
||||
| 111 | 恢复骰子 | 当骰子双倍时,恢复 {n}% 生命值 | 8 |
|
||||
| 112 | 战斗狂 | 每失去 5% 生命值,攻击速度 +{n}% | 3 |
|
||||
| 113 | 祝福的开始 | 战斗开始时,以 {n}% 概率恢复所有生命值 | 10 |
|
||||
| 114 | 快速回避 | 被攻击时,以 {n}% 概率仅受到 1 点伤害 | 4 |
|
||||
| 115 | 幸运骰子 | 当骰子总和为 7,攻击力 +{n}% | 30/40/50 |
|
||||
| 116 | 守护骰子 | 当骰子总和为 6 以上,获得防护罩 | 1 |
|
||||
| 117 | 吸收灵魂 | 每次击杀敌人,生命值永久增加 {n} | 5 |
|
||||
| 118 | 腐蚀一击 | 每次攻击命中,使敌人防御力降低 {n}% | 10/20/30 |
|
||||
| 121 | 多多益善 | 战斗开始时,按敌人数量使 {stat} +{n}% | 8 |
|
||||
| 122 | 奇数骰子 | 当所有骰子点数为奇数时,暴击率 +{n}% | 20 |
|
||||
| 124 | 掠夺者 | 在 {sec} 秒内击杀敌人时,获得装备 | 0(时间字段另存) |
|
||||
| 125 | 顽强生命 | 战斗开始 {sec} 秒后,恢复 {n}% 已损生命值 | 20 |
|
||||
| 126 | 呼唤闪电 | 每 {sec} 秒以 {n}% 概率召唤一次闪电 | 10 |
|
||||
| 132 | 质重于量 | 每击杀 {n} 个敌人,获得英雄阶级装备 | 10 |
|
||||
| 147 | 调整数量 | 移除所有各 1 个敌人 | 0 |
|
||||
| 148 | 支援金 | 该回合结束时,获得 {n} 点数 | 20 |
|
||||
| 149 | 补充骰子 | 当骰子总和大于 11,补充 1 个药水 | 0 |
|
||||
| 150 | 掠夺药水 | 每击杀 {n} 个敌人,获得 1 个药水 | 10 |
|
||||
| 151 | 领袖气质 | 每次进入商店时,增加 {n} 次免费刷新 | 1 |
|
||||
| 152 | 都市计划 | 于空地建设时,额外建设 {n} 个建筑 | 2 |
|
||||
| 153 | 刺激 | 回避时,恢复生命值上限的 {n}% | 1/2/3 |
|
||||
| 154 | 战后休息 | 战斗结束后,恢复生命值上限的 {n}% | 10 |
|
||||
| 156 | 残火 | 受到烧伤的敌人死亡时爆炸,对全体造成攻击力 {n}% 的伤害 | 150 |
|
||||
| 157 | 点燃 | 战斗开始时,以 {n}% 概率使所有敌人烧伤 +1 | 10 |
|
||||
|
||||
说明:表内对繁体/异体字做了便于开发阅读的简体规范化;CSV 中保留原始 `zh-cn` 文本和英文模板。
|
||||
|
||||
## 3. 装备列表与生成规则
|
||||
|
||||
### 3.1 40 件装备本体
|
||||
|
||||
| 部位 | 主属性 | 10 件原作装备 |
|
||||
|---|---|---|
|
||||
| 武器 | `ATTACK_POWER` | 冒险者匕首、誓约匕首、破碎匕首、樵夫匕首、亡者匕首、神圣匕首、霜光匕首、光之匕首、祭坛匕首、烈火匕首 |
|
||||
| 戒指 | `HEALTH` | 冒险者戒指、誓约戒指、星星戒指、樵夫戒指、亡者戒指、龙之戒指、霜光戒指、幸运戒指、堕落戒指、永存戒指 |
|
||||
| 护手 | `AIM` | 冒险者手套、誓约手套、古代手套、樵夫手套、神圣手套、龙之手套、霜光手套、幸运手套、侏儒手套、永劫手套 |
|
||||
| 鞋子 | `DEFENSE` | 冒险者靴子、誓约靴子、古代靴子、樵夫靴子、神圣靴子、猎龙者靴子、霜光靴子、幸运靴子、堕落靴子、永劫靴子 |
|
||||
|
||||
### 3.2 品质、等级与词条
|
||||
|
||||
装备本体、品质、等级和随机词条是分阶段生成,不能把某件装备固化成某个品质。
|
||||
|
||||
| 品质 | 基础权重 | 无修正基础概率 | 副词条数 |
|
||||
|---|---:|---:|---:|
|
||||
| Normal(灰) | 210 | 68.40% | 0 |
|
||||
| Rare(绿) | 60 | 19.54% | 1 |
|
||||
| Epic(蓝) | 28 | 9.12% | 2 |
|
||||
| Legend(金) | 4 | 1.30% | 3 |
|
||||
| Myth(彩) | 1 | 0.33% | 3 |
|
||||
| Arcane(红) | 4 | 1.30% | 3 |
|
||||
|
||||
- 等级:`Floor + Δ`,`Δ=0/1/2` 的权重为 `90/5/1`;归一化概率约为 93.75%/5.21%/1.04%。
|
||||
- 所有四个部位共享九项不重复随机副词条池:闪避、每秒恢复、总伤害、真实伤害、击杀恢复、反击、攻击速度、暴击率、生命偷取。
|
||||
- 星级是 `Status.plusLevel`,属于词条强化层,不是装备等级或品质的别名。
|
||||
- 品质决定副词条数量及可用强化资源,但装备名称本身不决定品质、等级或词条。
|
||||
- 主属性/副词条数值公式和星级分配证据已在既有掉落规则报告闭合,本清单直接复用,不重复创造一套规则。
|
||||
|
||||
## 4. 商店商品(96 条)
|
||||
|
||||
### 4.1 商品构成
|
||||
|
||||
| 类型 | 数量 | ID 范围 | 定价/限购方式 |
|
||||
|---|---:|---|---|
|
||||
| 地块 `TILE` | 12 | 100–111 | 每行固定价格;通常限购 1 |
|
||||
| 祝福 `AUGMENT` | 31 | 112–142 | 每行固定价格;限购 1 |
|
||||
| 药水 `POTION` | 9 | 143–151 | 每行固定价格;限购 1 |
|
||||
| 直接属性 `STAT` | 13 | 152–164 | 每行固定价格;限购 3/5/10 |
|
||||
| 固定升级 `FIXED` | 30 | 165–194 | 等级链逐行预设价格;末项药水补充可重复购买 |
|
||||
| 彩票 `LOTTO` | 1 | 195 | 价格 5;限购 1 |
|
||||
|
||||
96 条商品的中文名称、效果、价格、`buyCount`、等级和键值见 `tables/shop-catalog.csv`。
|
||||
|
||||
### 4.2 刷新机制
|
||||
|
||||
原生函数确认如下:
|
||||
|
||||
```text
|
||||
打开商店:paidRerollCount = 0
|
||||
|
||||
当前付费刷新价:
|
||||
nowRerollCost = 3 + 2 * paidRerollCount
|
||||
|
||||
点击刷新:
|
||||
if freeRerollCount >= 1:
|
||||
freeRerollCount -= 1
|
||||
不扣点数,不增加 paidRerollCount
|
||||
else:
|
||||
扣除 nowRerollCost
|
||||
paidRerollCount += 1
|
||||
```
|
||||
|
||||
因此每次进入商店后的付费刷新序列是 **3、5、7、9、11……**。免费刷新优先消耗,不推进付费价格。刷新随机商品槽;固定升级槽的进度不因刷新重置。
|
||||
|
||||
### 4.3 重复购买与价格增长
|
||||
|
||||
这里需要纠正一个常见误解:源码不存在“同一普通商品每买一次按百分比涨价”的通用逻辑。
|
||||
|
||||
- 普通商品购买成功后,只执行 `remainBuyCount -= 1`;归零后售罄,价格字段不变化。
|
||||
- 直接属性商品可购买多次,但每次价格仍是该商品行的固定价格,直到达到限购。
|
||||
- 固定升级看似“重复购买涨价”,实际是买完当前等级后切换到下一条预配置商品行。
|
||||
|
||||
固定升级价格链:
|
||||
|
||||
| 升级族 | 价格序列 | 相邻涨幅 |
|
||||
|---|---|---|
|
||||
| 药水持有上限 `potionCount` | 10, 15, 21, 28, 36, 45, 55, 66, 78 | +5,+6,+7,+8,+9,+10,+11,+12 |
|
||||
| 药水恢复量 `potionHeal` | 7, 11, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 | +4,+4,+5,之后每级 +5 |
|
||||
| 补充 1 瓶药水 `potionAdd` | 5 | 无限次;单价不增长 |
|
||||
|
||||
黑市加价是另一套机制,与购买次数无关:
|
||||
|
||||
`price = basePrice + trunc(basePrice × surchargePercent / 100)`
|
||||
|
||||
当前逆向样本已恢复公式和字段 `priceSurchargePer`,但没有足够证据确定所有场景使用的序列化百分比,因此不填猜测值。
|
||||
|
||||
## 5. Evidence → Finding → Design Path
|
||||
|
||||
本轮证据记录:`E-CATALOG-BLESSING-001`、`E-CATALOG-EQUIP-001`、`E-CATALOG-SHOP-001`、`E-SHOP-RUNTIME-001`。
|
||||
|
||||
| Evidence | Finding | 可实施规则 |
|
||||
|---|---|---|
|
||||
| `augment.csv` + 本地化资产 | 31 条启用祝福及原作文本 | 祝福池严格取启用行,展示文案按键值格式化 |
|
||||
| `weapondrop.csv` + `weaponstatus.csv` + 原生生成函数 | 40 件装备、四部位主属性、动态品质/词条 | 装备本体与品质/等级/词条分离抽取 |
|
||||
| `ingameshoplist.csv` + 关联表 | 96 条商品、价格和购买上限 | 以商品行作为唯一配置源,不自行拼价 |
|
||||
| `gameconfig.shopRerollCost=3,2` + `0x54E1FD4` | 刷新成本为线性公式 | 每次进店重置付费计数;免费刷新优先 |
|
||||
| `BuyItem @ 0x54DE518` | 购买只递减剩余次数 | 普通重复购买不涨价 |
|
||||
| `SetSurcharge @ 0x54DE0A4` | 黑市使用独立百分比加价 | 不把黑市加价误写成重复购买涨价 |
|
||||
|
||||
## 6. 复现、限制与来源
|
||||
|
||||
- 结构化抽取脚本:`analysis/catalog-reverse/scripts/extract_catalogs.py`
|
||||
- 原生刷新公式:`IngameShopView` 方法 `0x06002CD2 @ 0x54E1FD4`,核心 `madd` 位于约 `0x54E2188`。
|
||||
- 刷新动作:`0x06002CD3 @ 0x54E2250`;免费次数优先分支约 `0x54E22F0–0x54E23A4`。
|
||||
- 购买计数:`IngameShopItemSlot.BuyItem @ 0x54DE518`,递减与售罄约 `0x54DE724–0x54DE74C`。
|
||||
- 黑市加价:`IngameShopItemSlot.SetSurcharge @ 0x54DE0A4`。
|
||||
- 未使用互联网补全:本地逆向数据已足够回答清单、刷新、价格和购买增长问题;唯一未闭合的黑市加价百分比明确保留为未知,没有以网络二手资料替代源码证据。
|
||||
@@ -0,0 +1,62 @@
|
||||
"domain","id","string_id","subtype","source_enabled","mvp_enabled","scope","min_stage","min_loop","gate_override","source"
|
||||
"Tile","100","Empty","Empty","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","101","NormalEnemy_1","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","102","NormalEnemy_2","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","103","NormalEnemy_3","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","104","NormalEnemy_4","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","105","BossAttackStrongEnemy","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","106","BossAttackBerserk1","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","110","BossAttackEvolve1","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","111","BossAttackEvolve2","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","112","BossAttackEvolve3","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","113","BossAttackEvolve4","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","114","BossAttackInfected","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","115","BossAttackInfectedHost3","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","116","BossAttackInfectedHost2","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","117","BossAttackInfectedHost1","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","118","MiniBoss","MiniBoss","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","119","Boss","Boss","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","124","AugmentRandom","Augment","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","125","CornerKillOneLineEnemy","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","127","CornerRace","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","128","CornerOneLineChest","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","129","CornerDiceBuilding","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","131","CornerBlackMarket","Corner","true","true","MVP active Corner","0","3","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","132","Start","Start","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","133","StartShop","Start","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","134","BadEventJail","BadEvent","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","135","BadEventPlusOneLineEnemy","BadEvent","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","137","GoodEventSmithy","GoodEvent","true","true","MVP active Good event","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","141","GoodEventChest","GoodEvent","true","true","MVP active Good event","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","143","GoodEventBlackJack","GoodEvent","true","true","MVP active Good event","0","3","Keep original minLoop=3 for natural generation; debug console may force","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","151","GoodEventClawGrab","GoodEvent","true","true","MVP active Good event","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","164","GoodEventDiceMachine","GoodEvent","true","true","MVP active Good event","0","3","Keep original minLoop=3 for natural generation; debug console may force","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","169","GoodEventSpito","GoodEvent","true","true","MVP active Good event","1","3","MVP validation override: original minStage=1,minLoop=3; use minStage=0,minLoop=0 in the Stage 0 validation build","newtile.csv + v0.2.8 scope freeze"
|
||||
"Blessing","100","AttackShield","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","102","CritHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","103","CritDamageUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","108","FirstAttackDMGUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","109","DMGUpAfterSecond","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","110","ASPUpAfterSecond","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","111","DoubleHeal","AUGMENT","true","true","main blessing candidate pool","","","Natural Double consumer confirmed by runtime observation; additive 8% max-HP heal per stack","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","112","LowHPASPUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","113","BattleStartHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","114","LuckyHit","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","115","DiceSumDMGUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","116","DiceSumShield","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","117","KillHPUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","118","ReduceEnemyDEF","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","121","EnemyCountStatUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","122","OddDiceCritUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","124","KillInTimeGetGear","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","125","HealAfterSecond","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","126","LightingEverySec","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","132","KillForHeroGear","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","147","KillAllEmeny","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","148","PointSupply","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","149","DicePotionGet","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","150","KillPotionGet","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","151","ShopFreeReroll","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","152","EmptyTripleBuild","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","153","EvaHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","154","BattleEndHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
|
@@ -0,0 +1,11 @@
|
||||
# 06-天道赐福
|
||||
|
||||
Blessing目录、候选池、叠加、依赖与首版启用范围。
|
||||
|
||||
## 文件
|
||||
|
||||
- [02-tile-corner-blessing-whitelist.csv](./02-tile-corner-blessing-whitelist.csv) — contract;来源:`analysis/mvp-rules-closure/02-tile-corner-blessing-whitelist.csv`
|
||||
- [祝福装备商店综合逆向报告.md](./%E7%A5%9D%E7%A6%8F%E8%A3%85%E5%A4%87%E5%95%86%E5%BA%97%E7%BB%BC%E5%90%88%E9%80%86%E5%90%91%E6%8A%A5%E5%91%8A.md) — report;来源:`analysis/catalog-reverse/2026-08-31_逆向-HEROLL祝福装备商店完整清单-report.md`
|
||||
- [blessings-catalog.csv](./blessings-catalog.csv) — catalog;来源:`analysis/catalog-reverse/tables/blessings-catalog.csv`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,32 @@
|
||||
source_id,string_id,name_zh_cn,name_en,effect_zh_cn_template,effect_en_template,prob_weight,stackable,linear_value,values,after_plus_value,time_value,max_count,stat_value,requires,icon,title_key,description_key,source_tag
|
||||
100,AttackShield,守护一击,Guardian Strike,每攻击敌人{n}次,获得防护罩,Gain a shield every {n} attacks,10.0,False,6,6,,-1,1,,,a_0,AttackShield_titleKey,AttackShield_desKey,源码确认
|
||||
102,CritHeal,吸血,Blood Drain,额外恢復{n}%暴击伤害,Recover {n}% of CRIT DMG dealt,10.0,True,15,"15,20,25,30",1,-1,999,,,a_2,CritHeal_titleKey,CritHeal_desKey,源码确认
|
||||
103,CritDamageUp,攻击弱点,Weakness Exploit,暴击攻击力+{n}%,CRIT DMG +{n}%,10.0,True,30,"30,35,40",2,-1,999,,,a_3,CritDamageUp_titleKey,CritDamageUp_desKey,源码确认
|
||||
106,Revive,奇蹟骰子,Miracle Dice,濒临死亡危机, / 当骰子总和骰点大于{n},将復活,Revive if the sum of the dice is {n} or higher,10.0,False,4,4,,-1,100,,,a_6,Revive_titleKey,Revive_desKey,源码确认
|
||||
108,FirstAttackDMGUp,起始一击,Opening Strike,首次攻击伤害+{n}%,First attack damage +{n}%,10.0,True,70,"70,80,90",1,-1,999,,,a_8,FirstAttackDMGUp_titleKey,FirstAttackDMGUp_desKey,源码确认
|
||||
109,DMGUpAfterSecond,攻击力加速,ATK Booster,开始战斗3秒后,攻击力+{n}%,ATK +{n}% after 3 seconds in battle,10.0,True,30,30,2,3,999,,,a_9,DMGUpAfterSecond_titleKey,DMGUpAfterSecond_desKey,源码确认
|
||||
110,ASPUpAfterSecond,攻击速度加速,ATK SPD Booster,开始战斗3秒后,攻击速度+{n}%,ATK SPD +{n}% after 3 seconds in battle,10.0,True,30,30,2,3,999,,,a_10,ASPUpAfterSecond_titleKey,ASPUpAfterSecond_desKey,源码确认
|
||||
111,DoubleHeal,恢復骰子,Healing Dice,当骰子双倍时,恢復{n}%生命值,Restore {n}% HP when a Double is rolled,10.0,True,8,8,2,-1,999,,,a_11,DoubleHeal_titleKey,DoubleHeal_desKey,源码确认
|
||||
112,LowHPASPUp,战斗狂,Warmonger,每失去5%生命值,攻击速度+{n}%,ATK SPD +{n}% for every 5% HP lost,10.0,True,3,3,1,-1,999,,,a_12,LowHPASPUp_titleKey,LowHPASPUp_desKey,源码确认
|
||||
113,BattleStartHeal,祝福的开始,Guardian Spirit,战斗开始时,以{n}%机率恢復所有生命值,{n}% chance to fully restore health at the start of combat,10.0,False,10,10,1,-1,6,,,a_13,BattleStartHeal_titleKey,BattleStartHeal_desKey,源码确认
|
||||
114,LuckyHit,快速迴避,Too Slow,被攻击时,以{n}%机率仅获得1伤害,{n}% chance to take only 1 damage when hit,10.0,False,4,4,1,-1,5,,,a_14,LuckyHit_titleKey,LuckyHit_desKey,源码确认
|
||||
115,DiceSumDMGUp,幸运骰子,Lucky Dice,当骰子总和骰点为7,攻击力+{n}%,ATK +{n}% when the sum of the dice is 7,10.0,True,30,"30,40,50",1,-1,999,,,a_15,DiceSumDMGUp_titleKey,DiceSumDMGUp_desKey,源码确认
|
||||
116,DiceSumShield,守护骰子,Protection Dice,当骰子总和骰点为6以上,获得防护罩,Gain a shield when the sum of the dice is 6 or higher,10.0,False,1,1,,-1,1,,,a_16,DiceSumShield_titleKey,DiceSumShield_desKey,源码确认
|
||||
117,KillHPUp,吸收灵魂,Soul Absorption,每当击杀敌人时,生命值永久增加{n},Permanently increase health by {n} each time you kill an enemy,10.0,True,10,5,1,-1,1,,,a_17,KillHPUp_titleKey,KillHPUp_desKey,源码确认
|
||||
118,ReduceEnemyDEF,腐蚀一击,Corrosive Strike,每当攻击命中时,使敌人防禦力降低{n}%,"On hit, reduces enemy DEF by {n}%",10.0,True,30,"10, 20, 30",1,-1,999,,,a_18,ReduceEnemyDEF_titleKey,ReduceEnemyDEF_desKey,源码确认
|
||||
121,EnemyCountStatUp,多多益善,The More / The Better,战斗开始时,与敌人数量等比,使{stat}+{n}%,{stat} +{n}% based on the number of enemies in battle,10.0,True,8,8,1,-1,5,ALL,,a_20,EnemyCountStatUp_titleKey,EnemyCountStatUp_desKey,源码确认
|
||||
122,OddDiceCritUp,奇数骰子,Dice of Odds,当所有骰子骰点为奇数时,暴击率+{n}%,CRIT RATE +{n}% when all dice are odd,10.0,True,20,20,2,-1,11,,,a_21,OddDiceCritUp_titleKey,OddDiceCritUp_desKey,源码确认
|
||||
124,KillInTimeGetGear,掠夺者,Pillager,{sec}秒内击杀敌人时,获得装备,Obtain equipment if you kill an enemy within {sec} seconds,10.0,False,0,0,,2.5,999,,,a_23,KillInTimeGetGear_titleKey,KillInTimeGetGear_desKey,源码确认
|
||||
125,HealAfterSecond,顽强生命,Persistent Life,开始战斗{sec}秒后,恢復{n}%失去的生命值,Recover {n}% of lost health {sec} seconds after combat begins,10.0,True,20,20,2,5,6,,,a_24,HealAfterSecond_titleKey,HealAfterSecond_desKey,源码确认
|
||||
126,LightingEverySec,呼唤闪电,Thunder Call,每{sec}秒以{n}%机率召唤一次闪电,Summon lightning with {n}% chance every {sec} sec,10.0,True,10,10,1,1,21,,,a_25,LightingEverySec_titleKey,LightingEverySec_desKey,源码确认
|
||||
132,KillForHeroGear,质重于量,Quality Over Quantity,每击杀{n}个敌人,获得英雄阶级装备,Obtain epic grade equipment for every {n} enemies killed,10.0,False,10,10,1,-1,999,,,a_29,KillForHeroGear_titleKey,KillForHeroGear_desKey,源码确认
|
||||
147,KillAllEmeny,调整数量,Population Control,移除所有各1个敌人,Remove one enemy from all enemy tiles,10.0,False,,0,,-1,999,,,a_44,KillAllEmeny_titleKey,KillAllEmeny_desKey,源码确认
|
||||
148,PointSupply,支援金,Subsidy,该回合结束时,获得{n}点数,Gain {n} points at the end of this turn,10.0,False,20,20,,-1,999,,,a_45,PointSupply_titleKey,PointSupply_desKey,源码确认
|
||||
149,DicePotionGet,补充骰子,Dice of Recharge,当骰子总和骰点大于11,补充1个药水,"If the sum of the dice is 11 or higher, recharge 1 potion",10.0,False,,0,,-1,5,,,a_46,DicePotionGet_titleKey,DicePotionGet_desKey,源码确认
|
||||
150,KillPotionGet,掠夺药水,Potion Plunder,每当击杀{n}个敌人时,获得1个药水,Gain 1 potion for every {n} enemies killed,10.0,True,10,10,1,-1,1,,,a_47,KillPotionGet_titleKey,KillPotionGet_desKey,源码确认
|
||||
151,ShopFreeReroll,领袖气质,Charisma,每次进入商店时,增加{n}次免费更新,Gain {n} free reroll per shop visit,10.0,True,1,1,1,-1,10,,,a_48,ShopFreeReroll_titleKey,ShopFreeReroll_desKey,源码确认
|
||||
152,EmptyTripleBuild,都市计画,Urban Planning,于空地建设时,额外建设{n}个建筑,Construct +{n} buildings when building on empty tile,10.0,False,2,2,,-1,999,,,a_49,EmptyTripleBuild_titleKey,EmptyTripleBuild_desKey,源码确认
|
||||
153,EvaHeal,刺激,Thrill,迴避时,恢復生命值上限的{n}%,Recover {n}% of max HP when evading,10.0,True,3,"1,2,3",1,-1,10,,,a_50,EvaHeal_titleKey,EvaHeal_desKey,源码确认
|
||||
154,BattleEndHeal,战后休息,Recuperation,战斗结束后,恢復生命值上限的{n}%,Recover {n}% of max HP after battle,10.0,True,10,10,1,-1,11,,,a_51,BattleEndHeal_titleKey,BattleEndHeal_desKey,源码确认
|
||||
156,BurnEnemyDead,残火,Embers,若受到<link='keyword_burn'><style=keyword>烧伤</style></link>的敌人死亡,将引起爆炸,对所有敌人造成攻击力{n}%的伤害。,"When an enemy with <link='keyword_burn'><style=keyword>Burn</style></link> dies, it explodes, dealing {n}% ATK to all enemies",10.0,True,150,150,5,-1,15,,FirstEnemyAllBurn,a_53,BurnEnemyDead_titleKey,BurnEnemyDead_desKey,源码确认
|
||||
157,FirstEnemyAllBurn,点燃,Ignite,战斗开始时,以{n}%机率使所有敌人<link='keyword_burn'><style=keyword>烧伤</style></link>+1,"At the start of battle, {n}% chance to inflict <link='keyword_burn'><style=keyword>Burn</style></link> +1 on all enemies",10.0,False,10,10,1,-1,10,,,a_54,FirstEnemyAllBurn_titleKey,FirstEnemyAllBurn_desKey,源码确认
|
||||
|
@@ -0,0 +1,168 @@
|
||||
# HEROLL 2.0.1 祝福、装备与局内商店逆向清单
|
||||
|
||||
> 范围:仅 HEROLL 2.0.1。结论来自本地 XAPK/Unity 配置、本地化资产及解密后的 `libil2cpp`;未混用其他项目资料。本文用于内部玩法验证,不代表发行授权。
|
||||
|
||||
## 1. 结论摘要
|
||||
|
||||
| 模块 | 逆向结论 | 置信度 |
|
||||
|---|---|---|
|
||||
| 祝福 | `augment.csv` 共 58 行,其中原作启用 31 条;名称和效果模板均已从原作简中本地化资产还原 | 高 |
|
||||
| 装备 | 局内装备 40 件,武器/戒指/护手/鞋子各 10 件;装备 ID 不绑定品质与随机词条 | 高 |
|
||||
| 品质 | 六档:灰/绿/蓝/金/彩/红;基础权重 `210/60/28/4/1/4`,副词条数 `0/1/2/3/3/3` | 高 |
|
||||
| 装备等级 | 普通关卡 `GearLevel = Floor + Weighted(0,1,2; 90,5,1)` | 高 |
|
||||
| 商店 | 源码商品 96 条:地块 12、祝福 31、药水 9、属性 13、固定升级 30、彩票 1 | 高 |
|
||||
| 刷新 | 商店打开时付费刷新计数归零;第 `k` 次付费刷新价格为 `3 + 2k`,所以依次为 3、5、7、9…… | 高 |
|
||||
| 重复购买 | 没有通用“重复购买涨价”。普通商品只减少剩余购买次数,价格不变;固定升级通过不同等级商品行形成预设价格链 | 高 |
|
||||
| 黑市 | 独立加价公式 `最终价 = 基础价 + trunc(基础价 × 加价百分比 / 100)`;当前样本未闭合序列化的百分比常量 | 中高 |
|
||||
|
||||
完整逐行数据见同目录的 `tables/` CSV 和 Excel 工作簿。
|
||||
|
||||
## 2. 启用祝福列表(31 条)
|
||||
|
||||
效果文字保留原作占位符:`{n}` 为数值、`{sec}` 为秒数、`{stat}` 为属性名。升级数组、可叠加标志、触发概率、图标和依赖字段在完整表中保留。
|
||||
|
||||
| ID | 祝福 | 原作简中效果模板 | 配置值 |
|
||||
|---:|---|---|---|
|
||||
| 100 | 守护一击 | 每攻击敌人 {n} 次,获得防护罩 | 6 |
|
||||
| 102 | 吸血 | 额外恢复 {n}% 暴击伤害 | 15/20/25/30 |
|
||||
| 103 | 攻击弱点 | 暴击攻击力 +{n}% | 30/35/40 |
|
||||
| 106 | 奇迹骰子 | 濒临死亡时,当骰子总和大于 {n},将复活 | 4 |
|
||||
| 108 | 起始一击 | 首次攻击伤害 +{n}% | 70/80/90 |
|
||||
| 109 | 攻击力加速 | 开始战斗 3 秒后,攻击力 +{n}% | 30 |
|
||||
| 110 | 攻击速度加速 | 开始战斗 3 秒后,攻击速度 +{n}% | 30 |
|
||||
| 111 | 恢复骰子 | 当骰子双倍时,恢复 {n}% 生命值 | 8 |
|
||||
| 112 | 战斗狂 | 每失去 5% 生命值,攻击速度 +{n}% | 3 |
|
||||
| 113 | 祝福的开始 | 战斗开始时,以 {n}% 概率恢复所有生命值 | 10 |
|
||||
| 114 | 快速回避 | 被攻击时,以 {n}% 概率仅受到 1 点伤害 | 4 |
|
||||
| 115 | 幸运骰子 | 当骰子总和为 7,攻击力 +{n}% | 30/40/50 |
|
||||
| 116 | 守护骰子 | 当骰子总和为 6 以上,获得防护罩 | 1 |
|
||||
| 117 | 吸收灵魂 | 每次击杀敌人,生命值永久增加 {n} | 5 |
|
||||
| 118 | 腐蚀一击 | 每次攻击命中,使敌人防御力降低 {n}% | 10/20/30 |
|
||||
| 121 | 多多益善 | 战斗开始时,按敌人数量使 {stat} +{n}% | 8 |
|
||||
| 122 | 奇数骰子 | 当所有骰子点数为奇数时,暴击率 +{n}% | 20 |
|
||||
| 124 | 掠夺者 | 在 {sec} 秒内击杀敌人时,获得装备 | 0(时间字段另存) |
|
||||
| 125 | 顽强生命 | 战斗开始 {sec} 秒后,恢复 {n}% 已损生命值 | 20 |
|
||||
| 126 | 呼唤闪电 | 每 {sec} 秒以 {n}% 概率召唤一次闪电 | 10 |
|
||||
| 132 | 质重于量 | 每击杀 {n} 个敌人,获得英雄阶级装备 | 10 |
|
||||
| 147 | 调整数量 | 移除所有各 1 个敌人 | 0 |
|
||||
| 148 | 支援金 | 该回合结束时,获得 {n} 点数 | 20 |
|
||||
| 149 | 补充骰子 | 当骰子总和大于 11,补充 1 个药水 | 0 |
|
||||
| 150 | 掠夺药水 | 每击杀 {n} 个敌人,获得 1 个药水 | 10 |
|
||||
| 151 | 领袖气质 | 每次进入商店时,增加 {n} 次免费刷新 | 1 |
|
||||
| 152 | 都市计划 | 于空地建设时,额外建设 {n} 个建筑 | 2 |
|
||||
| 153 | 刺激 | 回避时,恢复生命值上限的 {n}% | 1/2/3 |
|
||||
| 154 | 战后休息 | 战斗结束后,恢复生命值上限的 {n}% | 10 |
|
||||
| 156 | 残火 | 受到烧伤的敌人死亡时爆炸,对全体造成攻击力 {n}% 的伤害 | 150 |
|
||||
| 157 | 点燃 | 战斗开始时,以 {n}% 概率使所有敌人烧伤 +1 | 10 |
|
||||
|
||||
说明:表内对繁体/异体字做了便于开发阅读的简体规范化;CSV 中保留原始 `zh-cn` 文本和英文模板。
|
||||
|
||||
## 3. 装备列表与生成规则
|
||||
|
||||
### 3.1 40 件装备本体
|
||||
|
||||
| 部位 | 主属性 | 10 件原作装备 |
|
||||
|---|---|---|
|
||||
| 武器 | `ATTACK_POWER` | 冒险者匕首、誓约匕首、破碎匕首、樵夫匕首、亡者匕首、神圣匕首、霜光匕首、光之匕首、祭坛匕首、烈火匕首 |
|
||||
| 戒指 | `HEALTH` | 冒险者戒指、誓约戒指、星星戒指、樵夫戒指、亡者戒指、龙之戒指、霜光戒指、幸运戒指、堕落戒指、永存戒指 |
|
||||
| 护手 | `AIM` | 冒险者手套、誓约手套、古代手套、樵夫手套、神圣手套、龙之手套、霜光手套、幸运手套、侏儒手套、永劫手套 |
|
||||
| 鞋子 | `DEFENSE` | 冒险者靴子、誓约靴子、古代靴子、樵夫靴子、神圣靴子、猎龙者靴子、霜光靴子、幸运靴子、堕落靴子、永劫靴子 |
|
||||
|
||||
### 3.2 品质、等级与词条
|
||||
|
||||
装备本体、品质、等级和随机词条是分阶段生成,不能把某件装备固化成某个品质。
|
||||
|
||||
| 品质 | 基础权重 | 无修正基础概率 | 副词条数 |
|
||||
|---|---:|---:|---:|
|
||||
| Normal(灰) | 210 | 68.40% | 0 |
|
||||
| Rare(绿) | 60 | 19.54% | 1 |
|
||||
| Epic(蓝) | 28 | 9.12% | 2 |
|
||||
| Legend(金) | 4 | 1.30% | 3 |
|
||||
| Myth(彩) | 1 | 0.33% | 3 |
|
||||
| Arcane(红) | 4 | 1.30% | 3 |
|
||||
|
||||
- 等级:`Floor + Δ`,`Δ=0/1/2` 的权重为 `90/5/1`;归一化概率约为 93.75%/5.21%/1.04%。
|
||||
- 所有四个部位共享九项不重复随机副词条池:闪避、每秒恢复、总伤害、真实伤害、击杀恢复、反击、攻击速度、暴击率、生命偷取。
|
||||
- 星级是 `Status.plusLevel`,属于词条强化层,不是装备等级或品质的别名。
|
||||
- 品质决定副词条数量及可用强化资源,但装备名称本身不决定品质、等级或词条。
|
||||
- 主属性/副词条数值公式和星级分配证据已在既有掉落规则报告闭合,本清单直接复用,不重复创造一套规则。
|
||||
|
||||
## 4. 商店商品(96 条)
|
||||
|
||||
### 4.1 商品构成
|
||||
|
||||
| 类型 | 数量 | ID 范围 | 定价/限购方式 |
|
||||
|---|---:|---|---|
|
||||
| 地块 `TILE` | 12 | 100–111 | 每行固定价格;通常限购 1 |
|
||||
| 祝福 `AUGMENT` | 31 | 112–142 | 每行固定价格;限购 1 |
|
||||
| 药水 `POTION` | 9 | 143–151 | 每行固定价格;限购 1 |
|
||||
| 直接属性 `STAT` | 13 | 152–164 | 每行固定价格;限购 3/5/10 |
|
||||
| 固定升级 `FIXED` | 30 | 165–194 | 等级链逐行预设价格;末项药水补充可重复购买 |
|
||||
| 彩票 `LOTTO` | 1 | 195 | 价格 5;限购 1 |
|
||||
|
||||
96 条商品的中文名称、效果、价格、`buyCount`、等级和键值见 `tables/shop-catalog.csv`。
|
||||
|
||||
### 4.2 刷新机制
|
||||
|
||||
原生函数确认如下:
|
||||
|
||||
```text
|
||||
打开商店:paidRerollCount = 0
|
||||
|
||||
当前付费刷新价:
|
||||
nowRerollCost = 3 + 2 * paidRerollCount
|
||||
|
||||
点击刷新:
|
||||
if freeRerollCount >= 1:
|
||||
freeRerollCount -= 1
|
||||
不扣点数,不增加 paidRerollCount
|
||||
else:
|
||||
扣除 nowRerollCost
|
||||
paidRerollCount += 1
|
||||
```
|
||||
|
||||
因此每次进入商店后的付费刷新序列是 **3、5、7、9、11……**。免费刷新优先消耗,不推进付费价格。刷新随机商品槽;固定升级槽的进度不因刷新重置。
|
||||
|
||||
### 4.3 重复购买与价格增长
|
||||
|
||||
这里需要纠正一个常见误解:源码不存在“同一普通商品每买一次按百分比涨价”的通用逻辑。
|
||||
|
||||
- 普通商品购买成功后,只执行 `remainBuyCount -= 1`;归零后售罄,价格字段不变化。
|
||||
- 直接属性商品可购买多次,但每次价格仍是该商品行的固定价格,直到达到限购。
|
||||
- 固定升级看似“重复购买涨价”,实际是买完当前等级后切换到下一条预配置商品行。
|
||||
|
||||
固定升级价格链:
|
||||
|
||||
| 升级族 | 价格序列 | 相邻涨幅 |
|
||||
|---|---|---|
|
||||
| 药水持有上限 `potionCount` | 10, 15, 21, 28, 36, 45, 55, 66, 78 | +5,+6,+7,+8,+9,+10,+11,+12 |
|
||||
| 药水恢复量 `potionHeal` | 7, 11, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 | +4,+4,+5,之后每级 +5 |
|
||||
| 补充 1 瓶药水 `potionAdd` | 5 | 无限次;单价不增长 |
|
||||
|
||||
黑市加价是另一套机制,与购买次数无关:
|
||||
|
||||
`price = basePrice + trunc(basePrice × surchargePercent / 100)`
|
||||
|
||||
当前逆向样本已恢复公式和字段 `priceSurchargePer`,但没有足够证据确定所有场景使用的序列化百分比,因此不填猜测值。
|
||||
|
||||
## 5. Evidence → Finding → Design Path
|
||||
|
||||
本轮证据记录:`E-CATALOG-BLESSING-001`、`E-CATALOG-EQUIP-001`、`E-CATALOG-SHOP-001`、`E-SHOP-RUNTIME-001`。
|
||||
|
||||
| Evidence | Finding | 可实施规则 |
|
||||
|---|---|---|
|
||||
| `augment.csv` + 本地化资产 | 31 条启用祝福及原作文本 | 祝福池严格取启用行,展示文案按键值格式化 |
|
||||
| `weapondrop.csv` + `weaponstatus.csv` + 原生生成函数 | 40 件装备、四部位主属性、动态品质/词条 | 装备本体与品质/等级/词条分离抽取 |
|
||||
| `ingameshoplist.csv` + 关联表 | 96 条商品、价格和购买上限 | 以商品行作为唯一配置源,不自行拼价 |
|
||||
| `gameconfig.shopRerollCost=3,2` + `0x54E1FD4` | 刷新成本为线性公式 | 每次进店重置付费计数;免费刷新优先 |
|
||||
| `BuyItem @ 0x54DE518` | 购买只递减剩余次数 | 普通重复购买不涨价 |
|
||||
| `SetSurcharge @ 0x54DE0A4` | 黑市使用独立百分比加价 | 不把黑市加价误写成重复购买涨价 |
|
||||
|
||||
## 6. 复现、限制与来源
|
||||
|
||||
- 结构化抽取脚本:`analysis/catalog-reverse/scripts/extract_catalogs.py`
|
||||
- 原生刷新公式:`IngameShopView` 方法 `0x06002CD2 @ 0x54E1FD4`,核心 `madd` 位于约 `0x54E2188`。
|
||||
- 刷新动作:`0x06002CD3 @ 0x54E2250`;免费次数优先分支约 `0x54E22F0–0x54E23A4`。
|
||||
- 购买计数:`IngameShopItemSlot.BuyItem @ 0x54DE518`,递减与售罄约 `0x54DE724–0x54DE74C`。
|
||||
- 黑市加价:`IngameShopItemSlot.SetSurcharge @ 0x54DE0A4`。
|
||||
- 未使用互联网补全:本地逆向数据已足够回答清单、刷新、价格和购买增长问题;唯一未闭合的黑市加价百分比明确保留为未知,没有以网络二手资料替代源码证据。
|
||||
@@ -0,0 +1,208 @@
|
||||
# HEROLL 2.0.1 局内装备等级、词条、星级与 Boss 中途掉落逆向报告
|
||||
|
||||
> 范围:仅 HEROLL 2.0.1 Unity IL2CPP 版本;仅用于本机内部玩法验证。
|
||||
> 标签:`[源码确认]` 可直接还原;`[实机观察]` 来自用户/录像;`[验证版新增]` 是原作证据不足时的明确设计选择。
|
||||
> 样本:`libil2cpp.runtime-decrypted.so`,SHA-256 `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA`。
|
||||
|
||||
## 结论摘要
|
||||
|
||||
| 问题 | 可实施结论 | 证据等级 |
|
||||
|---|---|---|
|
||||
| 装备等级 | `GearLevel = max(1, Floor + Δ)`;普通主线 `Δ={0,1,2}`,权重 `90:5:1`,即 `93.75% / 5.2083% / 1.0417%` | `[源码确认]` |
|
||||
| 六品质影响 | 品质不使用全局倍率直接放大局内装备;它决定副词条数、星级分配,且仅 Myth 主属性多 1 个有效等级 | `[源码确认]` |
|
||||
| 部位词条池 | 四个局内部位共用同一组 9 个副词条,抽取不重复;没有发现部位过滤 | `[源码确认]` |
|
||||
| 星级维度 | 星级是每条 `Status.plusLevel`,不是装备等级、品质或另一套 Affix Tier;每星把该词条的有效等级提高 1 | `[源码确认]` |
|
||||
| Boss 中途掉装 | 已观察存在,但未恢复 `boss_0` 可审计阈值;验证版采用首次向下越过 50% HP 时追加 1 件 | `[实机观察] + [验证版新增]` |
|
||||
|
||||
## 1. 装备等级公式
|
||||
|
||||
配置 `gameconfig.csv` 给出:
|
||||
|
||||
```text
|
||||
LoopRatio = 90, 5, 1
|
||||
```
|
||||
|
||||
`BattleController.GetWeaponLoop @ 0x55BE240` 构造三项权重并抽取偏移;函数尾部把当前零基圈数加一,再加抽到的偏移。因此普通主线可写为:
|
||||
|
||||
\[
|
||||
Floor = LoopIndex + 1
|
||||
\]
|
||||
|
||||
\[
|
||||
GearLevel = \max(1, Floor + \Delta)
|
||||
\]
|
||||
|
||||
| Δ | 权重 | 归一化概率 | Floor 10 示例 |
|
||||
|---:|---:|---:|---:|
|
||||
| 0 | 90 | 93.7500% | Lv.10 |
|
||||
| 1 | 5 | 5.2083% | Lv.11 |
|
||||
| 2 | 1 | 1.0417% | Lv.12 |
|
||||
|
||||
这与实机观察“Floor 10 不低于 Lv.10、最高 Lv.12”一致。原生函数还含模式/研究相关的下限或上限分支;本地玩法验证版没有局外研究,故应使用上表作为普通主线基线,不引入元成长修正。
|
||||
|
||||
## 2. 品质、主属性和副词条
|
||||
|
||||
### 2.1 六品质
|
||||
|
||||
| enum | 品质 | 基础权重 | 基础概率 | 副词条数 | 主属性特殊规则 |
|
||||
|---:|---|---:|---:|---:|---|
|
||||
| 0 | Normal / 灰 | 210 | 68.4039% | 0 | 无 |
|
||||
| 1 | Rare / 绿 | 60 | 19.5440% | 1 | 无 |
|
||||
| 2 | Epic / 蓝 | 28 | 9.1205% | 2 | 无 |
|
||||
| 3 | Legend / 金 | 4 | 1.3029% | 3 | 无 |
|
||||
| 4 | Myth / 彩 | 1 | 0.3257% | 3 | 主属性有效等级 +1 |
|
||||
| 5 | Arcane / 红 | 4 | 1.3029% | 3 | 无;一条副词条带 Arcane 隐藏/观察标记 |
|
||||
|
||||
这些百分比是无其他修正时的基础品质分布。`GrageMultiplier=1,2,4,8,16` 虽存在于 `gameconfig.csv`,但没有进入本报告追踪到的局内 `GetMonoWeaponData → GetStatus` 数值路径,不能把它当作局内品质乘区。
|
||||
|
||||
### 2.2 四部位主属性
|
||||
|
||||
| 局内部位 | 固定主属性 |
|
||||
|---|---|
|
||||
| Ingame_Weapon | ATTACK_POWER |
|
||||
| Ingame_Ring | HEALTH |
|
||||
| Ingame_Gauntlet | AIM |
|
||||
| Ingame_Boots | DEFENSE |
|
||||
|
||||
先抽 40 件装备之一,再独立生成品质、等级和属性;装备 ID 与品质不是预组合的独立掉落项。
|
||||
|
||||
### 2.3 属性值公式
|
||||
|
||||
对 `weaponstatus.csv` 中任意属性 `s`:
|
||||
|
||||
\[
|
||||
EffectiveLevel_{main}=GearLevel-1+MythBonus+ResearchBonus
|
||||
\]
|
||||
|
||||
其中 `MythBonus=1` 仅品质 enum 4 生效;验证版 `ResearchBonus=0`。
|
||||
|
||||
\[
|
||||
EffectiveLevel_{affix}=GearLevel+Star-1
|
||||
\]
|
||||
|
||||
\[
|
||||
MinValue=BaseMin_s+PlusValue_s\times EffectiveLevel
|
||||
\]
|
||||
|
||||
\[
|
||||
MaxValue=BaseMax_s+PlusValue_s\times EffectiveLevel
|
||||
\]
|
||||
|
||||
随后在 `[MinValue, MaxValue]` 内取随机值。`isFloat=true` 保留 1 位小数,`isFloat=false` 取整数。源码内部生成两个有间距的候选值,当前调用链采用第一个;要做逐 seed 精确复刻时,必须保持原随机流调用次数。
|
||||
|
||||
## 3. 四部位允许的随机副词条
|
||||
|
||||
原生生成器显式建立枚举集合 `{6,5,7,8,9,10,11,12,13}`,对应下列 9 项;四个部位均使用此池,单件装备内无重复。
|
||||
|
||||
| 副词条 | Base 范围 | 每星 Plus | 百分比 | 小数 |
|
||||
|---|---:|---:|---|---|
|
||||
| EVASION | 14–20 | 7 | 否 | 否 |
|
||||
| REGEN_PER_SECOND | 1–2 | 2.4 | 否 | 是 |
|
||||
| TOTAL_DAMAGE | 1–2 | 1 | 否 | 是 |
|
||||
| TRUE_DAMAGE | 1–2.5 | 1.7 | 否 | 否 |
|
||||
| KILL_HEAL | 6–9 | 2.5 | 否 | 否 |
|
||||
| COUNTER_ATTACK | 7–9 | 1.5 | 是 | 否 |
|
||||
| ATTACK_SPEED | 7–9 | 1.4 | 是 | 否 |
|
||||
| CRITICAL_RATE | 10–12 | 1.5 | 是 | 否 |
|
||||
| LIFE_STEAL | 4.5–7.5 | 1.5 | 是 | 否 |
|
||||
|
||||
注意:`HEALTH` 不是随机副词条,而是 Ring 固定主属性;`ATTACK_POWER/AIM/DEFENSE` 同理属于各自部位主属性。
|
||||
|
||||
## 4. 星级的真实含义及品质分配
|
||||
|
||||
运行时数据没有独立 `AffixTier` 字段。每条属性使用 `Status.plusLevel` 表达星级;因此实现中不要再叠加一套隐藏 T1/T2/T3。
|
||||
|
||||
| 品质 | 生成结果(副词条星级) | 精确规则 |
|
||||
|---|---|---|
|
||||
| Normal | 无 | 0 条副词条 |
|
||||
| Rare | `[1]` | 1 条,初始 1 星 |
|
||||
| Epic | `[1,1]` | 2 条,各 1 星 |
|
||||
| Legend | `[2,1,1]` | 3 条各 1 星,再随机给其中一条 +1 |
|
||||
| Myth | 见下表 | 3 条各 1 星,再独立随机分配 3 个星点,可重复命中 |
|
||||
| Arcane | `[4,1,1]` | 3 条各 1 星;随机选一条集中获得 +3,并设置 Arcane 标记 |
|
||||
|
||||
Myth 的排序后分布:
|
||||
|
||||
| 星级组合 | 概率 |
|
||||
|---|---:|
|
||||
| `[4,1,1]` | 1/9 = 11.1111% |
|
||||
| `[3,2,1]` | 2/3 = 66.6667% |
|
||||
| `[2,2,2]` | 2/9 = 22.2222% |
|
||||
|
||||
原生额外星点循环调用 `Common.Roll(1.0)`;该条件恒真,所以 Legend 精确增加 1 点,Myth/Arcane 精确增加 3 点,不是“最多增加”。Arcane 被选中的 4 星词条还会设置 `isHideStatusIndex=true`、`arcaneWatchIndex=0`;本报告不把尚未闭环的 UI 揭示时序扩写成规则。
|
||||
|
||||
## 5. Boss HP 中途追加装备
|
||||
|
||||
用户实机观察表明 Boss 在战斗中 HP 降低到某阶段时会追加 1 件装备。当前逆向可以确认多个 `SpawnRandomWeapon` 调用入口,也能确认 `GoldCarriageEnemy` 有独立阈值奖励结构,但没有恢复到足以证明 `boss_0` HP 百分比的专属调用链。因此不能把任意百分比标成原作事实。
|
||||
|
||||
玩法验证版采用以下覆盖规则:
|
||||
|
||||
```text
|
||||
[验证版新增] boss_0 首次由 HP > 50% 向下越过 HP <= 50% 时,追加生成 1 件装备。
|
||||
midBossGearDropped 为单场战斗幂等标记;复活不重置。
|
||||
若一击同时越过 50% 并致死,先产生中途装备,再执行死亡结算。
|
||||
Boss 死亡掉落与该追加掉落是两个独立来源。
|
||||
```
|
||||
|
||||
这个选择可见、易测、不会伪装成原作恢复结论。若未来动态 Hook 得到真实阈值,只替换配置,不改变事务结构。
|
||||
|
||||
## 生成流程图
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[当前 Floor] --> B[GetWeaponLoop]
|
||||
B --> C{Δ 加权抽取 90:5:1}
|
||||
C --> D[GearLevel = Floor + Δ]
|
||||
D --> E[抽 40 件装备之一]
|
||||
E --> F[抽六品质]
|
||||
F --> G[部位固定主属性]
|
||||
F --> H[按品质确定副词条数]
|
||||
H --> I[四部位共享 9 词条池\n单件不重复]
|
||||
I --> J[按品质分配 plusLevel 星级]
|
||||
G --> K[GetStatus 数值区间]
|
||||
J --> K
|
||||
K --> L[按 isFloat 整数或 1 位小数]
|
||||
```
|
||||
|
||||
## Evidence → Finding → Path
|
||||
|
||||
### Findings
|
||||
|
||||
- `F-DROP-001`(validated,高):普通主线装备等级为 `Floor + Weighted(0,1,2; 90,5,1)`。`evidence_ids: [E-DROP-LEVEL-001]`
|
||||
- `F-DROP-002`(validated,高):六品质通过副词条数量、星级分配和 Myth 主属性 +1 有效等级影响属性,不在此路径使用全局品质倍率。`evidence_ids: [E-DROP-AFFIX-001]`
|
||||
- `F-DROP-003`(validated,高):四局内部位共用 9 项无重复副词条池。`evidence_ids: [E-DROP-AFFIX-001]`
|
||||
- `F-DROP-004`(validated,高):星级等于每条 `Status.plusLevel`,每星提升该词条一个有效等级;没有独立 Affix Tier。`evidence_ids: [E-DROP-AFFIX-001]`
|
||||
- `F-DROP-005`(partial,中):Boss 中途追加装备被实机观察支持,但 `boss_0` 精确 HP 阈值尚未由静态调用链闭环;50% 是验证版新增。`evidence_ids: [E-DROP-BOSS-001]`
|
||||
|
||||
### Path
|
||||
|
||||
- `P-DROP-001`
|
||||
- `path_type: callflow`
|
||||
- steps: `gameconfig.LoopRatio → BattleController.GetWeaponLoop → GetMonoWeaponData → status generator → GetStatus → GetRandomValues`
|
||||
- `evidence_ids: [E-DROP-LEVEL-001, E-DROP-AFFIX-001]`
|
||||
|
||||
## 复现入口
|
||||
|
||||
```powershell
|
||||
rg -n "LoopRatio|GrageMultiplier" HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/gameconfig.csv
|
||||
rg -n "ATTACK_POWER|EVASION|LIFE_STEAL" HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/weaponstatus.csv
|
||||
radare2 -q -c "s 0x55BE240; pd 420" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
radare2 -q -c "s 0x55BDCC0; pd 1450" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
radare2 -q -c "s 0x55C0840; pd 360" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
radare2 -q -c "s 0x55C0D70; pd 320" work/heroll-stage-2-5/libil2cpp.runtime-decrypted.so
|
||||
```
|
||||
|
||||
## 互联网交叉检索
|
||||
|
||||
公开资料没有给出上述局内精确权重或公式。Google Play 只描述掷骰、战斗和装备循环;社区 Wiki 的 Equipment 页面主要是局外持久装备系统,不能与本报告的局内 `MonoWeaponData/Status.plusLevel` 混用。社区讨论“等级通常比稀有度更重要”仅与本报告的线性等级增长方向相容,不构成公式证据。
|
||||
|
||||
- Google Play:https://play.google.com/store/apps/details?hl=en_SG&id=com.percent.aos.rollinghero
|
||||
- Heroll Wiki Equipment:https://heroll.fandom.com/wiki/Equipment
|
||||
- Reddit 社区讨论:https://www.reddit.com/r/heroll/comments/1l1x8qx
|
||||
|
||||
## 限制
|
||||
|
||||
- Arcane 词条的完整 UI 揭示/观察生命周期尚未闭环,本报告只保留已确认字段语义。
|
||||
- `boss_0` 的原作中途掉落阈值尚未闭环;50% 仅为验证版配置。
|
||||
- 模式和局外研究可能给 `GetWeaponLoop/GetStatus` 增加修正;本报告的实现目标是无局外成长的主线玩法验证版。
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
# HEROLL 2.0.1 掉落规则逆向报告
|
||||
|
||||
> 样本:`com.percent.aos.rollinghero`,versionName `2.0.1`,versionCode `113296145`
|
||||
> 原始 XAPK SHA-256:`439D532704AFCCDBEBA8C01AF7869552387CDE31651963D0A45541F252B94E2F`
|
||||
> 结论等级:**确认**=配置或 Native 正文直接证明;**高置信推导**=多项独立证据闭合;**未知**=不得用于原作还原。
|
||||
|
||||
## 1. 核心结论
|
||||
|
||||
HEROLL 的局内装备生成不是一次抽完,而是至少拆成四步:
|
||||
|
||||
1. 从 `WeaponDrop` 的 40 条局内装备中随机选装备身份。
|
||||
2. 以六档相对权重生成品质,并叠加 Joker/局内效果及圈数相关修正。
|
||||
3. 另行生成 `loopGrade` 与随机属性。
|
||||
4. 检查封印等后处理,生成装备槽;槽满时先进入回收路径。
|
||||
|
||||
基础品质权重为:
|
||||
|
||||
`NORMAL : RARE : EPIC : LEGEND : MYTH : ARCANE = 210 : 60 : 28 : 4 : 1 : 4`
|
||||
|
||||
这些数值是**相对权重,不是百分比**。未激活任何动态修正时,总权重为 307,基线概率如下:
|
||||
|
||||
| 品质 | 权重 | 基线概率 |
|
||||
|---|---:|---:|
|
||||
| NORMAL | 210 | 68.4039% |
|
||||
| RARE | 60 | 19.5440% |
|
||||
| EPIC | 28 | 9.1205% |
|
||||
| LEGEND | 4 | 1.3029% |
|
||||
| MYTH | 1 | 0.3257% |
|
||||
| ARCANE | 4 | 1.3029% |
|
||||
|
||||
`ARCANE` 的基础权重确实高于 `MYTH`;这是样本原值,不能为了“看起来合理”而改写。
|
||||
|
||||
## 2. Native 生成链
|
||||
|
||||
### 2.1 装备身份
|
||||
|
||||
`BattleController.GetMonoWeaponData`(VA `0x55BDCC0`)读取 `WeaponDrop` 表的总行数,以随机整数索引取一条,再写入 `weaponStringId`。
|
||||
|
||||
`weapondrop.csv` 正好有 40 条数据:
|
||||
|
||||
| 槽位类型 | 数量 | 基础身份概率 |
|
||||
|---|---:|---:|
|
||||
| Ingame_Weapon | 10 | 25%(单件 2.5%) |
|
||||
| Ingame_Ring | 10 | 25%(单件 2.5%) |
|
||||
| Ingame_Gauntlet | 10 | 25%(单件 2.5%) |
|
||||
| Ingame_Boots | 10 | 25%(单件 2.5%) |
|
||||
|
||||
该等概率结论仅适用于走基础 `GetMonoWeaponData` 随机重载的奖励。`SpawnFixWeapon`、`SpawnTypeWeapon` 及其他带筛选参数的入口可以固定身份或限制类型,不能套用 2.5%。
|
||||
|
||||
### 2.2 品质
|
||||
|
||||
`BattleController.GetEWeaponGrade`(VA `0x55BDE8C`)执行以下流程:
|
||||
|
||||
```text
|
||||
weights = [210, 60, 28, 4, 1, 4]
|
||||
for gradeIndex in 0..5:
|
||||
weights[gradeIndex] *= JokerEffectController.GetWeaponProbMultiplier(gradeIndex)
|
||||
|
||||
apply_loop_or_grade_related_modifiers(weights)
|
||||
|
||||
if excludeNormal:
|
||||
weights[0] = 0
|
||||
|
||||
gradeIndex = Utils.GetRatioPercent(weights)
|
||||
```
|
||||
|
||||
`Utils.GetRatioPercent` 是加权选择器,因此最终概率为 `修正后本档权重 / 修正后总权重`。
|
||||
|
||||
当调用入口设置 `excludeNormal=true` 且没有其他修正时,归一化结果为:RARE 61.8557%、EPIC 28.8660%、LEGEND 4.1237%、MYTH 1.0309%、ARCANE 4.1237%。这不是普通掉落率,只是该特殊分支的数学基线。
|
||||
|
||||
### 2.3 `loopGrade`、属性与后处理
|
||||
|
||||
`BattleController.GetWeaponLoop`(VA `0x55BE240`)另建一个三项权重列表,经 `Utils.GetRatioPercent` 抽取并叠加圈数/品质相关值。它不是六档品质抽取。
|
||||
|
||||
随后 `GetMonoWeaponData` 继续生成状态值、检查封印并写入 `MonoWeaponData`。随机装备协程的已闭合调用链为:
|
||||
|
||||
```text
|
||||
CheckFullSlotRecycleFirstExtra
|
||||
-> GetMonoWeaponData
|
||||
-> MonoWeaponSlot.Spawn
|
||||
-> AddWeaponRewardForEventLog
|
||||
-> HandleJokerWeaponSpawnPostProcess
|
||||
```
|
||||
|
||||
因此以下行为已确认:
|
||||
|
||||
- 满槽会在生成前进入回收处理。
|
||||
- Joker 不只修正品质权重,装备生成后还有独立后处理。
|
||||
- `GetWeaponDropDestroyChance` 表明某些 Joker 效果可令掉落销毁;具体活动值取决于当前效果状态。
|
||||
|
||||
## 3. 掉落“出现机会”与“掉落品质”必须分开
|
||||
|
||||
`ingameWeaponDropRatio` 只证明**已经进入装备生成时的品质分布**,不等于“每只敌人有多少概率掉装备”。
|
||||
|
||||
当前静态证据能确认多个系统会调用随机、固定或类型限定装备生成接口,包括战斗相关奖励、宝箱/事件、碎片交互、小游戏和特殊祝福效果。但 APK 中没有发现一个可直接解释为“所有普通敌人的统一装备掉率”的全局配置。
|
||||
|
||||
两个启用的祝福配置会改变装备出现机会:
|
||||
|
||||
| ID | StringId | 关键配置 | 可确认内容 | 尚未确认内容 |
|
||||
|---:|---|---|---|---|
|
||||
| 124 | KillInTimeGetGear | `timeValue=2.5` | 祝福启用,名称指向限时击杀装备奖励 | 2.5 的精确单位、触发对象及是否必掉 |
|
||||
| 132 | KillForHeroGear | `Value=10` | 祝福启用,名称指向击杀换高品质装备 | “10”的计数/概率语义及品质下限 |
|
||||
|
||||
仅凭 StringId 不足以把这两项写成确定公式;需要继续闭合祝福消费者 Native 正文或做指定种子的动态采样。
|
||||
|
||||
## 4. 局内非装备奖励表
|
||||
|
||||
`ingamereward.csv` 配置了以下节点:
|
||||
|
||||
| 时机 | 奖励 | 配置 |
|
||||
|---|---|---|
|
||||
| `killStrong` | 钻石(item 101) | 数量 0、概率 0,等同关闭 |
|
||||
| `loopClear` | 钻石(item 101) | 数量 1、概率 80 |
|
||||
| `loopEndTileMove` | 金币(item 100) | 基数 10、概率 100、随目标关卡乘 `stageMult` |
|
||||
| `loopClear` | 金币(item 100) | 基数 330、概率 100、随目标关卡乘 `stageMult` |
|
||||
| `loopClear` | 四槽卷轴(119–122) | 各数量 1、配置概率数组均为 20 |
|
||||
| `loopClear` | 四槽强化材料(126–129) | 各数量 1、配置概率数组均为 20 |
|
||||
| `gameEnd` | 鱼饼(item 111) | 数量 1、概率 100 |
|
||||
|
||||
金币 `stageMult`:
|
||||
|
||||
| 目标关卡索引 | stageMult |
|
||||
|---|---:|
|
||||
| -1–16 | 0.30 |
|
||||
| 17–21 | 0.29 |
|
||||
| 22–25 | 0.28 |
|
||||
| 26–30 | 0.27 |
|
||||
| 31–33 | 0.26 |
|
||||
| 34–37 | 0.25 |
|
||||
| 38–44 | 0.24 |
|
||||
| 45–99 | 0.23 |
|
||||
|
||||
表中 `itemCount × stageMult` 的小数取整规则尚未由消费者正文证明,不应自行选择 floor、round 或 ceil。四项 `20` 是配置事实,但“各自独立判定”还是“先选一项再判空”也需 Native 消费者闭合。
|
||||
|
||||
## 5. 抓娃娃掉落配置
|
||||
|
||||
`clawcraneminigame.csv` 说明场内出现 20 个胶囊,配置项包括:
|
||||
|
||||
| 奖励 | 普通 Prob | goodProb |
|
||||
|---|---:|---:|
|
||||
| 空 | 40 | 0 |
|
||||
| 点数 | 70 | 0 |
|
||||
| 药水 | 14 | 0 |
|
||||
| NORMAL 装备 | 40 | 0 |
|
||||
| RARE 装备 | 0 | 0 |
|
||||
| EPIC 装备 | 0 | 0 |
|
||||
| LEGEND 装备 | 0 | 1 |
|
||||
| 祝福 | 0 | 0 |
|
||||
| 药水祝福 | 0 | 0 |
|
||||
|
||||
这些是胶囊生成器的输入权重/概率字段,不应直接归一化为单次抓取概率;胶囊层级、20 个场内对象、好胶囊分支和物理抓取成功率都会影响最终获得率。
|
||||
|
||||
## 6. 保底与重复保护
|
||||
|
||||
结论:**未发现局内 `BattleController` 装备品质抽取的保底计数器或重复品排除逻辑。**
|
||||
|
||||
搜索到的保底实现属于其他系统:
|
||||
|
||||
- `gachaceildata.csv`:局外抽卡保底。
|
||||
- `IdleDungeonController.RollGuaranteedIdleDungeonEquipmentGrade`:挂机地牢装备保底。
|
||||
- `DestinyStatPage.RollGuaranteedHighGrade`:命运属性重掷保底。
|
||||
|
||||
它们不能迁移为普通局内装备掉落规则。公开社区所说的“20 抽保底”和 S 级装备抽取率也属于 Mimic Hunt/局外抽取,不是局内棋盘掉落。
|
||||
|
||||
## 7. 仍然未知的精确项
|
||||
|
||||
以下项目不应冒充已经还原:
|
||||
|
||||
1. 普通敌人自然产生一次装备奖励的基础触发率。
|
||||
2. `GetEWeaponGrade` 中圈数对 EPIC/LEGEND/MYTH/ARCANE 的完整倍率公式。
|
||||
3. 当前运行中各 Joker 的实际倍率、掉落销毁率及远程配置覆盖值。
|
||||
4. `GetWeaponLoop` 三项权重的语义名称及最终 `loopGrade` 分布。
|
||||
5. 卷轴/强化材料概率数组的精确判定顺序。
|
||||
6. 小数奖励数量的取整方式。
|
||||
|
||||
要闭合 1–4,最小动态采样方案是固定 seed,分别在无祝福、获取 ID 124、获取 ID 132、不同圈数及指定 Joker 状态下,Hook `GetEWeaponGrade` 的入参、六项修正后权重和返回值,并记录每个 `SpawnRandomWeapon` 的调用栈。互联网资料无法替代这一步。
|
||||
|
||||
## 8. 证据索引
|
||||
|
||||
| 证据 | SHA-256 | 用途 |
|
||||
|---|---|---|
|
||||
| `gameconfig.csv` | `A57510DEDE13DAF1A597DE1EE73E47B0ABD830D96719DAD24B2CA7370E8DFE3D` | 六档基础权重 |
|
||||
| `weapondrop.csv` | `AF8C97D022A83C1FF898D33FC541F157CAD1DC6C5732FF57D61A502E82914809` | 40 条局内装备身份 |
|
||||
| `ingamereward.csv` | `BCD0E607C0F31A378960F3CD3BA25518A3F3D72D377EEDE11064A276849A9A74` | 圈结算与关卡结束奖励 |
|
||||
| `augment.csv` | `E0B14AF4709E3F0D548973E124F679EF091589D7C99B0E35DE78C628A73D032A` | 装备掉落相关祝福 |
|
||||
| `clawcraneminigame.csv` | `AE52FA502303678DE55D910BF07CD222C29A6995D0A4D96A785E84C660035015` | 抓娃娃胶囊配置 |
|
||||
| `assembly-csharp.json` | `BA6D3F4BD91B0D3977EB1229AB46FE563118CC55793346796F93816BA7FEF526` | IL2CPP 类型、字段、方法映射 |
|
||||
| `libil2cpp.runtime-decrypted.so` | `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA` | Native 规则正文 |
|
||||
| `battlecontroller-drop-code.bin` | `DC28F8583A8AA60C2C3ED7CED8E5B9A60EDBF4A10E82370B32F2C169424FC0ED` | 原 SO 的只读函数区切片,便于 ARM64 复核 |
|
||||
|
||||
## 9. 互联网交叉检索结论
|
||||
|
||||
- [Heroll Wiki 的 Equipment 页面](https://heroll.fandom.com/wiki/Equipment)描述的是局外装备、Mimic Hunt、合成与升级,没有公开局内 `EMonoWeaponGrade` 的生成算法。
|
||||
- [Heroll 社区的 S Legendary 讨论](https://www.reddit.com/r/heroll/comments/1mtb15a/the_thing_about_s_legendary_equipment/)出现了玩家声称的 0.5964% 以及评论中的“20 抽保底”,上下文明确是局外抽取/合成,不可用于本报告的局内掉落率。
|
||||
|
||||
因此,互联网没有补上 Native 中尚缺的圈数倍率;本报告以 APK 2.0.1 本地证据为准。
|
||||
@@ -0,0 +1,12 @@
|
||||
# 07-奖励与掉落
|
||||
|
||||
死亡掉落、战斗奖励、Floor奖励、Boss中途装备与事件奖励。
|
||||
|
||||
## 文件
|
||||
|
||||
- [2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md](./2026-08-31_%E9%80%86%E5%90%91-HEROLL%E8%A3%85%E5%A4%87%E7%AD%89%E7%BA%A7%E8%AF%8D%E6%9D%A1%E6%98%9F%E7%BA%A7%E4%B8%8EBoss%E6%8E%89%E8%90%BD-report.md) — report;来源:`analysis/drop-rules/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md`
|
||||
- [event-reward-tables.csv](./event-reward-tables.csv) — table;来源:`analysis/tile-event-rules/tables/event-reward-tables.csv`
|
||||
- [gear-rarity-affix-rules.csv](./gear-rarity-affix-rules.csv) — table;来源:`analysis/drop-rules/gear-rarity-affix-rules.csv`
|
||||
- [HEROLL_2.0.1_DROP_RULES_REPORT.md](./HEROLL_2.0.1_DROP_RULES_REPORT.md) — report;来源:`analysis/drop-rules/HEROLL_2.0.1_DROP_RULES_REPORT.md`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,22 @@
|
||||
event,key,condition,reward,amount_or_weight,source
|
||||
Lucky Scratch,first_prize,preselected weighted result,point,30 at weight 10,newtile.csv values 30|10|1|10|50|40
|
||||
Lucky Scratch,second_prize,preselected weighted result,point,10 at weight 50,newtile.csv
|
||||
Lucky Scratch,third_prize,preselected weighted result,point,1 at weight 40,newtile.csv
|
||||
Claw Machine,guaranteed_good,one per layout,Legendary gear,1,newtile.csv plus clawcraneminigame.csv
|
||||
Claw Machine,normal_empty,normal capsule sample,none,weight 40,clawcraneminigame.csv
|
||||
Claw Machine,normal_point,normal capsule sample,point 1,weight 70,clawcraneminigame.csv
|
||||
Claw Machine,normal_potion,normal capsule sample,potion 1,weight 14,clawcraneminigame.csv
|
||||
Claw Machine,normal_gear,normal capsule sample,Normal gear 1,weight 40,clawcraneminigame.csv
|
||||
Dicereel,pair_face_1,exactly one pair,point,5,dicemachine.csv id0
|
||||
Dicereel,triple_face_1,triple,point,20,dicemachine.csv id6
|
||||
Dicereel,pair_face_2,exactly one pair,Normal gear,1,dicemachine.csv id1
|
||||
Dicereel,triple_face_2,triple,Rare gear,1,dicemachine.csv id7
|
||||
Dicereel,pair_face_3,exactly one pair,free spin,1,dicemachine.csv id2
|
||||
Dicereel,triple_face_3,triple,free spin,2,dicemachine.csv id8
|
||||
Dicereel,pair_face_4,exactly one pair,blessing,1,dicemachine.csv id3
|
||||
Dicereel,triple_face_4,triple,blessing,2,dicemachine.csv id9
|
||||
Dicereel,pair_face_5,exactly one pair,Good Tile,1,dicemachine.csv id4
|
||||
Dicereel,triple_face_5,triple,Good Tile,3,dicemachine.csv id10
|
||||
Dicereel,pair_face_6,exactly one pair,potion,1,dicemachine.csv id5
|
||||
Dicereel,triple_face_6,triple,potion,3,dicemachine.csv id11
|
||||
Dicereel,no_match,three distinct faces,none,0,dicemachine.csv id12
|
||||
|
@@ -0,0 +1,8 @@
|
||||
grade_enum,rarity_cn,rarity_en,base_weight,base_probability,affix_count,sorted_star_pattern,main_effect,source_tag
|
||||
0,灰,Normal,210,0.6840390879,0,none,none,源码确认
|
||||
1,绿,Rare,60,0.1954397394,1,"1",none,源码确认
|
||||
2,蓝,Epic,28,0.0912052117,2,"1|1",none,源码确认
|
||||
3,金,Legend,4,0.0130293160,3,"2|1|1",none,源码确认
|
||||
4,彩,Myth,1,0.0032573290,3,"4|1|1 OR 3|2|1 OR 2|2|2",main_effective_level_plus_1,源码确认
|
||||
5,红,Arcane,4,0.0130293160,3,"4|1|1",selected_affix_arcane_marked,源码确认
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -0,0 +1,12 @@
|
||||
"order","branch","phase","source_status","mvp_rule","skip_on_final_boss"
|
||||
"0","all","Start entry","source-aligned entry","Cross Start; lock dice and movement; store remainingSteps; finish any already-open equipment, blessing, event-reward, and shop UI before advancing the transaction.","false"
|
||||
"1","shop-eligible","shop judgment and interaction","MVP ordered override","Evaluate the every-3-Floor shop condition; build 3 fixed plus 3 non-duplicate random offers; open the shop and await close. TILE purchases enter purchasedTileQueue and are not installed yet.","false"
|
||||
"2","all","final Floor / Boss judgment","MVP ordered override","Evaluate Default final Floor or DiceGauge 50/50. On success replace all 44 positions with Boss Tile and retain remainingSteps.","false"
|
||||
"3","all","current Floor reward","MVP ordered override","Grant the completed-Floor reward exactly once. This step runs after Boss judgment and before any normal-loop mutation.","false"
|
||||
"4","normal non-final","loop commit and purchased Tile install","MVP ordered override","Increment loopIndex exactly once; install purchasedTileQueue entries in purchase order on legal ordinary small tiles. If the Boss branch was selected, roll back and do not charge uncommitted TILE purchases.","true"
|
||||
"5","normal non-final","Good injection","source call structure retained","Await AddRandomGoodTiles(loopIndex+2). The argument is attempt count, not guaranteed successful placement count.","true"
|
||||
"6","normal non-final","Enemy injection","source call structure retained","Await AddRandomEnemyTile(enemyTilesPerLoop,false); MVP default enemyTilesPerLoop=3 attempts.","true"
|
||||
"7","all surviving","spring heal","source relative position intentionally overridden","Heal 30% max HP after reward and normal refresh; clamp to max HP.","false"
|
||||
"8","all surviving","transaction completion","source-aligned completion","Restore camera/UI; write a safe checkpoint; unlock movement.","false"
|
||||
"9","normal or converted Boss board with remainingSteps","movement resume","MVP edge rule","Continue clockwise using remainingSteps. Only the new final landing tile resolves. On a Boss board, that landing starts the final Boss battle.","false"
|
||||
"10","converted Boss board without remainingSteps","next-roll Boss entry","MVP edge rule","Do not treat the standing position as a new landing. Require one more Roll; the next completed Boss-Tile landing starts the final Boss battle.","false"
|
||||
|
@@ -0,0 +1,62 @@
|
||||
"domain","id","string_id","subtype","source_enabled","mvp_enabled","scope","min_stage","min_loop","gate_override","source"
|
||||
"Tile","100","Empty","Empty","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","101","NormalEnemy_1","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","102","NormalEnemy_2","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","103","NormalEnemy_3","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","104","NormalEnemy_4","NormalEnemy","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","105","BossAttackStrongEnemy","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","106","BossAttackBerserk1","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","110","BossAttackEvolve1","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","111","BossAttackEvolve2","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","112","BossAttackEvolve3","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","113","BossAttackEvolve4","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","114","BossAttackInfected","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","115","BossAttackInfectedHost3","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","116","BossAttackInfectedHost2","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","117","BossAttackInfectedHost1","BossAttack","true","true","DiceGauge pressure extension","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","118","MiniBoss","MiniBoss","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","119","Boss","Boss","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","124","AugmentRandom","Augment","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","125","CornerKillOneLineEnemy","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","127","CornerRace","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","128","CornerOneLineChest","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","129","CornerDiceBuilding","Corner","true","true","MVP active Corner","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","131","CornerBlackMarket","Corner","true","true","MVP active Corner","0","3","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","132","Start","Start","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","133","StartShop","Start","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","134","BadEventJail","BadEvent","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","135","BadEventPlusOneLineEnemy","BadEvent","true","true","core board","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","137","GoodEventSmithy","GoodEvent","true","true","MVP active Good event","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","141","GoodEventChest","GoodEvent","true","true","MVP active Good event","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","143","GoodEventBlackJack","GoodEvent","true","true","MVP active Good event","0","3","Keep original minLoop=3 for natural generation; debug console may force","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","151","GoodEventClawGrab","GoodEvent","true","true","MVP active Good event","0","0","none","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","164","GoodEventDiceMachine","GoodEvent","true","true","MVP active Good event","0","3","Keep original minLoop=3 for natural generation; debug console may force","newtile.csv + v0.2.8 scope freeze"
|
||||
"Tile","169","GoodEventSpito","GoodEvent","true","true","MVP active Good event","1","3","MVP validation override: original minStage=1,minLoop=3; use minStage=0,minLoop=0 in the Stage 0 validation build","newtile.csv + v0.2.8 scope freeze"
|
||||
"Blessing","100","AttackShield","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","102","CritHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","103","CritDamageUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","108","FirstAttackDMGUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","109","DMGUpAfterSecond","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","110","ASPUpAfterSecond","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","111","DoubleHeal","AUGMENT","true","true","main blessing candidate pool","","","Natural Double consumer confirmed by runtime observation; additive 8% max-HP heal per stack","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","112","LowHPASPUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","113","BattleStartHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","114","LuckyHit","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","115","DiceSumDMGUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","116","DiceSumShield","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","117","KillHPUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","118","ReduceEnemyDEF","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","121","EnemyCountStatUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","122","OddDiceCritUp","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","124","KillInTimeGetGear","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","125","HealAfterSecond","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","126","LightingEverySec","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","132","KillForHeroGear","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","147","KillAllEmeny","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","148","PointSupply","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","149","DicePotionGet","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","150","KillPotionGet","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","151","ShopFreeReroll","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","152","EmptyTripleBuild","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","153","EvaHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
"Blessing","154","BattleEndHeal","AUGMENT","true","true","main blessing candidate pool","","","dependency/unique/stack cap filtering still applies","augment.csv + v0.2.8 scope freeze"
|
||||
|
@@ -0,0 +1,97 @@
|
||||
"offer_id","item_type","item_id","name_zh_cn","price","buy_limit","fixed_key","fixed_sort","source_catalog_loaded","mvp_enabled","pool","reason"
|
||||
"100","TILE","137","铁匠铺","6","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"101","TILE","138","恢復","9","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"102","TILE","139","来点节奏","7","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"103","TILE","140","勇士遗骸","4","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"104","TILE","141","宝箱","5","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"105","TILE","142","抽取","5","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"106","TILE","143","骰子对决","4","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"107","TILE","144","增幅星星","7","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"108","TILE","151","夹娃娃机","7","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"109","TILE","152","黄金马车","7","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"110","TILE","164","惊心骰子","5","1","","","true","true","random slot","Tile event is in the first-version event whitelist"
|
||||
"111","TILE","166","史莱姆神射手","8","1","","","true","false","random slot","Tile event is outside the frozen first-version deck"
|
||||
"112","AUGMENT","100","守护一击","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"113","AUGMENT","102","吸血","14","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"114","AUGMENT","103","攻击弱点","10","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"115","AUGMENT","106","奇蹟骰子","27","1","","","true","false","random slot","Disabled system: revive or burn chain"
|
||||
"116","AUGMENT","108","起始一击","12","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"117","AUGMENT","109","攻击力加速","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"118","AUGMENT","110","攻击速度加速","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"119","AUGMENT","111","恢復骰子","23","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"120","AUGMENT","112","战斗狂","16","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"121","AUGMENT","113","祝福的开始","14","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"122","AUGMENT","114","快速迴避","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"123","AUGMENT","115","幸运骰子","14","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"124","AUGMENT","116","守护骰子","20","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"125","AUGMENT","117","吸收灵魂","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"126","AUGMENT","118","腐蚀一击","16","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"127","AUGMENT","121","多多益善","10","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"128","AUGMENT","122","奇数骰子","13","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"129","AUGMENT","124","掠夺者","19","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"130","AUGMENT","125","顽强生命","18","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"131","AUGMENT","126","呼唤闪电","16","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"132","AUGMENT","132","质重于量","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"133","AUGMENT","147","调整数量","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"134","AUGMENT","148","支援金","10","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"135","AUGMENT","149","补充骰子","17","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"136","AUGMENT","150","掠夺药水","19","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"137","AUGMENT","151","领袖气质","8","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"138","AUGMENT","152","都市计画","11","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"139","AUGMENT","153","刺激","15","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"140","AUGMENT","154","战后休息","24","1","","","true","true","random slot","Blessing is in the first-version blessing whitelist"
|
||||
"141","AUGMENT","156","残火","16","1","","","true","false","random slot","Disabled system: revive or burn chain"
|
||||
"142","AUGMENT","157","点燃","18","1","","","true","false","random slot","Disabled system: revive or burn chain"
|
||||
"143","POTION","100","立即恢復药水","16","1","","","true","true","random slot","Only the healing potion family is retained"
|
||||
"144","POTION","101","持续恢復药水","15","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"145","POTION","103","攻击药水","15","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"146","POTION","104","命中药水","13","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"147","POTION","105","暴击药水","14","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"148","POTION","106","吸血药水","16","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"149","POTION","107","防禦药水","20","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"150","POTION","108","反击药水","19","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"151","POTION","109","迴避药水","13","1","","","true","false","random slot","Functional potion removed by the single-healing-potion MVP decision"
|
||||
"152","STAT","100","攻击力","3","10","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"153","STAT","101","生命值上限","3","10","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"154","STAT","102","命中","5","5","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"155","STAT","103","防禦力","3","10","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"156","STAT","104","迴避","5","5","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"157","STAT","105","每秒恢復","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"158","STAT","106","整体攻击","9","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"159","STAT","107","固定伤害","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"160","STAT","108","击杀后恢復","7","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"161","STAT","109","反击","5","5","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"162","STAT","110","攻击速度","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"163","STAT","111","暴击率","7","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"164","STAT","112","吸血","8","3","","","true","true","random slot","Direct combat stat is implemented"
|
||||
"165","FIXED","","药水持有量Lv.{0}","10","1","potionCount","0","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"166","FIXED","","药水持有量Lv.{0}","15","1","potionCount","1","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"167","FIXED","","药水持有量Lv.{0}","21","1","potionCount","2","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"168","FIXED","","药水持有量Lv.{0}","28","1","potionCount","3","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"169","FIXED","","药水持有量Lv.{0}","36","1","potionCount","4","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"170","FIXED","","药水持有量Lv.{0}","45","1","potionCount","5","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"171","FIXED","","药水持有量Lv.{0}","55","1","potionCount","6","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"172","FIXED","","药水持有量Lv.{0}","66","1","potionCount","7","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"173","FIXED","","药水持有量Lv.{0}","78","1","potionCount","8","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"174","FIXED","","药水恢復量Lv.{0}","7","1","potionHeal","0","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"175","FIXED","","药水恢復量Lv.{0}","11","1","potionHeal","1","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"176","FIXED","","药水恢復量Lv.{0}","15","1","potionHeal","2","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"177","FIXED","","药水恢復量Lv.{0}","20","1","potionHeal","3","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"178","FIXED","","药水恢復量Lv.{0}","25","1","potionHeal","4","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"179","FIXED","","药水恢復量Lv.{0}","30","1","potionHeal","5","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"180","FIXED","","药水恢復量Lv.{0}","35","1","potionHeal","6","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"181","FIXED","","药水恢復量Lv.{0}","40","1","potionHeal","7","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"182","FIXED","","药水恢復量Lv.{0}","45","1","potionHeal","8","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"183","FIXED","","药水恢復量Lv.{0}","50","1","potionHeal","9","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"184","FIXED","","药水恢復量Lv.{0}","55","1","potionHeal","10","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"185","FIXED","","药水恢復量Lv.{0}","60","1","potionHeal","11","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"186","FIXED","","药水恢復量Lv.{0}","65","1","potionHeal","12","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"187","FIXED","","药水恢復量Lv.{0}","70","1","potionHeal","13","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"188","FIXED","","药水恢復量Lv.{0}","75","1","potionHeal","14","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"189","FIXED","","药水恢復量Lv.{0}","80","1","potionHeal","15","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"190","FIXED","","药水恢復量Lv.{0}","85","1","potionHeal","16","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"191","FIXED","","药水恢復量Lv.{0}","90","1","potionHeal","17","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"192","FIXED","","药水恢復量Lv.{0}","95","1","potionHeal","18","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"193","FIXED","","药水恢復量Lv.{0}","100","1","potionHeal","19","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"194","FIXED","","补充药水","5","-1","potionAdd","0","true","true","fixed slot","Original potion count/heal/refill chain is retained"
|
||||
"195","LOTTO","","彩券","5","1","","","true","false","random slot","Lottery event is outside the frozen first-version scope"
|
||||
|
@@ -0,0 +1,27 @@
|
||||
"key","original_status","mvp_default","type","range","rationale","source","label"
|
||||
"enemyTilesPerLoop","serialized field confirmed; original scene value not recovered","3 attempts per normal loop","integer","0..40","keeps the board playable while preserving the real configuration entry","BoardController field + AddNextLoopTiles native call","DEMO default"
|
||||
"blackMarketSurchargePercent","formula confirmed; percentage unknown","50","integer percent","0..300","reproduces the former 1.5x demo while keeping the source formula","Black Market price native path","DEMO default"
|
||||
"bossPressureTargetCountWhenShort","normal target=4; shortage behavior unknown","require exactly 4 eligible distinct non-AUGMENT tiles; if fewer than 4, delay with no partial conversion and keep gauge full","rule","exactly 4","MVP does not downgrade the pressure action","DiceGauge reverse report + v0.2.8 design decision","MVP frozen"
|
||||
"bossPressureResolvedTile","restoration behavior unknown","convert resolved pressure tile to Empty; do not restore overwritten tile","enum","Empty","deterministic and avoids resurrecting consumed rewards","residual risk in stage-floor report","DEMO default"
|
||||
"bossPressureGaugeCycle","source normal path is 0->50->100","enter stage at 50; add 25 per completed player action; at 100 start 4-roll countdown; after pressure action reset to 0","rule","0..100","creates the approved initial 2-action then repeating 4-action pressure cycle","source reverse + v0.2.8 intentional deviation","MVP frozen"
|
||||
"bossPressureCounterUI","exact original presentation unknown","warning icon plus 4/3/2/1 countdown; never replace visible 0/50 progress","UI rule","hidden/off or warning","keeps three state variables distinct","runtime observation + reverse report","DEMO default"
|
||||
"combatDropDisplayCapacity","finite capacity confirmed; exact count unknown","10; when the 11th arrives replace the oldest unhandled drop FIFO with explicit feedback","integer","10","separates four equipped slots from the ten-item drop display","runtime observation + v0.2.8 design decision","MVP frozen"
|
||||
"randomShopDraw","3 random slots confirmed; full weighting/exclusion not closed","equal weight, without replacement, 3 offers","rule","0..3 visible","exclude disabled, sold-out, owned unique and unmet dependency offers","shop metadata/native partial","DEMO default"
|
||||
"shopTileInstallTarget","purchase exists; exact target selection not closed","random legal ordinary small tile; block purchase and do not charge if none","rule","eligible small tiles","atomic transaction and no reward loss","shop catalog + unresolved consumer","DEMO default"
|
||||
"augmentCandidateDraw","31 enabled all prob=10; runtime exclusion order partial","filter first, equal-weight without replacement, show exactly 3; if fewer than 3 treat as configuration error and block resolution","rule","exactly 3 visible","never fill with duplicates; all definitions return to the pool after selection and are filtered again next time","augment.csv + v0.2.8 design decision","MVP frozen"
|
||||
"augmentRerollNoRepeat","exact replacement exclusion unknown","replace all three; avoid the currently displayed IDs where pool permits","rule","once per event if enabled","prevents a no-op reroll","MVP interaction rule","DEMO default"
|
||||
"goodDeckFailedInstallConsumption","draw/deck behavior confirmed; failure consumption edge unknown","consume the drawn metadata attempt; reshuffle only after deck exhaustion","rule","boolean","preserves attempt semantics and deterministic RNG","GetNextMetadata/AddRandomGoodTiles partial","DEMO default"
|
||||
"integerAffixRandom","min/max formula confirmed; endpoint behavior not closed","uniform real draw over inclusive conceptual range, then round half up to integer","RNG rule","rounded integer","uses one explicit rounding policy","equipment reverse residual + v0.2.8 design decision","MVP frozen"
|
||||
"floatAffixRandom","one-decimal precision confirmed; endpoint behavior not closed","uniform real draw over inclusive conceptual range, then round half up to 0.1","RNG rule","rounded to 0.1","matches displayed precision","weaponstatus.csv + v0.2.8 design decision","MVP frozen"
|
||||
"maxHpDecreaseCurrentHp","consumer edge behavior unknown","currentHP=min(currentHP,newMaxHP), no damage/death event","rule","clamp","prevents equipment swap from triggering combat damage hooks","unresolved runtime edge","DEMO default"
|
||||
"attackSpeedChangeTiming","source uses real-time cooldown scheduling","apply to the next cooldown scheduled after the current attack completes; do not retroactively rescale an active attack or cooldown","rule","next cooldown","preserves deterministic scheduling in the source-aligned real-time model","combat native reverse + v0.2.8 decision","source-aligned edge rule"
|
||||
"bossMidFightDropHp","mid-fight drop observed; exact threshold/phase unknown","first crossing to HP <= 50%, once per boss fight","percent","1..99","documented v0.2.7 validation value","runtime observation","DEMO default"
|
||||
"normalEnemyDeathReward","death-time generation path confirmed; probabilities unknown","one weighted result: gear 95, potion 4, points 1","relative weights","95:4:1","stable validation economy","v0.2.7 frozen reward pacing","DEMO default"
|
||||
"eliteEnemyDeathReward","exact elite rule unknown","1 gear plus one extra result from potion:points=5:2","rule","fixed + weighted","stable elite differentiation","v0.2.7 frozen reward pacing","DEMO default"
|
||||
"floorPointReward","original loop rewards use different resources; MVP mapping is not source","10 + 5 * displayedFloor points","integer formula",">=15","closed local-run economy","v0.2.7 design","DEMO default"
|
||||
"originalRewardFloatRounding","stage multiplier rows confirmed; rounding unknown","floor after multiplication","rounding","nonnegative integer","single deterministic policy","ingamereward.csv residual","DEMO default"
|
||||
"finalStartRemainingSteps","boss branch exists; overflow movement edge not fully observed","preserve remainingSteps on boss-floor conversion; if zero require one additional Roll before Boss battle","rule",">=0","implements the approved Boss-board landing semantics","Start branch + v0.2.8 design decision","MVP frozen"
|
||||
"diceBattleTie","tie consumer not fully closed","dealer wins ties","enum","dealer/player/retry","standard house-edge fallback and single-exit state","GoodEventDiceBattle partial","DEMO default"
|
||||
"luckyScratchRevealThreshold","gesture completion threshold not recovered","65% revealed area","percent","50..90","prevents pixel-perfect scratching","GoodEventSpito UI residual","DEMO default"
|
||||
"forgeMaxQuality","80/50/30/10 steps confirmed; Arcane transition not closed","cap at Myth; Arcane cannot be forged","enum","Myth","four transitions from Normal align with four probabilities","Forge config/runtime residual","DEMO default"
|
||||
"housingRewardPerHouse","Housing Support rolls two independent D6 and rewards by actual houses built; exact house-to-point mapping is not recovered","1 spirit stone per successfully built house","integer","1","closes the construction event economy without presenting the value as an original rule","CornerDiceBuilding reverse + v0.2.8 design decision","DEMO default"
|
||||
|
@@ -0,0 +1,29 @@
|
||||
"system","original_rule","evidence","mvp_active_deviation","demo_default","status"
|
||||
"base player stats","ATK20, HP500, AIM1.5, DEF10, EVA1, COUNTER10, ASP100, CRIT10","battleplayerdefaultstat.csv","HP100, DEF5, AIM100%, EVA0%, CRIT5%, ASP multiplier1.0; ATK20 and COUNTER10 retained","frozen values in v0.2.7","intentional deviation"
|
||||
"battle cadence","real-time automatic cooldown/attack-speed system; each living actor schedules independently; interval=100/finalAttackSpeed","BattleController/native combat reverse","none; v0.2.8 adopts the original real-time cooldown scheduler and removes strict alternating turns","no global 0.25-second clamp","source-aligned"
|
||||
"damage and lifesteal rounding","source keeps floating damage through HP subtraction and lifesteal uses ceil(finalDamage*rate/100)","combat native reverse report","none in calculation; UI may round only for display","positive lifesteal result has minimum heal 1","source-aligned"
|
||||
"counterattack","independent >= RandomInt(1,101) check; triggered DamageMeta can miss or crit and uses defense; no lifesteal","combat native reverse report","none in calculation","base counter rate10","source-aligned"
|
||||
"revive","Revive blessing exists and original product also contains revive/ad paths","augment.csv ID106 + native metadata","all revive disabled","run ends at HP<=0","intentional deviation"
|
||||
"potions","9 shop potion offers","ingameshoplist.csv offers143..151","single healing potion only","10% maxHP, base capacity1","intentional deviation"
|
||||
"board lifetime","one persistent 44-position board mutates across loops","BoardController native refresh path","none","4 large + 40 small","source-aligned"
|
||||
"new-run generation","SpawnInitialTiles -> SpawnAllCornerTiles -> AddRandomGoodTiles(8)","InitNewGame native state machine","Good metadata deck is reduced to implemented events","8 attempts, not 8 guaranteed placements","mixed"
|
||||
"Start normal refresh order","source call order differs from the product transaction order","Start MoveNext calls 0x5541AC0, 0x5544C94, 0x554661C, 0x5546828, 0x55472D8","shop interaction -> final Boss judgment -> Floor reward -> non-final loop and purchased Tile commit -> Good -> Enemy -> heal -> resume","30% maxHP heal","intentional transaction-order deviation"
|
||||
"next-loop tile injection","AddRandomGoodTiles(loop+2), then AddRandomEnemyTile(enemyTilesPerLoop,false)","BoardController.AddNextLoopTiles native","none in structure","enemyTilesPerLoop=3 until serialized value is recovered","partial/default"
|
||||
"Good event deck","new-account deck has 8 OutGameTile metadata: 100,103,106,109,112,124,133,136","outgametile.csv/outgametileskill.csv","runtime deck: tile IDs137,141,143,151,164,169 plus fixed AUGMENT124","169 gate overridden only for validation","intentional deviation"
|
||||
"Corner set","8 enabled Corner tile rows:125,126,127,128,129,131,167,175 with gates","newtile.csv","only 125,127,128,129,131","consumed Corner locally refreshes to another legal Corner","intentional deviation + edge default"
|
||||
"building / exterior houses","Housing Support 129 rolls two independent D6; A+B is the base construction-attempt count; actual construction is capped by eligible spaces in the upcoming row; exact reward conversion is unresolved","CornerDiceBuilding runtime path + corner-rules.csv","enable one exterior house slot per ordinary small tile; place without replacement on the next clockwise board side; houses persist independently of underlying tile mutation until final Boss conversion; Urban Planning 152 adds 2 attempts","1 spirit stone per actual house; no eligible slot resolves as zero; final Boss conversion clears all houses","source structure + MVP executable edges"
|
||||
"blessing catalog","31 enabled main-mode blessings, equal base prob weight10","augment.csv + runtime observation for DoubleHeal","28 active; disable IDs106,156,157; show exactly 3 distinct candidates; all definitions return to pool after choice; stackable values add","DoubleHeal adds 8% max-HP healing per acquired copy on Natural Double; Urban Planning 152 is unique and adds 2 construction attempts","intentional scope and stacking rule"
|
||||
"shop catalog","96 offers: TILE12/AUGMENT31/POTION9/STAT13/FIXED30/LOTTO1","ingameshoplist.csv","load all, enable 77 offers in runtime pools","see 03-shop-product-whitelist.csv","intentional scope filter"
|
||||
"shop slots","3 fixed + 3 random","shop native/config reverse","none in count; random slots are equal-weight without replacement, cannot duplicate on one screen, and sold-out items stay excluded for the current visit","next shop activation clears the sold-out visit set; owned stackable blessings may recur","source-aligned + MVP draw edge rules"
|
||||
"shop reroll","price=3+2*k, k starts0; free reroll does not advance k","gameconfig.csv ID119 + native shop reverse","none","no hard cap","source-aligned"
|
||||
"ordinary repeat purchase","price does not automatically rise; buyCount limits stock","ingameshoplist.csv","none","fixed price","source-aligned"
|
||||
"fixed potion upgrades","separate rows encode price ladder, not dynamic markup","offers165..194","mapped onto the single potion","count 10..78, heal 7..100, refill5","source structure + MVP mapping"
|
||||
"black market","base + trunc(base*surchargePercent/100); percent unresolved","CornerBlackMarket native reverse","none in formula","50% surcharge","partial/default"
|
||||
"equipment quality","six weights 210:60:28:4:1:4","weapondrop.csv","none","no pity","source-aligned"
|
||||
"equipment level","Floor/Floor+1/Floor+2 relative weights90:5:1","gameconfig.csv ID100 + native reverse","none","weighted normalized draw","source-aligned"
|
||||
"equipment salvage","exact in-run conversion values not closed","consumer unresolved","quality values1/2/4/8/12/16","fixed per quality","demo economy"
|
||||
"enemy death reward","death-time generation path confirmed; no unified probabilities recovered","combat/drop reverse","95/4/1 normal and fixed+5:2 elite","see defaults table","demo economy"
|
||||
"boss mid-fight gear","one mid-fight gear appearance observed; condition unknown","runtime observation","trigger at first <=50% crossing","once per boss","demo threshold"
|
||||
"DiceGauge pressure","source hidden gauge 0->50->100, then 4-roll counter, then 4 distinct non-AUGMENT pressure tiles","stage config + IL2CPP + runtime","enter at50; +25 per player action; at100 count down4 rolls; pressure action resets to0; shortage does not downgrade and delays conversion","resolved pressure tile becomes Empty","intentional cycle deviation + frozen edge rules"
|
||||
"final Boss conversion movement","source overflow edge not fully observed","Start/Boss branch partial + gameplay decision","preserve remainingSteps after 44-tile conversion; if zero require one more Roll and new landing","current standing tile is not a new landing","MVP frozen"
|
||||
"Floor point reward","original loop reward resources and stage multipliers differ","ingamereward.csv","10+5*Floor in-run points","integer","intentional economy replacement"
|
||||
|
@@ -0,0 +1,14 @@
|
||||
"key","value","execution_rule","source_status","source"
|
||||
"buildingCarrier","exterior house layer","A house is attached to a small tile's exterior slot and never replaces its movement tile, event, or enemy content","MVP frozen","v0.2.8 building-module decision"
|
||||
"exteriorSlotCapacity","1 per ordinary small tile","A slot is eligible only when it has no house and belongs to the configured upcoming board side","MVP frozen","v0.2.8 building-module decision"
|
||||
"housingSupportTileId","129","Landing on Housing Support opens the construction event and performs one two-die construction roll","source-aligned","newtile.csv + CornerDiceBuilding reverse"
|
||||
"baseConstructionAttempts","D6_A + D6_B","Roll two independent six-sided dice once; their sum is the number of base construction attempts","source-aligned","CornerDiceBuilding reverse"
|
||||
"urbanPlanningBlessingId","152","If owned, add 2 construction attempts once per Housing Support event; the blessing is unique and does not stack","source structure + MVP consumer freeze","augment.csv EmptyTripleBuild"
|
||||
"placementOrder","next clockwise board side","Starting after the Housing Support Corner, collect empty exterior slots on the following side and choose distinct slots without replacement using the run RNG seed","MVP executable edge","v0.2.8 geometry freeze"
|
||||
"actualBuiltCount","min(totalAttempts, eligibleSlotCount)","Every selected eligible slot succeeds; unused attempts are discarded","source-aligned cap + MVP edge","CornerDiceBuilding reverse + v0.2.8"
|
||||
"reward","actualBuiltCount * 1 spirit stone","Grant the reward after placement animation; the exact original reward conversion remains unknown","DEMO default","04-unknown-parameter-mvp-defaults.csv"
|
||||
"zeroEligibleSlots","build 0 and reward 0","Show a no-space result, complete the event, and do not reroll or relocate to another side","MVP frozen","v0.2.8 building-module decision"
|
||||
"persistence","until final Boss Floor","Houses survive loop/Floor progression and Good/Enemy/Empty mutations of the underlying tile because the exterior layer is independent","MVP frozen","v0.2.8 building-module decision"
|
||||
"ongoingEffect","none","A built house has no passive income, combat bonus, or tile-trigger modification in MVP","MVP scope freeze","v0.2.8 building-module decision"
|
||||
"finalBossCleanup","clear every exterior house","Clear houses in the same board-conversion transaction that replaces all 44 positions with Boss Tiles","MVP frozen","v0.2.8 final Boss rule"
|
||||
"saveState","slot occupancy + construction RNG result","Persist occupied slot IDs, both dice values, selected slot IDs, reward, seed, and ruleset version at the event safety point","MVP frozen","v0.2.8 determinism requirement"
|
||||
|
@@ -0,0 +1,14 @@
|
||||
# 10-配置与白名单
|
||||
|
||||
Start时序、内容白名单、未知参数默认值及原作/MVP对照。
|
||||
|
||||
## 文件
|
||||
|
||||
- [01-start-settlement-timeline.csv](./01-start-settlement-timeline.csv) — contract;来源:`analysis/mvp-rules-closure/01-start-settlement-timeline.csv`
|
||||
- [02-tile-corner-blessing-whitelist.csv](./02-tile-corner-blessing-whitelist.csv) — contract;来源:`analysis/mvp-rules-closure/02-tile-corner-blessing-whitelist.csv`
|
||||
- [03-shop-product-whitelist.csv](./03-shop-product-whitelist.csv) — contract;来源:`analysis/mvp-rules-closure/03-shop-product-whitelist.csv`
|
||||
- [04-unknown-parameter-mvp-defaults.csv](./04-unknown-parameter-mvp-defaults.csv) — contract;来源:`analysis/mvp-rules-closure/04-unknown-parameter-mvp-defaults.csv`
|
||||
- [05-original-vs-mvp-vs-demo.csv](./05-original-vs-mvp-vs-demo.csv) — contract;来源:`analysis/mvp-rules-closure/05-original-vs-mvp-vs-demo.csv`
|
||||
- [06-building-rules.csv](./06-building-rules.csv) — contract;来源:`analysis/mvp-rules-closure/06-building-rules.csv`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,60 @@
|
||||
# Stage 2.5.3 纠错报告
|
||||
|
||||
## 1. Critical Rate
|
||||
|
||||
### 已废止结论
|
||||
|
||||
`0x549B934` 位于防御者侧 `BaseMonoCharacter.HitAndGetResult`,属于 Hit/Miss 判定。任何把它解释成 Critical Rate RNG 的结论均标记为 `SUPERSEDED`。
|
||||
|
||||
### 新闭环
|
||||
|
||||
`CRITICAL_RATE / EMonoStatus 11` → `CharacterStatus.GetFinalStatus(11)` → 整数 RNG `[0,101)` → `chance > roll` → `DamageMeta.isCritical (+0x28)`。
|
||||
|
||||
入口是攻击者覆写 `BaseMonoPlayer.OnBeforeAttack @ 0x55A95EC`。`BaseActor.<RunAttackSequence>d__44.MoveNext @ 0x5496AB0` 先构造 `DamageMeta`,将 `isCritical` 初始化为 false,再调用攻击者攻击前钩子。攻击者钩子在公共尾部以 `cset gt` 生成布尔值并写入 DamageMeta。
|
||||
|
||||
结论:`VERIFIED / HIGH`。
|
||||
|
||||
## 2. Gacha
|
||||
|
||||
### Selector
|
||||
|
||||
`GachaProduct.RewardGacha @ 0x52F22E4` 使用 `<RewardGacha>b__21_0 @ 0x52F4840` 读取 `Gacha.prob (+0x28)`,并调用通用选择器 `0x50EDB34`。
|
||||
|
||||
选择器先获得权重总和,将其乘以常数 `10000`,调用 RNG 助手 `0x513C53C` 取得整数随机游标,再遍历候选项:若游标仍大于当前权重则减去当前权重并继续,否则返回当前索引。
|
||||
|
||||
结论:`VERIFIED / HIGH`。
|
||||
|
||||
### Pity counter
|
||||
|
||||
配置表明确给出三组 `ceilCount`:20、50、400。运行时计数更新助手 `0x51138F0` 已定位:它按抽数参数更新一个持久化 Gacha 记录的计数,并存在不同的分支处理;命中检查助手 `0x510078C` 会读取持久化记录并与传入的 ceil 参数比较。`RewardGacha` 在 `0x52F3D1C` 调用该检查助手,成功分支进入指定保底奖励选择。
|
||||
|
||||
但当前静态证据尚不能把 `0x51138F0` 的两个分支安全命名为“普通 increment”和“reset”,也没有看到可独立证明的 `count = 0` 写入。因此本包不把“何时归零、是否跨十连逐抽归零、提前出货是否归零”写成事实。
|
||||
|
||||
结论:`PARTIAL / MEDIUM`。已闭合 `count update → ceil compare → guaranteed branch`,未闭合精确 reset 语义。
|
||||
|
||||
## 3. Boss Gauge
|
||||
|
||||
### 关键纠正
|
||||
|
||||
`stageinfo.csv` 中 `bossSpawnRule=DiceGauge, bossSpawnRuleValue=50` 的 50 是每次格子结算加入 Gauge 的配置值,不是“当前 Gauge 与 50 比较”的阈值。
|
||||
|
||||
格子执行状态机 `<ExecuteAsync>d__0.MoveNext @ 0x553EEEC` 在 `0x55445E8` 读取配置增量,随后:
|
||||
|
||||
```text
|
||||
current = GetRuntimeGauge() // 0x52E4DA8
|
||||
next = clamp(current + configValue, 0, 100)
|
||||
SetRuntimeGauge(next) // 0x52E4E10
|
||||
```
|
||||
|
||||
实时 Gauge 存储在运行时数据对象 `+0x2E0`。setter 写入后还会通知相关事件/UI。`MoveTile` 在 `0x56C038C` 调用 `TrySpawnBossTilesByGauge @ 0x569FEC0`;生成流程完成后的后续状态机在 `0x52E6064–0x52E6068` 对同一 setter 传入 0,形成清零证据。
|
||||
|
||||
`NewStagePlayData.highestBossTileGauge (+0x1C)` 是历史最高 Gauge 存档字段,不能替代实时字段。
|
||||
|
||||
结论:Gauge 更新式与实时字段为 `VERIFIED / HIGH`;“具体哪一个布尔资格检查代表满 Gauge”仍为 `PARTIAL / MEDIUM`,因为该检查被共享/间接调用封装,未恢复出可靠托管名称。
|
||||
|
||||
## 4. 对 GDD 反推的约束
|
||||
|
||||
- 暴击率可写为客户端判定:`critical = CRITICAL_RATE > RandomInt(0,101)`。
|
||||
- Gacha 可写为权重抽取,但不得擅自把 `prob` 解释成百分比;它是相对权重,内部按 10000 精度离散化。
|
||||
- Pity 可写配置阈值与已定位计数助手,不得补写未经证明的 reset 时机。
|
||||
- Boss Gauge 应写成 0–100 的进度,配置 50 是单次增量;不要写成“Gauge >= 50 触发 Boss”。
|
||||
@@ -0,0 +1,54 @@
|
||||
# Stage 2.5.3 最终交付审计
|
||||
|
||||
审计日期:2026-08-21
|
||||
目标:HEROLL 2.0.1(`com.percent.aos.rollinghero`)
|
||||
审计性质:只补齐报告已引用的 Primary Native 与文件完整性记录;未新增逆向任务,未新增或修改玩法结论。
|
||||
|
||||
## 审计结论
|
||||
|
||||
**PASS / READY FOR CHATGPT HANDOFF**。
|
||||
|
||||
Stage 2.5.3 原有 Critical、Gacha、Boss Gauge 报告和 Evidence Matrix 保持原结论等级。此前报告引用但未随包提供的指定原生函数现已全部加入,并以完整、排他的函数地址范围导出。
|
||||
|
||||
## Primary Native 覆盖
|
||||
|
||||
### Gacha
|
||||
|
||||
| 要求地址 | 随包文件 | 完整范围 | 结果 |
|
||||
|---|---|---|---|
|
||||
| `0x52F4840` | `05_NATIVE_PRIMARY/GACHA_PRIMARY/RewardGacha_prob_reader__06001C52.txt` | `[0x52F4840, 0x52F4854)` | PASS |
|
||||
| `0x50EDB34` | `05_NATIVE_PRIMARY/GACHA_PRIMARY/Address_0x50EDB34_weighted_selector.txt` | `[0x50EDB34, 0x50EDCA4)` | PASS |
|
||||
| `0x513C53C` | `05_NATIVE_PRIMARY/GACHA_PRIMARY/Address_0x513C53C_rng_helper.txt` | `[0x513C53C, 0x513C8C4)` | PASS |
|
||||
| `0x51138F0` | `05_NATIVE_PRIMARY/GACHA_PRIMARY/Address_0x51138F0_counter_update.txt` | `[0x51138F0, 0x5113C40)` | PASS |
|
||||
| `0x510078C` | `05_NATIVE_PRIMARY/GACHA_PRIMARY/Address_0x510078C_ceil_compare.txt` | `[0x510078C, 0x5100928)` | PASS |
|
||||
|
||||
### Boss Gauge
|
||||
|
||||
| 要求内容 | 随包文件 | 完整范围 | 结果 |
|
||||
|---|---|---|---|
|
||||
| 包含 `0x55445E8–0x5544614` 的 ExecuteAsync | `05_NATIVE_PRIMARY/BOSS_GAUGE_PRIMARY/ExecuteAsync_d__0.MoveNext__06003026.txt` | `[0x553EEEC, 0x5547874)` | PASS |
|
||||
| getter `0x52E4DA8` | `05_NATIVE_PRIMARY/BOSS_GAUGE_PRIMARY/Address_0x52E4DA8_gauge_getter.txt` | `[0x52E4DA8, 0x52E4E10)` | PASS |
|
||||
| setter `0x52E4E10` | `05_NATIVE_PRIMARY/BOSS_GAUGE_PRIMARY/Address_0x52E4E10_gauge_setter.txt` | `[0x52E4E10, 0x52E4F94)` | PASS |
|
||||
| 包含 `0x52E6064–0x52E6068` 清零调用的完整函数 | `05_NATIVE_PRIMARY/BOSS_GAUGE_PRIMARY/MoveFocusToCompositeRoot.MoveNext_clear_call__06001BD8.txt` | `[0x52E5740, 0x52E78E8)` | PASS |
|
||||
|
||||
## Evidence → Finding → Path 复核
|
||||
|
||||
- Critical:原有 Primary Native 与 `F-CRIT-253-001/002` 路径未改动。
|
||||
- Gacha:新增的五份 Primary Native 为 `F-GACHA-253-001/002/003` 提供随包原始函数体;Finding 的 `VERIFIED/PARTIAL` 等级未改动。
|
||||
- Boss Gauge:新增的四份 Primary Native 覆盖 `F-BOSS-253-001/002` 报告引用区间;Finding 的 `VERIFIED/PARTIAL` 等级未改动。
|
||||
- `06_EVIDENCE_MATRIX.csv` 仍是结论等级主索引;`05_NATIVE_PRIMARY/FINAL_AUDIT_NATIVE_INDEX.csv` 是本轮原始函数附件索引。
|
||||
|
||||
## 范围与语义保护
|
||||
|
||||
- 包名已更正为 `com.percent.aos.rollinghero`。
|
||||
- 最终原始函数核对确认,先前报告把 ExecuteAsync 指令区间多写了一个十六进制位;已从 `0x554445E8–0x55444614` 校正为原生文件中的 `0x55445E8–0x5544614`。该校正不改变玩法结论。
|
||||
- 未进行新的动态测试、静态追踪或玩法推断。
|
||||
- 未把 Gacha reset 或 Boss 完整触发谓词从 `PARTIAL` 提升为 `VERIFIED`。
|
||||
- 新增文件仅用于补足报告已引用地址的原始指令可审计性。
|
||||
|
||||
## 完整性
|
||||
|
||||
- `SHA256SUMS.csv` 覆盖包内除其自身外的全部文件。
|
||||
- `05_NATIVE_PRIMARY/FINAL_AUDIT_NATIVE_INDEX.csv` 记录本轮九份新增 Primary Native 的地址范围、大小与单文件 SHA-256。
|
||||
- 已对原始 case `work/heroll-stage-2-5` 执行 Case Review 的 `--verify-hashes --strict` 检查:`0 errors / 0 warnings / PASS`。
|
||||
- 最终打包前执行逐文件 SHA-256 回验和 ZIP 条目检查;结果必须为 PASS 后方可交付。
|
||||
@@ -0,0 +1,23 @@
|
||||
# Case review
|
||||
|
||||
- status: PASS
|
||||
- case_root: `C:\Users\toshio\Documents\ChatGPT\heroll\work\heroll-stage-2-5`
|
||||
- generated_at: 2026-08-31T07:46:23.383470+00:00
|
||||
- command: `review_case.py work/heroll-stage-2-5 --verify-hashes --strict --format markdown`
|
||||
|
||||
## Summary
|
||||
|
||||
| Metric | Value |
|
||||
|---|---:|
|
||||
| errors | 0 |
|
||||
| warnings | 0 |
|
||||
| evidence | 20 |
|
||||
| workitems | 4 |
|
||||
| timeline_events | 5 |
|
||||
| findings | 10 |
|
||||
| paths | 8 |
|
||||
|
||||
## Result
|
||||
|
||||
No review issues found. Artifact hashes present in the case package were verified. New drop-rule Evidence records are linked to `WI-004` and the 2026-08-31 timeline event.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# 99-审计与证据追溯
|
||||
|
||||
范围、时间线、Evidence→Finding→Path与各模块Case Review。
|
||||
|
||||
## 文件
|
||||
|
||||
- [01_CORRECTION_REPORT.md](./01_CORRECTION_REPORT.md) — correction;来源:`HEROLL_STAGE_2_5_3_CORRECTION_EVIDENCE/01_CORRECTION_REPORT.md`
|
||||
- [09_CASE_REVIEW.md](./09_CASE_REVIEW.md) — audit;来源:`HEROLL_STAGE_2_5_3_CORRECTION_EVIDENCE/09_CASE_REVIEW.md`
|
||||
- [2026-08-31-drop-rules-case-review.md](./2026-08-31-drop-rules-case-review.md) — audit;来源:`work/heroll-stage-2-5/report/2026-08-31-drop-rules-case-review.md`
|
||||
- [case-review-combat.md](./case-review-combat.md) — audit;来源:`work/heroll-stage-2-5/report/case-review-combat.md`
|
||||
- [case-review-pass.md](./case-review-pass.md) — audit;来源:`analysis/catalog-reverse/case-review-pass.md`
|
||||
- [findings.md](./findings.md) — findings;来源:`work/heroll-stage-2-5/findings.md`
|
||||
- [path.md](./path.md) — path;来源:`work/heroll-stage-2-5/path.md`
|
||||
- [scope.md](./scope.md) — scope;来源:`work/heroll-stage-2-5/scope.md`
|
||||
- [stage-floor-case-review.md](./stage-floor-case-review.md) — audit;来源:`work/heroll-stage-2-5/report/stage-floor-case-review.md`
|
||||
- [tile-event-case-review.md](./tile-event-case-review.md) — audit;来源:`work/heroll-stage-2-5/report/tile-event-case-review.md`
|
||||
- [timeline.md](./timeline.md) — timeline;来源:`work/heroll-stage-2-5/timeline.md`
|
||||
|
||||
模块内Markdown与CSV均来自同一v0.2.8规则域;跨模块综合报告会在相关模块中保留副本。
|
||||
@@ -0,0 +1,22 @@
|
||||
# Case review — main-run combat and Double closure
|
||||
|
||||
- status: PASS
|
||||
- case_root: `work/heroll-stage-2-5`
|
||||
- generated_at: 2026-08-28T09:18:19.908482+00:00
|
||||
- mode: `--verify-hashes --strict --format markdown`
|
||||
|
||||
## Summary
|
||||
|
||||
| Metric | Value |
|
||||
|---|---:|
|
||||
| errors | 0 |
|
||||
| warnings | 0 |
|
||||
| evidence | 17 |
|
||||
| workitems | 3 |
|
||||
| timeline_events | 4 |
|
||||
| findings | 10 |
|
||||
| paths | 8 |
|
||||
|
||||
## Result
|
||||
|
||||
No review issues found. All seven evidence records added for the combat/Double closure are linked from WI-003 and the 2026-08-28 timeline event.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Case review
|
||||
|
||||
- status: PASS
|
||||
- date: 2026-08-31
|
||||
- strict: true
|
||||
- verify_hashes: true
|
||||
- errors: 0
|
||||
- warnings: 0
|
||||
- evidence_records: 24
|
||||
- workitems: 5
|
||||
|
||||
检查结论:Evidence → Work Item → Timeline → Report 路径完整,无严格审计问题。
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
# Findings
|
||||
|
||||
## F-STAGE-001
|
||||
- title: Default bossSpawnRuleValue is the exact Normal-stage floor count
|
||||
- category: reverse_algo
|
||||
- status: validated
|
||||
- evidence_ids: [E-STAGE-CONFIG-001]
|
||||
- location: stageinfo.csv joined to board.csv on EPlayMode=Normal and Stage
|
||||
- impact: Stage 0 is exactly ten stat-bearing loops before boss_0; DiceGauge 50 must not be interpreted as a floor count.
|
||||
- confidence: high
|
||||
- remediation: Drive Default stage length from bossSpawnRuleValue and require a matching board row for every zero-based loop.
|
||||
|
||||
## F-REFRESH-001
|
||||
- title: Board progression is additive and good-tile injection count is not fixed at two
|
||||
- category: reverse_algo
|
||||
- status: validated
|
||||
- evidence_ids: [E-STAGE-NATIVE-001, E-STAGE-WEB-001]
|
||||
- location: InitNewGame/SpawnInitalTiles/AddNextLoopTiles native state machines
|
||||
- impact: The earlier MVP rule of two guaranteed good tiles per floor does not reproduce the original board economy.
|
||||
- confidence: high
|
||||
- remediation: Initialize with AddRandomGoodTiles(8), then call AddRandomGoodTiles(loopIndex+2) and AddRandomEnemyTile(enemyTilesPerLoop,false) at loop transitions.
|
||||
|
||||
## F-TILE-001
|
||||
- title: Player good tiles use a shuffled OutGameTile deck without replacement per deck cycle
|
||||
- category: reverse_algo
|
||||
- status: validated
|
||||
- evidence_ids: [E-STAGE-CONFIG-001, E-STAGE-NATIVE-001]
|
||||
- location: BoardController.GetNextMetadata/GetRandomOutGameTileMetas/AddRandomGoodTiles
|
||||
- impact: Direct equal-weight selection from all GoodEvent rows produces the wrong initial board and ignores player loadout.
|
||||
- confidence: high
|
||||
- remediation: Build the deck from eligible player metas, advance a cached index, and reshuffle only at exhaustion.
|
||||
|
||||
## F-GAUGE-001
|
||||
- title: DiceGauge 50 is a per-settlement increment into a separate 0..100 runtime gauge
|
||||
- category: reverse_algo
|
||||
- status: validated
|
||||
- evidence_ids: [E-STAGE-NATIVE-001]
|
||||
- location: tile processing ExecuteAsync @ 0x553EEEC and MoveTile @ 0x56BF914
|
||||
- impact: Treating 50 as a threshold or merging it with BossDiceCounter breaks pressure timing and save restoration.
|
||||
- confidence: high
|
||||
- remediation: Keep runtimeBossGauge and BossDiceCounter separate; clamp additions and clear the gauge after the spawn sequence.
|
||||
|
||||
## F-GAUGE-002
|
||||
- title: Original DiceGauge pressure cycle is two-roll buildup plus four-roll countdown and four unique non-blessing conversions
|
||||
- category: design
|
||||
- status: validated
|
||||
- evidence_ids: [E-STAGE-NATIVE-001, E-STAGE-RUNTIME-001]
|
||||
- location: DiceGauge movement and boss tile generation flow
|
||||
- impact: Applying the cycle to Default stages or firing immediately after two rolls changes the original pacing.
|
||||
- confidence: high for observed standard path; partial for insufficient-candidate fallback
|
||||
- remediation: Enable only for DiceGauge stages and keep candidate-shortage behavior configurable until matching footage is captured.
|
||||
|
||||
## F-REFRESH-002
|
||||
- title: The start tile advances floor and hosts a shop every three display floors
|
||||
- category: design
|
||||
- status: corroborated
|
||||
- evidence_ids: [E-STAGE-WEB-001, E-STAGE-NATIVE-001]
|
||||
- location: Start tile behavior and BoardController shopPerLoop branch
|
||||
- impact: Treating the shop as an ordinary random tile changes access cadence.
|
||||
- confidence: medium-high
|
||||
- remediation: Attach shop appearance to the start tile at displayFloor mod 3 == 0.
|
||||
|
||||
## F-EVENT-001
|
||||
- title: The requested six Good Tiles are independent event state machines
|
||||
- category: reverse_algo
|
||||
- status: validated
|
||||
- evidence_ids: [E-TILE-CONFIG-001, E-TILE-NATIVE-001, E-TILE-RUNTIME-001]
|
||||
- location: NewTile IDs 137/141/143/151/164/169 and their ExecuteAsync/UI classes
|
||||
- impact: Reusing a single generic reward popup loses event-specific input, failure and continuation rules.
|
||||
- confidence: high
|
||||
- remediation: Implement each event as a separately persisted state machine with a single completion callback.
|
||||
|
||||
## F-EVENT-002
|
||||
- title: Lucky Scratch is GoodEventSpito 169, not GoodEventLotto 142
|
||||
- category: reverse_mapping
|
||||
- status: validated
|
||||
- evidence_ids: [E-TILE-CONFIG-001, E-TILE-NATIVE-001, E-TILE-RUNTIME-001]
|
||||
- location: newtile values 30,10,1,10,50,40 and ScratchPainter/SpitoEventView
|
||||
- impact: Mapping it to Lotto imports the wrong five-draw cost and reward rules.
|
||||
- confidence: high
|
||||
- remediation: Use weighted 30/10/1 point prizes at 10/50/40 and scratch-to-reveal input.
|
||||
|
||||
## F-EVENT-003
|
||||
- title: Chest generates three gear items and Dice Battle has no supported entry stake
|
||||
- category: design
|
||||
- status: validated
|
||||
- evidence_ids: [E-TILE-RUNTIME-001, E-TILE-NATIVE-001, E-TILE-WEB-001]
|
||||
- location: GoodEventChest spawn loop and BlackJackView reward flow
|
||||
- impact: The previous one-item chest and three-point stake materially underpay these tiles.
|
||||
- confidence: high for Chest; medium-high for no-stake mapping
|
||||
- remediation: Generate three normal-loot gear instances; interpret Blackjack config as three starting dice and ten-point base reward.
|
||||
|
||||
## F-CORNER-001
|
||||
- title: Core Corner set is 126–129 and has passive, timed and batch-mutation semantics
|
||||
- category: reverse_mapping
|
||||
- status: validated
|
||||
- evidence_ids: [E-TILE-CONFIG-001, E-TILE-NATIVE-001, E-TILE-WEB-001]
|
||||
- location: ingamereward item IDs 126–129 and Corner event classes
|
||||
- impact: Treating every enabled Corner as one of the base four breaks unlocks and board pacing.
|
||||
- confidence: high except Housing Support point scale
|
||||
- remediation: Keep Piggy Bank, Race, Flower Garden and Housing Support as the core four; gate later Corners independently.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Paths
|
||||
|
||||
## P-STAGE-001
|
||||
- title: Default stage configuration to final Boss
|
||||
- path_type: solve
|
||||
- start: stageinfo.csv Normal row
|
||||
- goal: final Boss entry
|
||||
- steps:
|
||||
1. Read bossSpawnRule and bossSpawnRuleValue — E-STAGE-CONFIG-001, F-STAGE-001.
|
||||
2. For Default, load board.csv rows loop=0..value-1 — E-STAGE-CONFIG-001, F-STAGE-001.
|
||||
3. Resolve each floor with its row's enemy stat template — E-STAGE-CONFIG-001, F-STAGE-001.
|
||||
4. After the final configured loop, enter stage bossID — E-STAGE-CONFIG-001, F-STAGE-001.
|
||||
- residual_risks: Default mid-boss user-visible floor number needs one capture to close the zero/one-based presentation boundary.
|
||||
|
||||
## P-REFRESH-001
|
||||
- title: Start-tile transition to additive board refresh
|
||||
- path_type: callflow
|
||||
- start: player passes the start tile
|
||||
- goal: next-floor board state
|
||||
- steps:
|
||||
1. Advance the loop through AddNextLoopTiles — E-STAGE-NATIVE-001, F-REFRESH-001.
|
||||
2. Draw loopIndex+2 player good-tile metas — E-STAGE-NATIVE-001, F-TILE-001.
|
||||
3. Resolve each refNewTileId and attempt installation with good-tile FX — E-STAGE-NATIVE-001, F-TILE-001.
|
||||
4. Add enemyTilesPerLoop enemy tiles without a full board rebuild — E-STAGE-NATIVE-001, F-REFRESH-001.
|
||||
5. At each third display floor, expose the shop on the start tile — E-STAGE-WEB-001, F-REFRESH-002.
|
||||
- residual_risks: The original serialized enemyTilesPerLoop value is not present in the recovered tables/assets.
|
||||
|
||||
## P-GAUGE-001
|
||||
- title: DiceGauge settlement to Boss pressure conversion
|
||||
- path_type: callflow
|
||||
- start: qualified tile settlement in a DiceGauge stage
|
||||
- goal: Boss pressure tiles generated and gauge reset
|
||||
- steps:
|
||||
1. Add bossSpawnRuleValue to the distinct runtime gauge and clamp 0..100 — E-STAGE-NATIVE-001, F-GAUGE-001.
|
||||
2. Run mid-boss and boss-spawn checks after movement — E-STAGE-NATIVE-001, F-GAUGE-001.
|
||||
3. With value 50, two standard settlements reach 100 — E-STAGE-NATIVE-001, E-STAGE-RUNTIME-001, F-GAUGE-002.
|
||||
4. Count down the next four rolls — E-STAGE-RUNTIME-001, F-GAUGE-002.
|
||||
5. Convert four unique non-blessing tiles and clear the runtime gauge — E-STAGE-NATIVE-001, E-STAGE-RUNTIME-001, F-GAUGE-002.
|
||||
- residual_risks: Candidate shortage, mode-specific protected tiles and exact post-attack restoration are not closed.
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Case Scope
|
||||
|
||||
## meta
|
||||
- case_id: heroll-stage-2-5
|
||||
- created: 2026-08-19T00:52:29.9191946+08:00
|
||||
- operator: local
|
||||
- project_root: C:\Users\toshio\Documents\ChatGPT\heroll
|
||||
- primary_skill: apk-reverse/SKILL.md
|
||||
- primary_id: R1
|
||||
- lead_role: lead
|
||||
- specialist_roles: []
|
||||
- hint: HEROLL 2.0.1 Unity IL2CPP APK targeted reverse engineering formulas runtime rules monetization evidence
|
||||
|
||||
## auth
|
||||
- status: granted
|
||||
- basis: user-owned project and explicitly provided APK
|
||||
- evidence_of_auth: User explicitly requested reverse-analysis of HEROLL APK materials in this task
|
||||
- MUST NOT proceed if status != granted
|
||||
|
||||
## in_scope
|
||||
- assets:
|
||||
- C:\Users\toshio\Documents\ChatGPT\heroll\HEROLL_APK_REVERSE_ONLY
|
||||
- C:\Users\toshio\Documents\ChatGPT\heroll\work\heroll-stage-2-5\video-analysis
|
||||
- surfaces: []
|
||||
- activities: []
|
||||
|
||||
## out_of_scope
|
||||
- assets: []
|
||||
- activities: [dos, phishing_real_users, unrestricted_exfil]
|
||||
|
||||
## network_profile
|
||||
- mode: offline
|
||||
- notes: |
|
||||
Stage 2.5.1 is an offline static/video evidence closure. No live target action is required.
|
||||
|
||||
## deliverables
|
||||
- report: true
|
||||
- field_journal: true
|
||||
- diagrams: true
|
||||
- timeline: true
|
||||
|
||||
## constraints
|
||||
- timebox: {}
|
||||
- stealth: low
|
||||
- data_handling: anonymize
|
||||
|
||||
## signoff
|
||||
- ready_for_act: true
|
||||
- checklist:
|
||||
- [x] auth.status = granted
|
||||
- [x] in_scope.assets non-empty OR offline sample path set
|
||||
- [x] network_profile.mode chosen
|
||||
- [x] out_of_scope reviewed
|
||||
- [x] roles assigned (lead-only offline review; no specialist delegation required)
|
||||
|
||||
## ops_refs
|
||||
- skills/ops/scope-contract.md
|
||||
- skills/ops/evidence-finding-path.md
|
||||
- skills/ops/role-map.md
|
||||
- skills/ops/timeline-workitem.md
|
||||
- skills/ops/IDENTITY.md
|
||||
@@ -0,0 +1,60 @@
|
||||
# Case Review — HEROLL Stage/Floor Refresh
|
||||
|
||||
## Verdict
|
||||
|
||||
PASS WITH EXPLICIT PARTIALS
|
||||
|
||||
The report is ready for internal gameplay-validation use. All central claims have an Evidence → Finding → Path chain. Three edge cases remain explicitly partial and are not represented as original facts.
|
||||
|
||||
## Scope readiness
|
||||
|
||||
- Authorization: PASS — user supplied and explicitly requested analysis of HEROLL 2.0.1.
|
||||
- Target identity: PASS — decrypted `libil2cpp.so` SHA-256 is recorded.
|
||||
- Network posture: PASS — local evidence is primary; public pages were used only for observable-behavior corroboration.
|
||||
- Cross-project contamination: PASS — no Dice Lords design rule is used.
|
||||
|
||||
## Traceability
|
||||
|
||||
| Finding | Evidence | Path | Result |
|
||||
|---|---|---|---|
|
||||
| F-STAGE-001 | E-STAGE-CONFIG-001 | P-STAGE-001 | PASS |
|
||||
| F-REFRESH-001 | E-STAGE-NATIVE-001, E-STAGE-WEB-001 | P-REFRESH-001 | PASS |
|
||||
| F-TILE-001 | E-STAGE-CONFIG-001, E-STAGE-NATIVE-001 | P-REFRESH-001 | PASS |
|
||||
| F-GAUGE-001 | E-STAGE-NATIVE-001 | P-GAUGE-001 | PASS |
|
||||
| F-GAUGE-002 | E-STAGE-NATIVE-001, E-STAGE-RUNTIME-001 | P-GAUGE-001 | PASS |
|
||||
| F-REFRESH-002 | E-STAGE-WEB-001, E-STAGE-NATIVE-001 | P-REFRESH-001 | PASS |
|
||||
|
||||
## Work item coverage
|
||||
|
||||
- WI-006 status: completed.
|
||||
- Required artifacts: present.
|
||||
- Timeline entry: present.
|
||||
- Field journal: present and continuous for this work item.
|
||||
- Configuration hashes: present.
|
||||
- Native target hash: present.
|
||||
- Gameplay-validation GDD and affected CSV contracts: corrected to disable DiceGauge in stage 0 and remove fixed-two/six-class guarantees.
|
||||
|
||||
## Mechanical validation
|
||||
|
||||
- 33 Default stages checked; floor-count mismatches: 0.
|
||||
- 19 DiceGauge stages checked; all configuration increments: 50.
|
||||
- Stage 0 Normal board rows: 10.
|
||||
- Generated tables: 52 stage rows, 10 Stage-0 floor rows, 46 enabled natural-tile rows, 8 default player-tile metas.
|
||||
- CSV parse: PASS for all four output tables and the edited GDD contract/UI/QA tables.
|
||||
- `git diff --check`: PASS.
|
||||
- Required artifact empty-file count: 0.
|
||||
|
||||
## Accuracy challenges
|
||||
|
||||
1. `loopIndex+2` was challenged against the previous “fixed +2” design. The ARM64 sequence explicitly loads the loop parameter and performs integer addition before the call; previous design is rejected.
|
||||
2. `DiceGauge=50` was challenged as a floor count/threshold. Board row counts are 13/15 and native arithmetic adds the value into a 0..100 field; the alternative interpretations are rejected.
|
||||
3. Initial draw 8 was challenged as coincidence with eight default metas. The call constant and eight defaultEquip rows are independent evidence; the implementation claim is accepted while placement success remains conditional.
|
||||
4. BossDiceCounter was challenged as the Gauge storage. It has independent getter/setter and add/subtract methods; the fields are kept separate.
|
||||
|
||||
## Explicit partials
|
||||
|
||||
- Exact serialized `enemyTilesPerLoop` value: UNKNOWN.
|
||||
- DiceGauge candidate shortage/protection fallback: UNKNOWN beyond the observed blessing exclusion.
|
||||
- Post-pressure restoration priority and exact Default mid-boss UI off-by-one boundary: PARTIAL.
|
||||
|
||||
No report section substitutes invented constants for these partials.
|
||||
@@ -0,0 +1,50 @@
|
||||
# HEROLL Good Tile / Corner Case Review
|
||||
|
||||
- review_date: 2026-09-01
|
||||
- scope: WI-007
|
||||
- verdict: PASS WITH EXPLICIT PARTIALS
|
||||
- target: HEROLL 2.0.1 `libil2cpp.runtime-decrypted.so`
|
||||
- target_sha256: `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA`
|
||||
|
||||
## Scope readiness
|
||||
|
||||
- Six requested Good Tiles are mapped to IDs 137, 141, 143, 151, 164 and 169.
|
||||
- The requested four core Corners are mapped to IDs 126–129.
|
||||
- Four additional enabled Corner events are separated from the core set to prevent taxonomy drift.
|
||||
- The analysis is limited to HEROLL; unrelated project material is not used as evidence.
|
||||
|
||||
## Evidence → Finding → Design traceability
|
||||
|
||||
| Evidence | Finding | Design output | Result |
|
||||
|---|---|---|---|
|
||||
| E-TILE-CONFIG-001 | F-EVENT-001, F-EVENT-002, F-CORNER-001 | Three CSV rule tables | PASS |
|
||||
| E-TILE-NATIVE-001 | F-EVENT-001, F-EVENT-003, F-CORNER-001 | Per-event state, input lock and completion rules | PASS |
|
||||
| E-TILE-RUNTIME-001 | F-EVENT-002, F-EVENT-003 | Chest/Forge/Scratch/Claw corrections | PASS |
|
||||
| E-TILE-WEB-001 | F-EVENT-003, F-CORNER-001 | Version-qualified semantic cross-check | PASS |
|
||||
|
||||
## Integrity and artifact checks
|
||||
|
||||
| Artifact | SHA256 |
|
||||
|---|---|
|
||||
| `analysis/tile-event-rules/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md` | `93EB13223E303FAD652ED46810A96AC5E4E0B4A0CA3384ED0B14352D2EA64B8B` |
|
||||
| `analysis/tile-event-rules/tables/good-tile-rules.csv` | `F5EBC9DF6A1BEEC71A8EB354881DBC2A8FA7DBDC92AC00E4E49B05C9CA0A7F2B` |
|
||||
| `analysis/tile-event-rules/tables/corner-rules.csv` | `4679EEBE11D52CDFAE15A830A5F3C221CC011F28E16FBCF4DAAB08731B4B60DE` |
|
||||
| `analysis/tile-event-rules/tables/event-reward-tables.csv` | `FBA1344325AF69C45862B8045A3FA6093F5DDC42BFA012CF0ECB38331881998C` |
|
||||
| `design/gameplay-validation/specs/events.csv` | `2B4064F29AA7B46EDB3DCC93F0150A6C43EA9A2E2BC14DAEC3B687AD0036B67F` |
|
||||
|
||||
- CSV parse check: PASS (`good-tile-rules` 6 rows, `corner-rules` 8 rows, `event-reward-tables` 21 rows, GDD `events` 14 rows).
|
||||
- Requested event-ID presence check: PASS.
|
||||
- Deprecated Dice Battle stake/dealer-17 rules absent: PASS.
|
||||
- `git diff --check`: PASS.
|
||||
- Native evidence index: 31 bounded ARM64 method extracts with individual hashes.
|
||||
|
||||
## Explicit partials
|
||||
|
||||
1. Housing Support: exact conversion from houses actually built to awarded points is not exposed by the recovered tables or localization data. The report does not promote the candidate “one point per house” to an original rule.
|
||||
2. Dice Battle: native methods expose UserWin and DealerWin but no separate push handler. Tie-to-dealer is a strong inference, not an exact recovered rule.
|
||||
|
||||
These partials do not affect entry, interaction, event completion or board-mutation reconstruction. They remain configuration gates for an exact reproduction build.
|
||||
|
||||
## Final review
|
||||
|
||||
WI-007 is complete at the available evidence boundary. Findings are supported by local configuration, bounded native disassembly and owner-provided runtime material; public community material is used only as version-qualified corroboration. No unsupported value is presented as source-confirmed.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Timeline (append-only)
|
||||
|
||||
## 2026-08-19T00:52:29.9191946+08:00 | lead | init
|
||||
- action: case-init
|
||||
- command_or_ref: skills/scripts/case-init.ps1
|
||||
- result_summary: case directory created; scope ready_for_act=true
|
||||
- artifacts: [scope.md, workitems.md]
|
||||
- evidence_ids: []
|
||||
- next: open PRIMARY SKILL.md and ACT within scope
|
||||
|
||||
## 2026-08-19T01:45:00+08:00 | lead | targeted-analysis
|
||||
- action: reconstruct IL2CPP mapping, extract native evidence, test runtime, index video, package findings
|
||||
- command_or_ref: method mapping scripts; radare2; ADB/logcat; FFmpeg; artifact-tool
|
||||
- result_summary: dice and Idle Dungeon formulas closed; commercial config structured; runtime blocker documented; UNKNOWNs preserved
|
||||
- artifacts: [libil2cpp.runtime-decrypted.so, method_addresses_raw.csv, native-evidence, video-analysis, report/stage25-findings.md]
|
||||
- evidence_ids: [E-IL2CPP-001, E-MAP-001, E-NATIVE-001, E-CONFIG-001, E-VIDEO-001, E-RUNTIME-001]
|
||||
- next: strict case review and handoff
|
||||
|
||||
## 2026-08-19T12:20:00+08:00 | lead | stage-2.5.1-closure
|
||||
- action: recover exact P0/P1 native bodies, protected IngameShop MethodDef addresses, dependency matrix, workbook and upload package
|
||||
- command_or_ref: build_stage251_manifest.mjs; extract_exact_stage251_native.ps1; build_stage251_call_edges.mjs; build_stage251_workbook.mjs
|
||||
- result_summary: 93 bounded Native bodies included; Main Run partially closed; Gacha pity and Boss Gauge arithmetic remain UNKNOWN; runtime attribution corrected
|
||||
- artifacts: [stage251-native-exact-final, evidence/stage251_evidence_dependency_matrix.csv, evidence/stage251_formula_evidence_incremental.xlsx]
|
||||
- evidence_ids: [E-NATIVE-251, E-MATRIX-251, E-WORKBOOK-251, E-ENV-251]
|
||||
- next: strict case review and independent ChatGPT audit
|
||||
|
||||
## 2026-08-28T00:00:00+08:00 | lead | main-run-combat-and-double-closure
|
||||
- action: re-audit main-run combat arithmetic and Double combat consumers
|
||||
- command_or_ref: radare2 6.2.0 bounded ARM64 disassembly; config joins; video evidence; web cross-check for unresolved localization semantics
|
||||
- result_summary: corrected hit-vs-critical RNG attribution; closed linear defense, reciprocal attack-speed, ceil/min-1 lifesteal and counter boundary; established that Double does not multiply movement or base damage and only affects combat through subscribed content
|
||||
- artifacts: [analysis/combat-rules/2026-08-28_逆向-HEROLL战斗规则-report.md, analysis/combat-rules/combat-formulas.csv, analysis/combat-rules/native-slices]
|
||||
- evidence_ids: [E-COMBAT-001, E-COMBAT-002, E-COMBAT-003, E-DOUBLE-001, E-DOUBLE-002, E-WEB-001, E-WEB-002]
|
||||
- next: apply validated overrides to the HEROLL gameplay-validation MVP and use controlled captures only for listed partial branches
|
||||
|
||||
## 2026-08-31T18:00:00+08:00 | lead | in-run-gear-generation-closure
|
||||
- action: recover gear-level weighted offset, rarity-to-affix mapping, shared affix pool, plusLevel star allocation and status value formula; audit boss mid-battle spawn evidence
|
||||
- command_or_ref: radare2 bounded ARM64 disassembly at 0x55BE240/0x55BDCC0/0x55C0840/0x55C0D70; config joins; user runtime observation; web cross-check
|
||||
- result_summary: normal-stage GearLevel=Floor+Weighted(0,1,2;90,5,1); six-grade affix/star behavior and nine-affix shared pool closed; original boss_0 threshold remains partial and validation 50 percent rule is explicitly non-original
|
||||
- artifacts: [analysis/drop-rules/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md, analysis/drop-rules/gear-level-rules.csv, analysis/drop-rules/gear-rarity-affix-rules.csv, analysis/drop-rules/gear-affix-pools.csv, analysis/drop-rules/gear-value-formulas.csv]
|
||||
- evidence_ids: [E-DROP-LEVEL-001, E-DROP-AFFIX-001, E-DROP-BOSS-001]
|
||||
- next: strict case review and implementation into the gameplay-validation MVP
|
||||
|
||||
## 2026-08-31T22:30:00+08:00 | lead | blessing-equipment-shop-catalog-closure
|
||||
- action: join authoritative CSVs with source localization and recover shop refresh, buy-count and surcharge arithmetic from native code
|
||||
- command_or_ref: extract_catalogs.py; bounded ARM64 review at 0x54E1FD4/0x54E2250/0x54DE518/0x54DE0A4
|
||||
- result_summary: 31 enabled blessings, 40 equipment identities and 96 shop offers extracted; paid reroll sequence 3,5,7... closed; generic repeat-purchase price growth disproved; fixed upgrade price chains enumerated
|
||||
- artifacts: [analysis/catalog-reverse/2026-08-31_逆向-HEROLL祝福装备商店完整清单-report.md, analysis/catalog-reverse/tables]
|
||||
- evidence_ids: [E-CATALOG-BLESSING-001, E-CATALOG-EQUIP-001, E-CATALOG-SHOP-001, E-SHOP-RUNTIME-001]
|
||||
- next: completed; workbook visual/formula validation and strict hash-aware case review passed
|
||||
|
||||
## 2026-08-31T23:30:00+08:00 | lead | stage-floor-refresh-closure
|
||||
- action: close Normal stage floor counts, additive board mutation, player good-tile deck selection and DiceGauge Boss pressure cycle
|
||||
- command_or_ref: radare2 6.2.0 bounded ARM64 disassembly; stageinfo/board/newtile/outgametile joins; owner runtime evidence; public behavior cross-check
|
||||
- result_summary: all Default stage values matched board row counts; initial good-tile draw 8 and per-loop loop+2 calls recovered; no-replacement shuffled player deck recovered; 50-per-settlement Gauge and 2+4 pressure cycle separated from BossDiceCounter
|
||||
- artifacts: [analysis/stage-floor-rules/2026-08-31_逆向-HEROLL关卡楼层分布与刷新规则-report.md, analysis/stage-floor-rules/tables]
|
||||
- evidence_ids: [E-STAGE-CONFIG-001, E-STAGE-NATIVE-001, E-STAGE-RUNTIME-001, E-STAGE-WEB-001]
|
||||
- next: strict case review; update gameplay-validation MVP to remove fixed +2-good-tile and stage-0 DiceGauge assumptions
|
||||
|
||||
## 2026-09-01T00:10:00+08:00 | lead | stage-floor-strict-review
|
||||
- action: execute strict traceability and mechanical validation; apply the recovered rules as an authoritative GDD overlay
|
||||
- command_or_ref: Evidence-Finding-Path audit; CSV parse/count checks; Default-stage equality join; git diff --check
|
||||
- result_summary: PASS WITH EXPLICIT PARTIALS; 33 Default stages had zero row-count mismatches; stage 0 Gauge and fixed-two/six-class assumptions removed from GDD and affected contracts
|
||||
- artifacts: [work/heroll-stage-2-5/report/stage-floor-case-review.md, design/gameplay-validation/Heroll_Gameplay_Validation_GDD.md]
|
||||
- evidence_ids: [E-STAGE-CONFIG-001, E-STAGE-NATIVE-001, E-STAGE-RUNTIME-001, E-STAGE-WEB-001]
|
||||
- next: update executable MVP behavior in a separate implementation turn if requested
|
||||
|
||||
## 2026-09-01T15:10:00+08:00 | lead | good-tile-corner-closure
|
||||
- action: recover six requested Good Tile state machines and the four core Corner rules
|
||||
- command_or_ref: CSV joins; IL2CPP metadata; radare2 6.2.0 bounded ARM64 extraction; owner screenshots; public semantic cross-check
|
||||
- result_summary: Chest/Forge/Dice Battle/Lucky Scratch/Claw/Dicereel and Corner 126–129 documented with entry, input, outcomes, rewards, exits and exception boundaries
|
||||
- artifacts: [analysis/tile-event-rules/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md, analysis/tile-event-rules/tables, analysis/tile-event-rules/native-evidence]
|
||||
- evidence_ids: [E-TILE-CONFIG-001, E-TILE-NATIVE-001, E-TILE-RUNTIME-001, E-TILE-WEB-001]
|
||||
- next: focused capture for Housing Support point payout and Dice Battle tie if exact closure is required
|
||||
|
||||
## 2026-09-01 — Good Tile / Corner strict review
|
||||
|
||||
- Completed WI-007 for Chest, Forge, Dice Battle, Lucky Scratch, Claw Machine, Dicereel and core Corner IDs 126–129.
|
||||
- Parsed all generated CSV deliverables, verified requested IDs, checked deprecated assumptions were removed, and ran `git diff --check` successfully.
|
||||
- Recorded artifact hashes and the two explicit residual unknowns in `report/tile-event-case-review.md`; verdict: PASS WITH EXPLICIT PARTIALS.
|
||||
@@ -0,0 +1,44 @@
|
||||
# HEROLL / 一骰登天 MVP v0.2.8 规则与逆向资料
|
||||
|
||||
> 这是按最终设计文档模块重新整理的GitHub发布包。总纲与闭合报告位于仓库根目录;每个模块的说明文档和CSV放在同一文件夹。
|
||||
|
||||
## 阅读顺序
|
||||
|
||||
1. [一骰登天 MVP v0.2.8 总纲](./一骰登天_MVP_v0.2.8_总纲.md)
|
||||
2. [规则闭合报告 v0.2.8](./规则闭合报告_v0.2.8.md)
|
||||
3. 按下方模块进入说明报告和CSV。
|
||||
4. 需要追溯结论时查看[文件索引](./文件索引.csv)和`99-审计与证据追溯`。
|
||||
|
||||
## 模块导航
|
||||
|
||||
- [01-关卡与棋盘](./01-%E5%85%B3%E5%8D%A1%E4%B8%8E%E6%A3%8B%E7%9B%98/README.md) — Stage、Floor、Start、棋盘刷新、Good牌组、Enemy注入与Boss规则。
|
||||
- [02-地块与事件](./02-%E5%9C%B0%E5%9D%97%E4%B8%8E%E4%BA%8B%E4%BB%B6/README.md) — Good Tile、Corner、事件奖励及运行规则。
|
||||
- [03-建筑](./03-%E5%BB%BA%E7%AD%91/README.md) — 地块外侧房屋、营造司掷骰、都市计划、建设奖励、持久化与终局清理。
|
||||
- [03-战斗](./03-%E6%88%98%E6%96%97/README.md) — 实时冷却行动模型、命中、暴击、防御、吸血、反击与Double消费者。
|
||||
- [04-局内装备](./04-%E5%B1%80%E5%86%85%E8%A3%85%E5%A4%87/README.md) — 装备本体、品质、等级、主副词条、plusLevel与随机值公式。
|
||||
- [05-商店](./05-%E5%95%86%E5%BA%97/README.md) — 商品目录、槽位、刷新、购买、固定升级与黑市价格。
|
||||
- [06-天道赐福](./06-%E5%A4%A9%E9%81%93%E8%B5%90%E7%A6%8F/README.md) — Blessing目录、候选池、叠加、依赖与首版启用范围。
|
||||
- [07-奖励与掉落](./07-%E5%A5%96%E5%8A%B1%E4%B8%8E%E6%8E%89%E8%90%BD/README.md) — 死亡掉落、战斗奖励、Floor奖励、Boss中途装备与事件奖励。
|
||||
- [08-BOSS与局内结束](./08-BOSS%E4%B8%8E%E5%B1%80%E5%86%85%E7%BB%93%E6%9D%9F/README.md) — Boss Gauge、压力循环、丹药关联、最终Boss Floor与结束分支。
|
||||
- [09-UI与美术资产](./09-UI%E4%B8%8E%E7%BE%8E%E6%9C%AF%E8%B5%84%E4%BA%A7/README.md) — 局内UI、小游戏配置、美术资产目录与资源说明。
|
||||
- [10-配置与白名单](./10-%E9%85%8D%E7%BD%AE%E4%B8%8E%E7%99%BD%E5%90%8D%E5%8D%95/README.md) — Start时序、内容白名单、未知参数默认值及原作/MVP对照。
|
||||
- [99-审计与证据追溯](./99-%E5%AE%A1%E8%AE%A1%E4%B8%8E%E8%AF%81%E6%8D%AE%E8%BF%BD%E6%BA%AF/README.md) — 范围、时间线、Evidence→Finding→Path与各模块Case Review。
|
||||
|
||||
## 证据边界
|
||||
|
||||
- `原作确认`来自HEROLL 2.0.1配置、IL2CPP原生逻辑或已闭合实机证据。
|
||||
- `实机确认`用于覆盖静态代码无法恢复的玩家可见语义。
|
||||
- `MVP主动偏离`与`DEMO冻结`只描述《一骰登天》的执行规则,不得反写成HEROLL原作事实。
|
||||
- 本仓库只发布Markdown和CSV;APK、SO、原生切片、工具与大体积导出资产未纳入。
|
||||
|
||||
## Evidence → Finding → Path
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
E[配置/原生/实机 Evidence] --> F[模块 Finding]
|
||||
F --> P[调用或规则 Path]
|
||||
P --> GDD[v0.2.8 总纲]
|
||||
GDD --> CSV[模块执行表与白名单]
|
||||
```
|
||||
|
||||
打包文件数:60;生成日期:2026-09-02。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
"module","kind","package_path","source_path","bytes","sha256"
|
||||
"01-关卡与棋盘","contract","01-关卡与棋盘/01-start-settlement-timeline.csv","analysis/mvp-rules-closure/01-start-settlement-timeline.csv","2422","48007B82C26FBF8A480FE1ADB85933B2A855B788CC91890E64C42DA6CD41E116"
|
||||
"01-关卡与棋盘","report","01-关卡与棋盘/2026-08-31_逆向-HEROLL关卡楼层分布与刷新规则-report.md","analysis/stage-floor-rules/2026-08-31_逆向-HEROLL关卡楼层分布与刷新规则-report.md","13184","DC4CCFED9467A38607CEB498C82612CF0D9957F9C63C2508FB206E88D8E6F1F1"
|
||||
"01-关卡与棋盘","table","01-关卡与棋盘/default-good-tile-deck.csv","analysis/stage-floor-rules/tables/default-good-tile-deck.csv","708","F89757D64E7D79ED16EC65436D4CA210BF51AC5E9637F9A47A4BCD8951124608"
|
||||
"01-关卡与棋盘","table","01-关卡与棋盘/enabled-tile-eligibility.csv","analysis/stage-floor-rules/tables/enabled-tile-eligibility.csv","3486","3D422BA72454F50F80D7A65F5C23A95A95299F5FAF2F82B095C32F51B68F5E05"
|
||||
"01-关卡与棋盘","table","01-关卡与棋盘/stage-boss-rules.csv","analysis/stage-floor-rules/tables/stage-boss-rules.csv","4354","56122C52143A674C0A098541BF6CE49BC215E5976B27E731D96C73B68F3D1A74"
|
||||
"01-关卡与棋盘","table","01-关卡与棋盘/stage0-loop-enemy-stats.csv","analysis/stage-floor-rules/tables/stage0-loop-enemy-stats.csv","680","C973EC282CE503FA81B30A70121DB59F46EB090C49FBA3F465F4AF8D666F0A3F"
|
||||
"02-地块与事件","report","02-地块与事件/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md","analysis/tile-event-rules/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md","10990","93EB13223E303FAD652ED46810A96AC5E4E0B4A0CA3384ED0B14352D2EA64B8B"
|
||||
"02-地块与事件","table","02-地块与事件/corner-rules.csv","analysis/tile-event-rules/tables/corner-rules.csv","3285","4679EEBE11D52CDFAE15A830A5F3C221CC011F28E16FBCF4DAAB08731B4B60DE"
|
||||
"02-地块与事件","table","02-地块与事件/event-reward-tables.csv","analysis/tile-event-rules/tables/event-reward-tables.csv","1643","FBA1344325AF69C45862B8045A3FA6093F5DDC42BFA012CF0ECB38331881998C"
|
||||
"02-地块与事件","table","02-地块与事件/good-tile-rules.csv","analysis/tile-event-rules/tables/good-tile-rules.csv","4026","F5EBC9DF6A1BEEC71A8EB354881DBC2A8FA7DBDC92AC00E4E49B05C9CA0A7F2B"
|
||||
"03-建筑","contract","03-建筑/04-unknown-parameter-mvp-defaults.csv","analysis/mvp-rules-closure/04-unknown-parameter-mvp-defaults.csv","7160","2934165195FA1F67909C2F81E562D7702CFE89A07AC0346A3073C62D3B5F7DE2"
|
||||
"03-建筑","contract","03-建筑/06-building-rules.csv","analysis/mvp-rules-closure/06-building-rules.csv","2689","90CEBB0F9C5A354A3E2DFF677E41ABCFDA04CDCAB8FD35A616ED336051E33B91"
|
||||
"03-建筑","table","03-建筑/corner-rules.csv","analysis/tile-event-rules/tables/corner-rules.csv","3285","4679EEBE11D52CDFAE15A830A5F3C221CC011F28E16FBCF4DAAB08731B4B60DE"
|
||||
"03-建筑","report","03-建筑/Housing Support逆向依据.md","analysis/tile-event-rules/2026-09-01_逆向-HEROLL-GoodTile与Corner规则-report.md","10990","93EB13223E303FAD652ED46810A96AC5E4E0B4A0CA3384ED0B14352D2EA64B8B"
|
||||
"03-战斗","report","03-战斗/2026-08-28_逆向-HEROLL战斗规则-report.md","analysis/combat-rules/2026-08-28_逆向-HEROLL战斗规则-report.md","14410","FF29B12BBB82D385C33D11AB1261790D8A410FAAFD6A0D056BFC791568C23110"
|
||||
"03-战斗","table","03-战斗/combat-formulas.csv","analysis/combat-rules/combat-formulas.csv","2744","7253CE558D053C60314891149C188CB1EC0722E5E38FFAF007852F9FFF4475A0"
|
||||
"04-局内装备","report","04-局内装备/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md","analysis/drop-rules/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md","9988","B3A57D004D4DC2F2F764DE3D95EFD84AB77AE972935A655ECBF4B22F52238EE2"
|
||||
"04-局内装备","catalog","04-局内装备/equipment-catalog.csv","analysis/catalog-reverse/tables/equipment-catalog.csv","13482","B10BEED4E764C676EB607BBD03CDEE7966504BFF428C0EEAF3A8745E733C5D2B"
|
||||
"04-局内装备","table","04-局内装备/gear-affix-pools.csv","analysis/drop-rules/gear-affix-pools.csv","754","58A8EE167125EF7817E90E48D78FAFB3B52ABFE8A7071E23A69A83D0DA745560"
|
||||
"04-局内装备","table","04-局内装备/gear-level-rules.csv","analysis/drop-rules/gear-level-rules.csv","418","760D73FDB262B485857090FFCC618A4B57B202A06EFB5B3180FFFBA67CCFAF29"
|
||||
"04-局内装备","table","04-局内装备/gear-rarity-affix-rules.csv","analysis/drop-rules/gear-rarity-affix-rules.csv","506","A1337C0A18D58E580CC08118319BE529C2FAEFEDE178DCF5D4184A6932DC6C54"
|
||||
"04-局内装备","table","04-局内装备/gear-value-formulas.csv","analysis/drop-rules/gear-value-formulas.csv","725","7A213F077A0ADB3084538DA095EC56B5419DB4708427B95F6EEE53C1008AC476"
|
||||
"04-局内装备","guide","04-局内装备/HEROLL_2.0.1_掉落规则.md","analysis/drop-rules/HEROLL_2.0.1_掉落规则.md","9511","C3C2293302D93C9ACF8B1BA20A12554764643F7139A49781F0C24679BB9CFE42"
|
||||
"05-商店","contract","05-商店/03-shop-product-whitelist.csv","analysis/mvp-rules-closure/03-shop-product-whitelist.csv","13226","8F707C92D2681E248D9781195EF631A568A8C4BC55AC2D34C2F52F0A7C3203A8"
|
||||
"05-商店","report","05-商店/祝福装备商店综合逆向报告.md","analysis/catalog-reverse/2026-08-31_逆向-HEROLL祝福装备商店完整清单-report.md","10325","27160FA4FBB1FD41015FE9C0F7AC4B67D357E5256275782B9B437E594D7F90EC"
|
||||
"05-商店","catalog","05-商店/shop-catalog.csv","analysis/catalog-reverse/tables/shop-catalog.csv","17267","CA8A0075701305E7C3A4AAC17A824BB7E39FD090648E1DAD734C508C626F1261"
|
||||
"05-商店","table","05-商店/shop-mechanics.csv","analysis/catalog-reverse/tables/shop-mechanics.csv","1134","96D2F02B3BFF68FB75CCD9734BB866113B80525453DA3AB56825E49F161C121E"
|
||||
"06-天道赐福","contract","06-天道赐福/02-tile-corner-blessing-whitelist.csv","analysis/mvp-rules-closure/02-tile-corner-blessing-whitelist.csv","9885","F0A51E521271BFB672C4AE4968578A302F72616F7B73E52D9947DD13E61C2A98"
|
||||
"06-天道赐福","report","06-天道赐福/祝福装备商店综合逆向报告.md","analysis/catalog-reverse/2026-08-31_逆向-HEROLL祝福装备商店完整清单-report.md","10325","27160FA4FBB1FD41015FE9C0F7AC4B67D357E5256275782B9B437E594D7F90EC"
|
||||
"06-天道赐福","catalog","06-天道赐福/blessings-catalog.csv","analysis/catalog-reverse/tables/blessings-catalog.csv","7410","973534F1FD6F606931E4298A4CE2685FBFF5C69E1C45F70E72FEAA06ED032846"
|
||||
"07-奖励与掉落","report","07-奖励与掉落/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md","analysis/drop-rules/2026-08-31_逆向-HEROLL装备等级词条星级与Boss掉落-report.md","9988","B3A57D004D4DC2F2F764DE3D95EFD84AB77AE972935A655ECBF4B22F52238EE2"
|
||||
"07-奖励与掉落","table","07-奖励与掉落/event-reward-tables.csv","analysis/tile-event-rules/tables/event-reward-tables.csv","1643","FBA1344325AF69C45862B8045A3FA6093F5DDC42BFA012CF0ECB38331881998C"
|
||||
"07-奖励与掉落","table","07-奖励与掉落/gear-rarity-affix-rules.csv","analysis/drop-rules/gear-rarity-affix-rules.csv","506","A1337C0A18D58E580CC08118319BE529C2FAEFEDE178DCF5D4184A6932DC6C54"
|
||||
"07-奖励与掉落","report","07-奖励与掉落/HEROLL_2.0.1_DROP_RULES_REPORT.md","analysis/drop-rules/HEROLL_2.0.1_DROP_RULES_REPORT.md","9511","C3C2293302D93C9ACF8B1BA20A12554764643F7139A49781F0C24679BB9CFE42"
|
||||
"08-BOSS与局内结束","report","08-BOSS与局内结束/2026-08-24_逆向-HEROLL丹药与Boss循环-report.md","docs/2026-08-24_逆向-HEROLL丹药与Boss循环-report.md","3553","3358DD16912F9A33E5428BAAAD49C4CF1A763A596AB680B1C0AE14CFD5F989F6"
|
||||
"08-BOSS与局内结束","report","08-BOSS与局内结束/boss_gauge_final_report.md","HEROLL_STAGE_2_5_2_EVIDENCE/10_UPLOAD_TO_CHATGPT/boss_gauge_final_report.md","1117","2D2892E0ED7504F98D73B88A2B985B85D41AA76C1B0059B93CEE263BD2067612"
|
||||
"08-BOSS与局内结束","report","08-BOSS与局内结束/HEROLL-potion-boss-report.md","work/20260824-heroll-potion-gauge/report/HEROLL-potion-boss-report.md","1929","B624801278848EA92923073B0B572604655DCCD5274CA49F8CF340769778B121"
|
||||
"08-BOSS与局内结束","table","08-BOSS与局内结束/stage-boss-rules.csv","analysis/stage-floor-rules/tables/stage-boss-rules.csv","4354","56122C52143A674C0A098541BF6CE49BC215E5976B27E731D96C73B68F3D1A74"
|
||||
"09-UI与美术资产","report","09-UI与美术资产/2026-08-13_art-bible-heroll-report.md","docs/2026-08-13_art-bible-heroll-report.md","27845","46B0A6761DFBDFB67E25E1B7A4957F5C41E78D94208950B4AB1859B5AE1CF4FC"
|
||||
"09-UI与美术资产","report","09-UI与美术资产/2026-08-24_逆向工程-HEROLL小游戏配置-report.md","docs/2026-08-24_逆向工程-HEROLL小游戏配置-report.md","6115","032057F5554B5517E4A37AB13A69702CF54A9412A4A163CF0F1ABC04C4C6473A"
|
||||
"09-UI与美术资产","report","09-UI与美术资产/2026-08-25_逆向资源-HEROLL美术资产-report.md","docs/2026-08-25_逆向资源-HEROLL美术资产-report.md","7945","6FAA5A53CF475500C7CF045DC340E60DF96755C356306F6CCF6051AF27F161A9"
|
||||
"10-配置与白名单","contract","10-配置与白名单/01-start-settlement-timeline.csv","analysis/mvp-rules-closure/01-start-settlement-timeline.csv","2422","48007B82C26FBF8A480FE1ADB85933B2A855B788CC91890E64C42DA6CD41E116"
|
||||
"10-配置与白名单","contract","10-配置与白名单/02-tile-corner-blessing-whitelist.csv","analysis/mvp-rules-closure/02-tile-corner-blessing-whitelist.csv","9885","F0A51E521271BFB672C4AE4968578A302F72616F7B73E52D9947DD13E61C2A98"
|
||||
"10-配置与白名单","contract","10-配置与白名单/03-shop-product-whitelist.csv","analysis/mvp-rules-closure/03-shop-product-whitelist.csv","13226","8F707C92D2681E248D9781195EF631A568A8C4BC55AC2D34C2F52F0A7C3203A8"
|
||||
"10-配置与白名单","contract","10-配置与白名单/04-unknown-parameter-mvp-defaults.csv","analysis/mvp-rules-closure/04-unknown-parameter-mvp-defaults.csv","7160","2934165195FA1F67909C2F81E562D7702CFE89A07AC0346A3073C62D3B5F7DE2"
|
||||
"10-配置与白名单","contract","10-配置与白名单/05-original-vs-mvp-vs-demo.csv","analysis/mvp-rules-closure/05-original-vs-mvp-vs-demo.csv","6940","D41539EB4F138F325A291BFF9CE7139C66A5AB8354F7F51747DAFB9435B89ADC"
|
||||
"10-配置与白名单","contract","10-配置与白名单/06-building-rules.csv","analysis/mvp-rules-closure/06-building-rules.csv","2689","90CEBB0F9C5A354A3E2DFF677E41ABCFDA04CDCAB8FD35A616ED336051E33B91"
|
||||
"99-审计与证据追溯","correction","99-审计与证据追溯/01_CORRECTION_REPORT.md","HEROLL_STAGE_2_5_3_CORRECTION_EVIDENCE/01_CORRECTION_REPORT.md","3605","FB553CE7F19A0484B02B35E8F6AD8FCF78D4AF599F4149814900FBC6EB840534"
|
||||
"99-审计与证据追溯","audit","99-审计与证据追溯/09_CASE_REVIEW.md","HEROLL_STAGE_2_5_3_CORRECTION_EVIDENCE/09_CASE_REVIEW.md","3566","BDE7F1AC330104166A5D5444FAC011384AA83F1F6447CE62D7798BE15D1B7120"
|
||||
"99-审计与证据追溯","audit","99-审计与证据追溯/2026-08-31-drop-rules-case-review.md","work/heroll-stage-2-5/report/2026-08-31-drop-rules-case-review.md","602","308D337B681F23DDD7FD10334262E1C856C12096B025FD6FEEEE2C95BE0103D1"
|
||||
"99-审计与证据追溯","audit","99-审计与证据追溯/case-review-combat.md","work/heroll-stage-2-5/report/case-review-combat.md","532","85AE5B9F6CB192A56E199C3C60401D0095A4DD7A20A693B3CAA1E5B88FE9E083"
|
||||
"99-审计与证据追溯","audit","99-审计与证据追溯/case-review-pass.md","analysis/catalog-reverse/case-review-pass.md","254","7F06E7E6394AF8887D0EA9B736E5D42CBD6C33F8E83925CFC495365E79608B3A"
|
||||
"99-审计与证据追溯","findings","99-审计与证据追溯/findings.md","work/heroll-stage-2-5/findings.md","5452","F3F753BB20E55339FF2BE32C861E870E3FE77F45C20684C6C95B6674D09C7A6C"
|
||||
"99-审计与证据追溯","path","99-审计与证据追溯/path.md","work/heroll-stage-2-5/path.md","2288","324AFFBE674C0DD6679481C95ABE6883CC4C929F937C2D2C0EB584648644D4C2"
|
||||
"99-审计与证据追溯","scope","99-审计与证据追溯/scope.md","work/heroll-stage-2-5/scope.md","1709","7DA3CBED2D838F6DE01FD12AC5ED97F3C134E56F745F44B9718113A7CE6E9335"
|
||||
"99-审计与证据追溯","audit","99-审计与证据追溯/stage-floor-case-review.md","work/heroll-stage-2-5/report/stage-floor-case-review.md","3154","14F869205C998CA3AE4209A8E272FEAE805EA46AF37D63227EE8C80649D0EF9F"
|
||||
"99-审计与证据追溯","audit","99-审计与证据追溯/tile-event-case-review.md","work/heroll-stage-2-5/report/tile-event-case-review.md","3099","577CB1A310327F95D8F8673898A030B47F795A8BA424B74784CD70E061E46C70"
|
||||
"99-审计与证据追溯","timeline","99-审计与证据追溯/timeline.md","work/heroll-stage-2-5/timeline.md","7738","71A13E26EFC5A54FA51ABBFF6DCF35CFF2E83435BD8A088EB1C9271654569B7F"
|
||||
"ROOT","closure","规则闭合报告_v0.2.8.md","analysis/mvp-rules-closure/2026-09-01_HEROLL-v0.2.8规则闭合报告.md","12055","1BA2A78C9D6181FBBF3D99A615244EA6BC3AD095E1F714B43288CDE6E468654F"
|
||||
"ROOT","master","一骰登天_MVP_v0.2.8_总纲.md","docs/局内玩法设计文档_一骰登天_MVP_v0.2.8.md","127137","3861D78E2A48F7BBDA79EDA63A7297B246C69B21F4BFEA97E11FB9369A85A0C0"
|
||||
|
@@ -0,0 +1,208 @@
|
||||
# HEROLL v0.2.8:Start 时序、首版白名单与未知参数闭合报告
|
||||
|
||||
> 仅研究 HEROLL 2.0.1。本文是《一骰登天》MVP v0.2.8 的规则覆盖层,不把 MVP 设计值伪装成 HEROLL 原作值。原生调用顺序作为证据保留;产品执行时序以本报告的“MVP冻结顺序”为准。
|
||||
|
||||
## 结论
|
||||
|
||||
本轮从 HEROLL 2.0.1 的 CSV 配置、IL2CPP 元数据和运行时解密后的 `libil2cpp.so` 中闭合了四项可直接开发的交付:
|
||||
|
||||
1. `Start` 正常结算路径的相对调用顺序;
|
||||
2. 原作规则、MVP 主动偏离、DEMO 默认值对照;
|
||||
3. Tile、Corner、Blessing 与 96 条 Shop 商品的首版运行时白名单;
|
||||
4. 原作仍无法确定的边界参数及唯一 MVP 默认值。
|
||||
|
||||
最重要的修正是:v0.2.7 原文中的两段 Start 描述彼此冲突。v0.2.8冻结为下面唯一产品执行顺序:
|
||||
|
||||
```text
|
||||
跨过Start,暂停剩余移动
|
||||
→ 商店判定与交互
|
||||
→ 最终Floor/BOSS判定
|
||||
→ 当前Floor结束奖励
|
||||
→ 非最终Floor:loopIndex推进并安装商店购买Tile
|
||||
→ 非最终Floor:AddRandomGoodTiles(loopIndex+2)
|
||||
→ 非最终Floor:AddRandomEnemyTile(enemyTilesPerLoop,false)
|
||||
→ 灵泉恢复
|
||||
→ 写安全点并继续剩余移动
|
||||
```
|
||||
|
||||
HEROLL原作调用链的商店准备、地块注入、商店交互和恢复相对顺序仍保留在证据列;上述产品事务顺序属于《一骰登天》主动覆盖,不能反写为原作顺序。
|
||||
|
||||
完整逐步表见 [01-start-settlement-timeline.csv](./01-start-settlement-timeline.csv)。
|
||||
|
||||
## 1. Start 结算时序
|
||||
|
||||
### 1.1 正常非最终 Floor
|
||||
|
||||
开发只读取[01-start-settlement-timeline.csv](./01-start-settlement-timeline.csv)中的MVP顺序。核心约束为:商店先完整交互;再判定最终BOSS;再发Floor奖励;普通分支才推进loop、安装购买Tile并依次刷新Good/Enemy;最后恢复并继续剩余移动。原生地址只用于说明来源差异,不覆盖本次产品时序决策。
|
||||
|
||||
`AddNextLoopTiles(loop)` 内部顺序为:
|
||||
|
||||
```text
|
||||
await AddRandomGoodTiles(loop + 2)
|
||||
await AddRandomEnemyTile(enemyTilesPerLoop, false)
|
||||
```
|
||||
|
||||
`loop+2` 是尝试次数,不是保证成功的新增数量。`enemyTilesPerLoop` 的字段和读取偏移已恢复,但场景中的原始序列化值没有出现在当前导出资产里,所以不能把 3 或 10 宣称为原作值。
|
||||
|
||||
### 1.2 最终 Floor 分支
|
||||
|
||||
达到 Default 最终 Floor 或 DiceGauge 50/50 的最终转换条件时:
|
||||
|
||||
1. 不继续普通 Good / Enemy 注入;
|
||||
2. 保存 Boss 前棋盘快照;
|
||||
3. 清空全部外侧房屋,并将 44 个位置转换为 Boss Tile;
|
||||
4. MVP保留`remainingSteps`并在新Boss棋盘继续移动;
|
||||
5. 若剩余步数归零后的新最终落点位于Boss Tile,则进入Boss战;
|
||||
6. 若转换时剩余步数已经为0,则必须再Roll一次并完成新的Boss Tile最终落点。
|
||||
|
||||
`SaveBeforeBossTiles` 的直接调用点为 `0x5545124`。最终转换时剩余步数是否在原作所有模式都以同样方式处理,现有证据没有完全闭合,因此“清零”仍标为 MVP 默认,而不是原作确认。
|
||||
|
||||
## 2. 首版内容 ID 白名单
|
||||
|
||||
### 2.1 Tile 与 Corner
|
||||
|
||||
首版真正启用 33 个 `newtile.csv` ID:
|
||||
|
||||
| 运行域 | ID |
|
||||
| --- | --- |
|
||||
| 核心棋盘 | `100,101,102,103,104,118,119,124,132,133,134,135` |
|
||||
| DiceGauge 压力扩展 | `105,106,110,111,112,113,114,115,116,117` |
|
||||
| Corner | `125,127,128,129,131` |
|
||||
| Good Event | `137,141,143,151,164,169` |
|
||||
|
||||
对应关系:
|
||||
|
||||
- `124` AUGMENT;
|
||||
- `125` Wall of Thorns / 天罚;
|
||||
- `127` Race / 竞天台;
|
||||
- `128` Flower Garden / 灵圃;
|
||||
- `129` Housing Support / 营造司;
|
||||
- `131` Black Market / 黑市散摊;
|
||||
- `137` Forge;`141` Chest;`143` Dice Battle;`151` Claw Machine;`164` Dicereel;`169` Lucky Scratch。
|
||||
|
||||
原作有 8 条 `isEnabled=true` 的 Corner:`125,126,127,128,129,131,167,175`。v0.2.8启用其中 `125,127,128,129,131`;`126` Piggy Bank、`167` Dice Catapult、`175` Warp 不进入首版。这是主动裁剪,不是原作禁用。
|
||||
|
||||
`129 Housing Support`落点时掷两枚独立D6,点数和为基础建设次数;实际建成数受下一条顺时针棋盘边的空闲外侧槽数量限制。每格外侧最多1栋,房屋不覆盖底层地块并持续到最终BOSS Floor。原作的房屋到点数换算尚未恢复,MVP冻结为每成功建成1栋获得1灵石。逐字段规则见[06-building-rules.csv](./06-building-rules.csv)。
|
||||
|
||||
原作 `169` 的自然生成门槛是 `minStage=1,minLoop=3`。为了在 Stage 0 玩法验证中实际覆盖 Lucky Scratch,首版验证配置将它覆盖为 `minStage=0,minLoop=0`;正式还原配置必须恢复原门槛。`143` 与 `164` 仍保留原作 `minLoop=3`,调试台可以强制触发。
|
||||
|
||||
### 2.2 Blessing
|
||||
|
||||
原作主模式启用 31 条祝福,基础 `prob_weight` 均为 10。首版候选池冻结为 28 条:
|
||||
|
||||
```text
|
||||
100,102,103,108,109,110,111,112,113,114,115,116,117,118,
|
||||
121,122,124,125,126,132,147,148,149,150,151,152,153,154
|
||||
```
|
||||
|
||||
首版关闭:
|
||||
|
||||
| Blessing ID | 原因 |
|
||||
| ---: | --- |
|
||||
| `106` | 复活系统未实现 |
|
||||
| `156`、`157` | Burn 状态链未实现;两条必须成对启用或关闭 |
|
||||
|
||||
`111 DoubleHeal`由实机确认保留。每层在Natural Double时恢复8%最大生命,重复获得按加法叠加;开发时必须绑定“最终骰子结算得到的Double事件”,不能仅凭UI文案轮询骰面。Forced Double默认不触发。
|
||||
|
||||
`152 Urban Planning / 都市计划`随建筑模块启用。它是不可叠加的唯一祝福,每次营造司事件在两骰点数和之外增加2次建设尝试,仍受合法外侧槽数量上限约束。
|
||||
|
||||
### 2.3 Shop
|
||||
|
||||
原作 96 条商品全部加载为只读目录,首版有 77 条进入运行时槽池:
|
||||
|
||||
| 类型 | 启用 Offer ID | 数量 |
|
||||
| --- | --- | ---: |
|
||||
| TILE | `100,104,106,108,110` | 5 |
|
||||
| AUGMENT | `112,113,114,116-140`,不含 `115,141,142` | 28 |
|
||||
| POTION | `143` | 1 |
|
||||
| STAT | `152-164` | 13 |
|
||||
| FIXED | `165-194` | 30 |
|
||||
| LOTTO | 无 | 0 |
|
||||
| 合计 | | **77** |
|
||||
|
||||
注意:Lucky Scratch `newtile ID 169` 在原作的 12 条 TILE 商品中没有对应 Offer,首版不得自行捏造一个“原作商品 ID”。它只能来自 Good 牌组、调试强制或之后明确新增的 MVP 商品。
|
||||
|
||||
普通商品没有“每买一次自动涨价”。价格上涨只存在于:
|
||||
|
||||
- 商店付费刷新:`3 + 2 × k`,即 3、5、7、9……;
|
||||
- 固定升级链:购买当前独立商品行后切换到下一级独立商品行;
|
||||
- 黑市:`base + trunc(base × surchargePercent / 100)`,其中百分比尚未知。
|
||||
|
||||
逐商品的价格、限购、固定槽顺序、启用状态与禁用原因见 [03-shop-product-whitelist.csv](./03-shop-product-whitelist.csv)。Tile、Corner 和 Blessing 的逐 ID 表见 [02-tile-corner-blessing-whitelist.csv](./02-tile-corner-blessing-whitelist.csv)。
|
||||
|
||||
## 3. 原作 / MVP 偏离 / DEMO 默认的使用规则
|
||||
|
||||
开发读取顺序必须是:
|
||||
|
||||
```text
|
||||
原作确认规则
|
||||
→ 若 05 表存在 intentional deviation,则用 MVP 规则覆盖
|
||||
→ 若原作参数仍 UNKNOWN,则只从 04 表读取一个 DEMO 默认值
|
||||
```
|
||||
|
||||
不能反向把 DEMO 默认值写回“原作规则”。几个最容易误写的项目如下:
|
||||
|
||||
| 系统 | 原作 | MVP / DEMO |
|
||||
| --- | --- | --- |
|
||||
| 玩家基础生命 | 500 | 100,主动偏离 |
|
||||
| 战斗节奏 | 实时自动冷却,各存活单位独立计时,间隔为`100/最终攻速` | v0.2.8统一采用原作模型,不再严格交替 |
|
||||
| 复活 | 原作存在祝福与相关路径 | 首版完全关闭 |
|
||||
| 药水 | 9 种商品 | 单一恢复丹药 |
|
||||
| Start 顺序 | 准备商店 → 刷新下一层 → 交互商店 → Heal | MVP 应按该顺序修正,不再沿用旧文本冲突 |
|
||||
| `enemyTilesPerLoop` | 字段确认、值未知 | 3,DEMO 默认 |
|
||||
| 建筑 | 两骰点数和为建设次数;原作奖励换算未知 | 外侧独立房屋层;每栋1灵石;都市计划+2次 |
|
||||
| Blessing | 原作 31 条 | 首版 28 条 |
|
||||
| Shop | 原作目录 96 条 | 首版槽池 77 条 |
|
||||
| Boss 中途装备 | 观察到,但阈值未知 | 50% 首次跨越,DEMO 默认 |
|
||||
| 黑市加价 | 公式确认,百分比未知 | 50%,DEMO 默认 |
|
||||
|
||||
完整28项对照见[05-original-vs-mvp-vs-demo.csv](./05-original-vs-mvp-vs-demo.csv)。
|
||||
|
||||
## 4. 未知参数默认表的边界
|
||||
|
||||
[04-unknown-parameter-mvp-defaults.csv](./04-unknown-parameter-mvp-defaults.csv)给出26个唯一执行值,包括:
|
||||
|
||||
- `enemyTilesPerLoop=3`;
|
||||
- 黑市加价 50%;
|
||||
- Boss压力采用进场50、每行动+25、满100后倒计时4回合;候选不足4格时不降级,延后转换;
|
||||
- 压力地块结算后变 Empty,不恢复被覆盖地块;
|
||||
- 战斗掉落展示容量10,第11件起先进先出替换最旧未处理掉落并给出明确反馈;
|
||||
- 商店 3 个随机槽等权、无放回;
|
||||
- Blessing 先过滤再等权无放回 3 选 1;
|
||||
- Boss 中途装备阈值 50%;
|
||||
- 普通怪死亡奖励 95:4:1;
|
||||
- 精英怪 1 件装备,再按 5:2 抽丹药或灵石;
|
||||
- Dice Battle 平局庄家胜;
|
||||
- Lucky Scratch 揭示完成阈值 65%;
|
||||
- Forge 最高升到 Myth,不从 Forge 进入 Arcane。
|
||||
- Housing Support每成功建成1栋获得1灵石;该值只属于DEMO默认。
|
||||
|
||||
这些值中有些适合调参,但在本版本必须只有一个默认值,不能让程序员自行猜测。调试台修改时也必须记录 seed、配置版本和修改项。
|
||||
|
||||
## 5. 证据与置信度
|
||||
|
||||
主要证据:
|
||||
|
||||
- [assembly-csharp.json](../../HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/metadata/assembly-csharp.json):类型、字段、方法 token;
|
||||
- [newtile.csv](../../HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/newtile.csv):Tile 启用、类型与门槛;
|
||||
- [augment.csv](../../HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/augment.csv):31 条启用 Blessing 与权重;
|
||||
- [ingameshoplist.csv](../../HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/ingameshoplist.csv):96 条商品;
|
||||
- [gameconfig.csv](../../HEROLL_APK_REVERSE_ONLY/01_core_reverse_archive/resource-tables/extracted/csv/gameconfig.csv):`LoopRatio=90,5,1`、`shopRerollCost=3,2` 等全局配置;
|
||||
- [E-STAGE-NATIVE-001.md](../../work/heroll-stage-2-5/evidence/E-STAGE-NATIVE-001.md):初始化与 `AddNextLoopTiles` 原生调用证据;
|
||||
- [stage-floor-rules report](../stage-floor-rules/2026-08-31_逆向-HEROLL关卡楼层分布与刷新规则-report.md):楼层、Good 牌组与 DiceGauge 压力闭环;
|
||||
- 运行时解密 `libil2cpp.so`:SHA-256 `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA`。
|
||||
|
||||
上面最后一行的哈希必须以 QA 脚本重新计算值为准;若与本机文件不一致,应停止地址复用。地址证据只对当前 HEROLL 2.0.1 样本有效。
|
||||
|
||||
本轮没有使用互联网资料。原因不是跳过检索,而是这四组问题都属于特定版本的私有配置与原生执行顺序;公开攻略无法比本地 APK 提供更强证据。无法从本地闭合的项目已经进入“未知参数 MVP 默认表”,没有用网络二手描述冒充源码结论。
|
||||
|
||||
## 6. 开发验收
|
||||
|
||||
1. 自动测试跨 Start 且带剩余步数:商店层必须先完成下一层注入,再打开商店,关闭后 Heal,最后继续移动。
|
||||
2. 最终Floor跨Start:不得调用普通Good/Enemy注入;保留`remainingSteps`;44格全部为Boss Tile;剩余步数为0时必须再Roll一次后入战。
|
||||
3. 对 `02` 白名单逐 ID 强制触发;任何未列入 ID 不得自然生成。
|
||||
4. 读取 `03` 的 96 行:目录必须全量加载,但只有 `mvp_enabled=true` 的 77 行能进入槽池。
|
||||
5. Blessing 候选池默认应为 28 条;依赖、唯一、叠加上限过滤在抽取前执行。
|
||||
6. 商店刷新仅刷新 3 个随机槽;固定槽不变;免费刷新不推进付费刷新计数。
|
||||
7. 所有 `04` 默认值必须可配置并带 `DEMO default` 标签;日志不可记录为 `source confirmed`。
|
||||
8. 强制触发`129`:验证两骰、`152`额外+2、无放回槽位选择、无空位分支、跨Floor持续与最终BOSS清理。
|
||||
Reference in New Issue
Block a user