diff --git a/CLAUDE.md b/CLAUDE.md index 1107bfd4..2773b0bb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,8 +20,8 @@ - 冒烟(全量 headless 断言):`python tools/run_smoke.py`(包装器三闸:退出码+摘要失败数+SCRIPT ERROR 扫描——脚本错误不计冒烟失败数且静默中断所在函数剩余断言,2026-09-19 台账 84 立闸)。底层命令 = `…console.exe --headless --path . --script res://smoke/smoke_all.gd` - 场景级探针(呈现层回归):`…console.exe --headless --path . res://smoke/ui_probe.tscn`;另有 `ui_tune_probe.tscn`(数值调整板)、`ui_click_probe.tscn`(合成鼠标事件行为探针) -- 调参期批量工具:`--script res://smoke/level_monte_carlo.gd`(关卡期望扫描)· `--script res://smoke/reward_expectation.gd`(奖励获取期望) -- 数值验证工具:`python tools/balance_verifier.py`(直入口基线带判定+零强化止步节点归因+营地循环爬升战役——采集端 `--script res://smoke/verifier_batch.gd`,报告落 `production/qa/`;元进度换算率标定与曲线调参的自动化评判面,2026-09-22 数值验证工具批) +- 调参期批量工具:`--script res://smoke/adventure_monte_carlo.gd`(全冒险期望扫描)· `--script res://smoke/reward_expectation.gd`(奖励获取期望)——单关直入口口径已退役(2026-09-23 用户拍板),通关率/难度类测量一律走全冒险(原 level_monte_carlo/level_debug 已删) +- 数值验证工具:`python tools/balance_verifier.py`(零强化冒险逐关条件通关率+止步节点归因+营地循环爬升战役——采集端 `--script res://smoke/verifier_batch.gd`,报告落 `production/qa/`;元进度换算率标定与曲线调参的自动化评判面,2026-09-22 数值验证工具批;直入口带判定随口径退役暂停,带重锚归曲线调参批) - 交付前验收 = smoke + 全部场景探针全绿(测试细则见 `docs/code-conventions.md`) ## Project Layout diff --git a/design/gdd/03-内容规模.md b/design/gdd/03-内容规模.md index 3e1437cd..34ce9ae4 100644 --- a/design/gdd/03-内容规模.md +++ b/design/gdd/03-内容规模.md @@ -12,7 +12,7 @@ |---|---|---|---| | 第一层 | 地精洞窟 | 分支节点图(战斗 / 随机道具 / 恢复点 / Boss 等节点型) | 已落地(正式序列首关) | | 第二层 | 幽暗地域 | 同一分支节点图模板复用,第二关深度轴行值填充 | 已落地(正式序列已生效) | -| 第三层 | 灰矮人矿城 | 同一分支节点图模板复用,第三关深度轴行值填充 | 已落地(正式序列已生效;测试直入口保留) | +| 第三层 | 灰矮人矿城 | 同一分支节点图模板复用,第三关深度轴行值填充 | 已落地(正式序列已生效) | 现行节点行集与行值读 `data/tables/level.tres`(registry 为准)。再扩关卡走扩展批流程:先填深度轴行值、再接正式序列推进,不新造节点链结构。 @@ -62,7 +62,7 @@ MVP 不加新状态;扩容走 status_effects.tres 加行 + registry 登记。 垂直切片阶段明确砍掉或推迟的内容,写在这里防止回潮: -- 更多关卡(N>3)——第三关已按扩展批流程落地(行集 + 测试直入口);三关正式序列已生效(冒险结构实现批 2026-09-21) +- 更多关卡(N>3)——第三关已按扩展批流程落地(行集);三关正式序列已生效(冒险结构实现批 2026-09-21),唯一试玩入口 = 完整冒险(单关测试直入口退役,2026-09-23 用户拍板) - 精英节点与词缀系统——只预留了字段位,不定义语义 - 地形变异扩展内容——首批四类型已落地,反制道具与全局作用域排 Alpha(2026-09-20 用户拍板) - 道具/增益之间的组合协同(遗物式联动) diff --git a/design/gdd/07-体验验证清单.md b/design/gdd/07-体验验证清单.md index 9ed0de76..bac582b8 100644 --- a/design/gdd/07-体验验证清单.md +++ b/design/gdd/07-体验验证清单.md @@ -95,4 +95,4 @@ - **Boss 战必须单独出列**(硬化行为变化——旧 Boss 承伤 84.8% 等读数全部作废)。 - 普通场承伤带、通关率基线全量重测(削弱续时 + 乘区接线 + 甲效量纲换装 + 充能退役 多变量叠加,禁与任何旧读数混算)。 - 旧读数作废清单:池触底免伤轮相关读数、硬化翻倍期全部战斗读数、乏力死效果期格面调研读数、充能期(三分量输出)全部战斗读数。 -- 工具就位:`analyze_playtest.py`(反事实分析,吃新日志)、`level_monte_carlo`(MC 基线重跑)、JSONL 日志含池值与快照。 +- 工具就位:`analyze_playtest.py`(反事实分析,吃新日志)、MC 基线重跑走 `balance_verifier.py` 冒险段(原 level_monte_carlo 随单关直入口口径退役,2026-09-23)、JSONL 日志含池值与快照。 diff --git a/design/gdd/systems/冒险循环/冒险结构.md b/design/gdd/systems/冒险循环/冒险结构.md index 70160fd8..0da4a2df 100644 --- a/design/gdd/systems/冒险循环/冒险结构.md +++ b/design/gdd/systems/冒险循环/冒险结构.md @@ -170,7 +170,7 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗 重开 = 全新一轮冒险:注入新主种子、从第一关、满血、空手——不是"重打刚才那一关"。上一局清零的是生命账本、库存与种子;唯一保留面是冒险摘要,它给每次死亡一个可对照的坐标("这局到第二层"),重开因此是新局面而不是复读。 -主动放弃按与失败同型结算:已获得的大奖励不追回、已到手的保留,摘要标记未打穿。放弃请求只在非战斗期受理,战斗进行中一律拒绝(战斗域单事务在飞)。放弃的界面入口挂在[关卡节点地图](关卡节点地图.md)的选路覆盖层上——选路停点天然是非战斗期,按钮只在冒险模式开放(单关测试直入口没有可放弃的冒险对象);战斗进行中没有选路停点,入口因此天然不可达,拒绝分支仅作防御兜底。 +主动放弃按与失败同型结算:已获得的大奖励不追回、已到手的保留,摘要标记未打穿。放弃请求只在非战斗期受理,战斗进行中一律拒绝(战斗域单事务在飞)。放弃的界面入口挂在[关卡节点地图](关卡节点地图.md)的选路覆盖层上——选路停点天然是非战斗期,按钮只在冒险模式开放(选路覆盖层只在冒险模式出现);战斗进行中没有选路停点,入口因此天然不可达,拒绝分支仅作防御兜底。 主种子(本文含义:冒险开始时注入的一个随机种子,本局全部随机性都派生自它)在冒险开始时注入恰一次。冒险内的雷图生成、奖励抽取、遭遇掷骰与 GP 掉落掷定(消费 gp_drop 封闭流)全部派生自它,冒险内不重置、不逐关播种——早期切片"每关开局各自播种"是没有冒险层时的历史简化,已改写为全冒险单一种子。冒险的可复现域 = 主种子 + 各随机流计数器,供复盘与快照(见[存档序列化](../表现与支撑/存档序列化.md))。重开抽到的种子与上一局相同是允许的(随机源范围小,撞种子不算错误),但生成新种子不得复用玩法里的随机数。 @@ -263,7 +263,7 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗 - 收束次序:通关宣布到达时库存已被关卡节点地图先行清空;重复的关卡结束宣布被拒绝,账本与摘要零变化。 - 覆盖义务:冒烟断言——行集内每个战斗与关底节点(关、深)在敌人与棋盘生成的数值表中有精确行;序列关数 = 行集关数。 - 生效前提未兑现(第二关行缺行):以单关冒险运行(合法态),两关断言显式跳过而非失败。 -- 放弃:战斗中的放弃请求被拒绝;非战斗期放弃按失败同型结算,已获大奖励不追回;放弃入口仅在选路停点呈现且只在冒险模式开放(单关测试直入口无放弃按钮)。 +- 放弃:战斗中的放弃请求被拒绝;非战斗期放弃按失败同型结算,已获大奖励不追回;放弃入口仅在选路停点呈现且只在冒险模式开放。 - 种子域:冒险内零随机流自开,一切随机派生自主种子(含 GP 掉落掷定的 gp_drop 封闭流);同种子同操作序列两局逐位可复现。 - GP 账本封闭:钱包只有三个收口——战斗完成入账恰一次(掉落掷定 + 关级加值 + 战斗内缓冲合计)、商店购买出账、冒险收束清零;战斗内缓冲与钱包隔离,战斗进行中钱包零变动。 - GP 不留痕:GP 不入存档、不入冒险摘要;重开后钱包从零开始。 @@ -284,3 +284,4 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗 | v0.5 | 2026-09-20 | **GP+商店房批(用户拍板——与关卡节点地图 v1.1 / 战斗结算 v0.23 / 地图战斗资源 v0.15 / 难度曲线与Boss v0.18 / registry / 切片同批)**:① 新增「GP 冒险账本」节——钱包三收口(战斗完成统一入账 / 商店购买出账 / 冒险收束清零)+ 战斗内缓冲隔离语义(格面兑付入缓冲、战斗完成统一到账、战斗域零钱包状态);② 统一冒险加算区成文——商店购买与关卡大奖励上限提升同一本账(三轴 {攻击, 生命上限, 护甲等级},经覆盖值通道生效;购血 = 上限与当前生命同步 +Δ);③ GP 掉落掷定消费 gp_drop 封闭随机流(主种子派生)登记进主种子节与调参表;④ GP 不入存档、不入冒险摘要;范围表 / 大奖励表 / 依赖表 / 验收标准同步。数值全 provisional-pending-曲线调参批,行值读 shop.tres | | v0.6 | 2026-09-21 | **冒险结构实现批落地登记(切片 AdventureRunner + LevelRunner 账本外置 + AdventureTable 建表——与切片代码 / registry / 03 / 06 / roadmap 同批)**:本批只记实现批状态,正文规则口径零改动。落地面 = 三关正式序列生效(首页「开始冒险」)、接口契约四件套正式侧承载(开始关卡 start_level_external / 战斗结果上报共享账本直写 / 治疗封顶回报 apply_rest / 关卡结束 level_finished)、生命账本与 GP 冒险账本上交冒险结构层、大奖励非末关恰兑付一次(末关钥石照记)、冒险摘要五件事产出、主种子恰一次注入(registry rng_service new_adventure 调用权同批登记)、结算受理只算一次;06 待办「两关序列未生效」「切片行进代码与定稿的接口漂移」「冒险表未建表」三条随批解决移除。**规划书冲突按代码为准登记两处**:①大奖励 `_pending_next_level` 置位先于 emit(信号同步派发——处理器内立即确认需标记已就位);②放弃受理补 state=running 守卫(契约 7 结算受理只算一次的 abandoned 侧对齐) | | v0.7 | 2026-09-21 | **放弃入口界面呈现批(用户拍板「放弃接口也要有」——台账 119,推翻本文原「MVP 无界面入口、呈现后置」条款)**:① 放弃入口挂[关卡节点地图](关卡节点地图.md)选路覆盖层(选路停点 = 天然非战斗期;战斗中拒绝转为防御兜底分支——入口在战斗期不可达);② 入口只在冒险模式开放,单关测试直入口没有可放弃的冒险对象;③ 正文改现行口径(放弃节 / 验收标准放弃条),P1 后置表「放弃入口的界面呈现」随落地移除(同表「两关序列生效」系 v0.6 已落地漏收口,顺手同口径移除);④ 验收闸 = ui_probe 三断言(默认隐藏 / 冒险模式可见 / 首战中按下被拒 state 保持 running)+ 冒烟既有放弃两态 API 断言 | +| v0.8 | 2026-09-23 | **单关测试直入口退役(用户拍板——唯一试玩入口 = 完整三关冒险)**:正文改现行口径两处(放弃节「按钮只在冒险模式开放」的理由从「单关直入口无冒险对象」改为「选路覆盖层只在冒险模式出现」;验收标准放弃条同步去单关直入口从句)——放弃语义对象(整局冒险)与拒绝分支零改动。版本历史行(v0.7)按 ADR 纪律不回改 | diff --git a/design/gdd/systems/冒险循环/难度曲线与Boss.md b/design/gdd/systems/冒险循环/难度曲线与Boss.md index 27835a46..cff274b9 100644 --- a/design/gdd/systems/冒险循环/难度曲线与Boss.md +++ b/design/gdd/systems/冒险循环/难度曲线与Boss.md @@ -112,7 +112,7 @@ MVP 行值并不逐式现算,而是按此式量级直填经切片验证过的 | 带 | 定稿口径 | 含义 | |---|---|---| -| 基线通关率带 | 基线档(无元进度加成)通关率:**第 1 关 ∈ [35%, 55%]、第 2 关 ∈ [25%, 45%]**(2026-09-20 用户拍板分带——旧带 [10%, 25%] 随普通画像换装基础定式后失锚作废:旧带锚定的是随机点击画像,基础定式+引导后玩家的真人体验换算(模拟 47%/34% 对应真人约六成/五成)反推落此;更早的 [30%, 50%] 系随机画像口径亦作废) | 首关吃紧但多数玩家数局内能过;第二关明显更难;与完美档带 [35%, 65%] 错开一档留出元进度爬升空间 | +| 基线通关率带 | ⚠ 测量口径退役待重锚(2026-09-23 用户拍板单关直入口口径退役):原带 **第 1 关 ∈ [35%, 55%]、第 2 关 ∈ [25%, 45%]** 锚定直入口单关读数(满血零上下文进关)——与真实冒险的条件通关率脱节(实证:直入口 L2 普通 5% vs 营地检查点 L2 条件 90% 同期并存),逐关读数改冒险条件口径派生(balance_verifier 冒险段),旧带值不可比;新带重锚归曲线调参批,重锚前只测不判(原带推导史:2026-09-20 分带批,更早 [10%, 25%]/[30%, 50%] 系随机画像口径先后作废) | 首关吃紧但多数玩家数局内能过;第二关明显更难;与完美档带错开一档留出元进度爬升空间——重锚时按此设计意图在新口径上取值 | | 通关余量带 | 通关者通关时剩余生命的 p90 / p10 按现生命轴上限百分比表达(压缩前绝对血量带已作废;界值重标随验收批) | **通关余量** = 通关瞬间还剩多少血。余量太肥说明赢得太从容,压生存侧;太瘦说明"剩一两滴血惨胜"成常态,抬治疗供给或恢复点收益 | | 第一关形态带 | 教学位绿档 + 中段黄档 + Boss 黄档不红 | **形态带**管一关内各战三档判定的排布形状:第一战必须稳过,中段有输的可能,Boss 战紧但不许是配置事故 | @@ -281,7 +281,7 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 - 零红档:全部行集经区间扫描,不存在"最好情况也打不过"的战斗组合。 - 教学位绿档:第一关第一战与各新敌种首遇位的区间判定为绿档。 - 形态带成立:第一关形态 = 教学位绿 + 中段黄 + Boss 黄不红。 -- 通关率带:基线档通关率第 1 关 ∈ [35%, 55%]、第 2 关 ∈ [25%, 45%](2026-09-20 用户拍板分带,旧带 [10%, 25%] 作废——随机画像口径失锚)——重投基线读数 L1 47%/L2 34% 落带(2026-09-20,N=300/画像,production/qa/mc-reinvest-baseline-2026-09-20.md)。 +- 通关率带:⚠ 口径退役待重锚(2026-09-23)——原带第 1 关 ∈ [35%, 55%]、第 2 关 ∈ [25%, 45%](2026-09-20 分带批)锚定直入口单关读数,该口径随单关试玩入口一并退役;逐关读数改冒险条件口径(balance_verifier 报告①),新带值重锚归曲线调参批,重锚前只测不判(旧重投读数 L1 47%/L2 34% 系直入口口径,production/qa/mc-reinvest-baseline-2026-09-20.md 留档不作判据)。 - 通关余量带:通关者剩余生命 p90 / p10 按现生命轴上限百分比表达,界值重标随验收批。 - 恒等式闭合:关级通关恒等式逐项对账闭合,残差 <5%(provisional 阈值);奖励输出占比 ∈ [15%, 40%]。 - Boss 锚在案:每个 Boss 行的血量锚比率记录在案且落在现行带内;越带须登记,不静默变更。 @@ -315,3 +315,4 @@ Boss 战的棋盘用本关最大板形(板形行值读棋盘参数表),板 | v0.16 | 2026-09-20 | **基线通关率带分带批 + MC 重投基线(用户拍板方案 A;台账 105〔登记时撞并行会话 103 号,顺延让号〕)**:① 基线通关率带由单一 [10%, 25%] 改为分带——第 1 关 [35%, 55%] / 第 2 关 [25%, 45%]:旧带锚定随机点击画像,普通画像换装基础定式后失锚;推导链 = 真人体验换算(模拟 47%/34% 对应真人新手约六成/五成)+ 与完美档带 [35,65] 错开一档保留元进度爬升空间;② MC 重投基线(N=300/画像/关 · unique · seed0=7000):完美档 55.7%/39.7% 落 [35,65]、普通档 46.7%/34.3% 落新带——双画像双关全落带,加难紧迫性解除;③ 残留越带唯一项 = L2 完美 Boss 承伤 51.6%(微越 1.6 点,归调参批);④ 报告 production/qa/mc-reinvest-baseline-2026-09-20.md;工具 level_monte_carlo.gd 增 baseline 参数 + F5 脚注随带同步 | | v0.17 | 2026-09-20 | **第三关内容批(灰矮人矿城——与切片代码 / registry / 03-内容规模 / 棋盘生成 / 地形变异 同批,存量行值零改动)**:调参表新增第三关图版注记——敌种生态(灰矮人 duergar 单体重甲中坚 + 钩爪恐魔 hook_horror 群行复用撕咬 + Boss 灰矮人石君王 duergar_king 专属池独占妨害技大地脉动 = 乏力 sapped 第二妨害词汇首发)、首遇位节点 0/1 固定数量不加骰、克制面重轻错开(重甲首次登台,教学梯度轻→魔→重在 L3 补完)、Boss 血量锚 75 = Σ91 × r_boss≈0.82、棋盘 13×13 / Boss 14×14 密度 0.25 维持、地形落石 3 点 + 矿尘、armor_class 恒 0(正式投值仍归在案条目全表同批);期望值带节补 L3 口径——行值 provisional-pending-growth,零成长基线红档属预期、冒烟首遇绿档按成长代理档(atk+200 / hp+100)口径,正式通关率带与首遇绿档口径随 L3-A 玩家成长批(GP + 商店房)换装,归曲线调参批统一收带 | | v0.18 | 2026-09-20 | **GP+商店房批(用户拍板"骨架先行、数值整体后置"——与 关卡节点地图 v1.1 / 冒险结构 v0.5 / 战斗结算 v0.23 / 地图战斗资源 v0.15 / registry / 切片同批,行值零改动)**:① 新增「商店与 GP 经济杠杆」节——GP 供给 × 商品定价 = 第三族玩家侧杠杆(掉落均值±方差 / 关级掉落加值 / 关级价格加成 / 首价与步长,全部读 shop.tres provisional-pending-曲线调参批),定价锚定口径 = 正常运气与运气极好可购档数的数学期望(期望账进商店表批注);② 分层验收 defer 成文——shop=off/on 双格 MC、shop=on 带平移、换算率登记全部随曲线调参批执行(与「基线通关率越带」「L2 Boss 承伤微越带」「大奖励数值联动」同窗),执行前 shop=on 只登记不判读;③ L3 首遇绿档成长代理档口径不变;④ 调参联动表 +GP 供给↔商品定价行、调参表 +shop.tres 行、验收标准 +杠杆在案条目 | +| v0.19 | 2026-09-23 | **基线通关率带测量口径退役(用户拍板单关直入口口径退役——与单关试玩入口退役同批)**:原带(第 1 关 [35,55] / 第 2 关 [25,45],v0.16 分带批)锚定直入口单关读数——满血零上下文进关,与真实冒险的条件通关率脱节(实证:直入口 L2 普通 5% 与营地检查点 L2 条件 90% 同期并存,曾误导曲线调参)。逐关读数改冒险条件口径(balance_verifier 冒险段派生:通关数/到达数);新带值重锚归曲线调参批,重锚前只测不判;调参表「基线通关率带」行与验收标准通关率带条同步改口径退役注记。行值零改动 | diff --git a/design/gdd/systems/表现与支撑/存档序列化.md b/design/gdd/systems/表现与支撑/存档序列化.md index 15421ca8..5a6e8948 100644 --- a/design/gdd/systems/表现与支撑/存档序列化.md +++ b/design/gdd/systems/表现与支撑/存档序列化.md @@ -95,7 +95,7 @@ SaveManager 不依赖任何玩法系统就能工作:它是被动的承载方 写盘是原子操作:先写临时文件(`<路径>.tmp`),写完改名覆盖正式档——写一半断电不留烂档。 -单局测试入口不写档:关卡直入口(L2/L3)与调试两层路径不接写盘——测试模式不污染生涯数据;只有正式冒险(AdventureRunner)收束才入账。 +单局测试入口不写档:调试两层与 headless 单关测试路径(LevelRunner.start_level,仅 QA 工具使用)不接写盘——测试模式不污染生涯数据;只有正式冒险(AdventureRunner)收束才入账。 ### 版本与迁移 @@ -157,3 +157,4 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单 |---|---|---| | v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) | | v1.0 | 2026-09-21 | **存档序列化批(SaveManager 落地)**:格式裁决 JSON 单档 `user://save.json`;数据模型逐域成文(元进度四件 + 最近冒险摘要 cap 10);读写时机(启动读盘/冒险收束写盘/营地即时写/测试入口不写)+ tmp+rename 原子写;版本策略(高版本拒读禁写/低版本链式迁移/缺域补齐);损坏兜底(.corrupt.bak 备份 + 默认新档);待设计问题清单六条全部裁决成文(1/2/3/5/6 入核心规则,4 = 单档 MVP 多档留 P2)。自范围草案升定稿 | +| v1.1 | 2026-09-23 | 单关测试直入口(L2/L3)退役(用户拍板——唯一试玩入口 = 完整冒险):不写档条款改口径为「调试两层与 headless 单关测试路径(LevelRunner.start_level,仅 QA 工具)」;写盘面零改动(正式冒险收束唯一写档点不变) | diff --git a/design/registry/entities.yaml b/design/registry/entities.yaml index 708f88c1..8b3b10d4 100644 --- a/design/registry/entities.yaml +++ b/design/registry/entities.yaml @@ -77,7 +77,7 @@ entities: format: JSON 单档(人可读可调试;字典键一律 String) version: SAVE_FORMAT_VERSION=1(registry schema_version 同源;高版本拒读 + 禁写盘 + 内存默认新档运行;低版本读档时链式迁移 register_migration,任一步失败按损坏兜底) domains: meta 域六件——keystone_balance(内容 owner=元进度)/ forge_levels 三档 max_hp·atk·armor_class(元进度)/ item_unlocks(元进度·道具工坊消费)/ level_clear_counts(元进度)/ boss_first_kill(元进度)/ recent_summaries cap 10 冒险摘要五件事副本(内容 owner=冒险结构;元素附 boss_drops 副本——Boss 两档金额入账随元进度实现批 2026-09-21 接通,apply_adventure_summary 第二参) - write_timing: 启动读盘;正式冒险收束(adventure_finished → apply_adventure_summary)写盘;营地每笔钥石变更后即时写(元进度实现批接线);单关测试入口与调试两层不写档 + write_timing: 启动读盘;正式冒险收束(adventure_finished → apply_adventure_summary)写盘;营地每笔钥石变更后即时写(元进度实现批接线);调试两层与单关测试路径(LevelRunner.start_level,仅 QA 工具)不写档 atomic_write: tmp + rename 原子写(写一半断电不留烂档——钥石不丢判据承载) corruption_policy: 坏档改名 .corrupt.bak(已存在覆盖)+ 默认新档继续 + 警告留痕(不静默丢档不 crash) domain_boundary: 行动点/RAP/道具库存/生命账本/GP 不入档(局内资源单局清零;冒烟断言承载) @@ -528,9 +528,9 @@ entities: owner: design/gdd/systems/冒险循环/难度曲线与Boss.md attributes: kind: 调参目标带(F5)+ 承伤估算(F4)+ 供给平衡式(F6)——设计期工具式,运行时零新增公式(难度曲线与Boss 定位声明) - clear_rate_target: L1 基线 **10-25%**(2026-09-17 数值纪律收口批用户拍板——旧 30-50% 带作废,乱点玩家画像不真实、引导后玩家逼近完美策略;压缩批后旧扫描读数 60% 系旧带旧值链口径、已失效,重测随验收批另批登记)/ L2 20-40% / L3+ 10-25%(中高加成带见 GDD F5 表——区间位移机制承载:atk 翻倍 ≈ K 减半 → 绿档;2026-09-18 起永久强化经换算率表按带平移接入,见 meta_progression_conversion_table) + clear_rate_target: ⚠ 口径退役待重锚(2026-09-23 用户拍板单关直入口口径退役——逐关读数改冒险条件口径派生〔balance_verifier 冒险段〕,带值重锚归曲线调参批,重锚前只测不判;带史 = 2026-09-20 分带批 L1 [35,55]/L2 [25,45] 锚定直入口单关读数〔已随口径退役不可比〕,更早 L1 10-25/L2 20-40 系乱点画像口径亦作废;区间位移机制承载:atk 翻倍 ≈ K 减半 → 绿档;2026-09-18 起永久强化经换算率表按带平移接入,见 meta_progression_conversion_table) supply_balance_band: "**关级供给带 [1.1,2.0] 退役(2026-09-14——其验算 0.54 与实测 60% 通关矛盾)**——由生存链区间模型替代:每战 S/K 区间三档判定(绿 S_min>K_max / 黄 E[S]≥E[K]+1 / 红 S_max≤K_min 禁止入表)+ 关级恒等式(atk×ΣR_survive + Σ奖励输出 ≈ Σ敌hp期望×(1+缓冲),actuals 逐项审计闭合)+ 输出占比带 [15%,40%] + 通关余量带(p90≤13 & p10≥3——'通关只剩一点血'量化)" - tool_carrier: level_monte_carlo.gd / reward_expectation.gd(切片原型→难度曲线与Boss 期正式批量工具,棋盘生成 F4 排期倒挂解除载体) + tool_carrier: balance_verifier.py 冒险段(逐关条件通关率/止步归因/营地循环——2026-09-23 起难度读数主载体)/ adventure_monte_carlo.gd / reward_expectation.gd(原 level_monte_carlo.gd 随单关直入口口径退役删除 2026-09-23;棋盘生成 F4 排期倒挂解除载体) calibration_gap: 真人修正系数待 playtest 标定(OQ3——**方向已由试玩批次 1 反向确认:真人显著强于模拟者**〔v2 真人 100% vs 模拟 80%〕;旧"真人预期低于模拟"方向声明由本条替代;带按模拟口径定义,真人系数批次 2 定量) referenced_by: [地图战斗资源, 战斗结算, 冒险结构, 元进度] @@ -555,7 +555,7 @@ entities: nodes: 节点图结构——节点数组 + 连线(node_kind ∈ {battle, reward, rest, boss, shop},切片字段名 type;+shop 随 2026-09-20 GP+商店房批——商店房兑付 = 打开商店覆盖层、离开后确认回选路,不携带战斗行〔零敌人、零棋盘配置行〕;每节点领关卡内唯一**节点编号**,battle/boss 数据键 node_depth 沿用〔v1.0 语义升级:深度 → 节点编号〕;连线 = 出边节点编号表,只朝前进方向、无回头路);单链特例 = 隐式后继(数组序即链,切片现行形态零漂移) rowset_rule: 图合法性校验(2026-09-17 关卡节点地图 v1.0)——节点编号关卡内唯一、入口唯一、Boss 恒唯一终点(编号最大,Dmax 语义平移)、连线无环、所有节点沿连线可达 Boss,违规加载期致命;实现批(2026-09-17 分支节点图批):校验落 LevelTable.validate(单链形态经同一套算法——编号解析单链 = 数组下标 / 图 = node_depth),L1 单链与 L2 图双行集加载全绿断言;商店房编排(每关恰 1、Boss 前一位必经位)由冒烟断言承载、非加载校验——图合法性六检零新增(GP+商店房批 2026-09-20,关卡节点地图 v1.1) cross_table_validation: battle/boss 节点 (L,D) 在 board_gen/enemy 两表存在精确行(数据配置 跨表校验⑧复用 + 冒险结构 AC-7 冒烟断言——序列关数 ⊆ 内容覆盖,越界关卡 = 内容生产缺口) - mvp_content: L1 全行(切片转正——7 节点链〔单链特例,合法图形态〕、rest_heal_pct=30);L2 全行已落地(2026-09-17 分支节点图批——首张分支图:9 节点〔入口 0 → 中间三层 2/3/2 → Boss 8〕、真实岔路 4 处、奖励点+恢复点各 1、战斗节点 6 + Boss;行值 provisional 归 难度曲线与Boss v0.7;首页直入口试玩模式保留);**L3 全行已落地(2026-09-20 第三关内容批——「第三层 · 灰矮人矿城」:九节点图复用 L2 同模板〔6 战 + Boss + 奖励 + 恢复、真实岔路 4 处〕,行值全 provisional 归 难度曲线与Boss;测试直入口保留)**;2026-09-20 GP+商店房批 rewiring:L2/L3 图版 Boss 重编号 8→9、各新增 (8, shop, next[9]) 商店房节点(Boss 前一位必经位),L1 零改动,图合法性六检零新增——必经位由冒烟断言承载;**2026-09-21 冒险结构实现批:三关正式序列生效**(首页「开始冒险」= L1→L2→L3 连探,AdventureRunner 编排——大奖励/生命账本/GP 冒险账本/主种子归冒险结构层,冒烟断言在案)** + mvp_content: L1 全行(切片转正——7 节点链〔单链特例,合法图形态〕、rest_heal_pct=30);L2 全行已落地(2026-09-17 分支节点图批——首张分支图:9 节点〔入口 0 → 中间三层 2/3/2 → Boss 8〕、真实岔路 4 处、奖励点+恢复点各 1、战斗节点 6 + Boss;行值 provisional 归 难度曲线与Boss v0.7;首页直入口已退役〔2026-09-23 用户拍板〕);**L3 全行已落地(2026-09-20 第三关内容批——「第三层 · 灰矮人矿城」:九节点图复用 L2 同模板〔6 战 + Boss + 奖励 + 恢复、真实岔路 4 处〕,行值全 provisional 归 难度曲线与Boss;测试直入口已退役〔2026-09-23〕)**;2026-09-20 GP+商店房批 rewiring:L2/L3 图版 Boss 重编号 8→9、各新增 (8, shop, next[9]) 商店房节点(Boss 前一位必经位),L1 零改动,图合法性六检零新增——必经位由冒烟断言承载;**2026-09-21 冒险结构实现批:三关正式序列生效**(首页「开始冒险」= L1→L2→L3 连探,AdventureRunner 编排——大奖励/生命账本/GP 冒险账本/主种子归冒险结构层,冒烟断言在案)** referenced_by: [冒险结构, 关卡节点地图, 难度曲线与Boss, 棋盘生成, 数据配置] - name: adventure_table diff --git a/docs/code-conventions.md b/docs/code-conventions.md index 6b6e2282..6bda2ea3 100644 --- a/docs/code-conventions.md +++ b/docs/code-conventions.md @@ -118,7 +118,7 @@ ("可选类 3.32"不加"每板",会被读成每格期望 >1)。 ### 5.2 调参先测量,改后复测 -改任何玩法数值前,先用扫描工具产出基线(`level_monte_carlo.gd` / `reward_expectation.gd`); +改任何玩法数值前,先用扫描工具产出基线(通关率/难度类读数走 `balance_verifier.py` 冒险段——单关直入口口径已退役,机制类读数走 `reward_expectation.gd` 等); 改完必须复测回填数据。禁止拍脑袋调参。 ### 5.3 数值设计必须跨尺度推演 diff --git a/production/qa/balance-verifier-20260923-043341.md b/production/qa/balance-verifier-20260923-043341.md new file mode 100644 index 00000000..52e8938a --- /dev/null +++ b/production/qa/balance-verifier-20260923-043341.md @@ -0,0 +1,105 @@ +# 数值验证报告(20260923-043341) + +- 采集规模:直入口每格 100 局 · 基线冒险 60 局/画像 · 战役 60 局/画像 · 种子 8000 起逐局独立 · 锻造花费策略 = hp_first +- 切片版本:3309aae · 表状态:判定带与表值溯源见 tools/balance_verifier.py 文件头 + +## ① 直入口基线通关率(验收带判定) + +| 层 | 画像 | 通关/局数 | 通关率±95%CI | 验收带 | 判定 | +|----|------|-----------|--------------|--------|------| + +## ② 零永久强化冒险:止步分布与败退节点(用户判据③) + +### 普通档(60 局) + +- 止步分布:止步第1层 29(48%)、止步第2层 26(43%)、止步第3层 5(8%) +- 第一层通过率(冒险口径交叉核对):51.7% +- 败退节点分布(失败局归因): + - 第二层·节点9·Boss ×13 + - 第一层·节点4·战斗 ×12 + - 第一层·节点6·Boss ×12 + - 第二层·节点1·战斗 ×8 + - 第一层·节点3·战斗 ×5 + - 第二层·节点6·战斗 ×4 + - 第三层·节点1·战斗 ×3 + - 第二层·节点0·战斗 ×1 + - 第三层·节点9·Boss ×1 + - 第三层·节点0·战斗 ×1 + +### 完美档(60 局) + +- 止步分布:止步第1层 6(10%)、止步第2层 41(68%)、止步第3层 13(22%) +- 第一层通过率(冒险口径交叉核对):90.0% +- 败退节点分布(失败局归因): + - 第二层·节点9·Boss ×25 + - 第二层·节点1·战斗 ×13 + - 第三层·节点1·战斗 ×7 + - 第一层·节点4·战斗 ×6 + - 第三层·节点9·Boss ×3 + - 第二层·节点6·战斗 ×3 + - 第三层·节点0·战斗 ×2 + - 第三层·节点6·战斗 ×1 + +## ③ 营地循环爬升(用户判据④:5 次通关 → 下一层可过) + +### 普通档(60 局战役) + +- 钥石:全程入账 1614 · 终态余额 153 · 锻造终态 = 生命+21/攻击+6/护甲+6 +- 道具工坊解锁时点(魔法道具面,局内效果未实装只报不判):显影尘 第 2 局、工兵令 第 2 局、探宝罗盘 第 4 局、探巢摆钟 第 4 局、地穴全图卷 第 5 局、爆破工兵包 第 5 局 + +- 判据:累计通过第一层 5 次后,第二层条件通关率(滑窗 10 局)——越上界(高于 45% 达 25.0 点)(触发时注入 = 生命+6/攻击+1/护甲+0) +- 判据:累计通过第二层 5 次后,第三层条件通关率(滑窗 10 局)——带未定(只测不判)(触发时注入 = 生命+9/攻击+2/护甲+2) + +| 局 | 注入(flat) | 钥石 | 第1层率(窗) | 第2层率(窗) | 第3层率(窗) | 终局 | +|--------|--------------|------|-------------|-------------|-------------|-----------| +| 第1局 | 血0/攻0/甲0 | 0 | 0%(n=1) | — | — | 止步第1层 | +| 第4局 | 血0/攻0/甲0 | 6 | 50%(n=4) | 0%(n=2) | — | 止步第2层 | +| 第7局 | 血6/攻0/甲0 | 7 | 71%(n=7) | 20%(n=5) | — | 止步第2层 | +| 第10局 | 血6/攻1/甲0 | 7 | 60%(n=10) | 33%(n=6) | 50%(n=2) | 通关 | +| 第13局 | 血9/攻2/甲1 | 10 | 80%(n=10) | 44%(n=9) | 75%(n=4) | 通关 | +| 第16局 | 血9/攻2/甲2 | 0 | 80%(n=10) | 60%(n=10) | 50%(n=6) | 止步第3层 | +| 第19局 | 血12/攻2/甲2 | 12 | 100%(n=10) | 70%(n=10) | 38%(n=8) | 止步第3层 | +| 第22局 | 血12/攻3/甲3 | 36 | 100%(n=10) | 80%(n=10) | 30%(n=10) | 止步第3层 | +| 第25局 | 血12/攻4/甲3 | 26 | 100%(n=10) | 80%(n=10) | 10%(n=10) | 止步第3层 | +| 第28局 | 血12/攻4/甲4 | 41 | 100%(n=10) | 90%(n=10) | 10%(n=10) | 通关 | +| 第31局 | 血12/攻4/甲4 | 23 | 100%(n=10) | 90%(n=10) | 20%(n=10) | 通关 | +| 第34局 | 血15/攻4/甲4 | 31 | 100%(n=10) | 100%(n=10) | 50%(n=10) | 通关 | +| 第37局 | 血15/攻5/甲5 | 39 | 100%(n=10) | 100%(n=10) | 80%(n=10) | 通关 | +| 第40局 | 血15/攻5/甲5 | 134 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第43局 | 血18/攻5/甲5 | 79 | 100%(n=10) | 100%(n=10) | 80%(n=10) | 通关 | +| 第46局 | 血18/攻6/甲5 | 37 | 100%(n=10) | 100%(n=10) | 80%(n=10) | 通关 | +| 第49局 | 血18/攻6/甲5 | 145 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第52局 | 血18/攻6/甲6 | 90 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第55局 | 血18/攻6/甲6 | 198 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第58局 | 血21/攻6/甲6 | 81 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | + +### 完美档(60 局战役) + +- 钥石:全程入账 1922 · 终态余额 11 · 锻造终态 = 生命+21/攻击+7/护甲+7 +- 道具工坊解锁时点(魔法道具面,局内效果未实装只报不判):显影尘 第 1 局、工兵令 第 1 局、探宝罗盘 第 2 局、探巢摆钟 第 2 局、地穴全图卷 第 2 局、爆破工兵包 第 2 局 + +- 判据:累计通过第一层 5 次后,第二层条件通关率(滑窗 10 局)——越上界(高于 65% 达 25.0 点)(触发时注入 = 生命+9/攻击+1/护甲+0) +- 判据:累计通过第二层 5 次后,第三层条件通关率(滑窗 10 局)——带未定(只测不判)(触发时注入 = 生命+9/攻击+3/护甲+0) + +| 局 | 注入(flat) | 钥石 | 第1层率(窗) | 第2层率(窗) | 第3层率(窗) | 终局 | +|--------|--------------|------|-------------|-------------|-------------|-----------| +| 第1局 | 血0/攻0/甲0 | 15 | 100%(n=1) | 0%(n=1) | — | 止步第2层 | +| 第4局 | 血3/攻1/甲0 | 8 | 100%(n=4) | 50%(n=4) | 0%(n=2) | 止步第3层 | +| 第7局 | 血9/攻2/甲0 | 12 | 100%(n=7) | 57%(n=7) | — | 止步第2层 | +| 第10局 | 血9/攻3/甲1 | 12 | 100%(n=10) | 70%(n=10) | 43%(n=7) | 通关 | +| 第13局 | 血9/攻3/甲3 | 62 | 100%(n=10) | 90%(n=10) | 50%(n=10) | 止步第3层 | +| 第16局 | 血12/攻3/甲3 | 10 | 100%(n=10) | 90%(n=10) | 50%(n=10) | 止步第3层 | +| 第19局 | 血12/攻4/甲4 | 38 | 100%(n=10) | 100%(n=10) | 60%(n=10) | 通关 | +| 第22局 | 血12/攻4/甲4 | 33 | 100%(n=10) | 100%(n=10) | 50%(n=10) | 通关 | +| 第25局 | 血15/攻5/甲4 | 28 | 100%(n=10) | 100%(n=10) | 60%(n=10) | 止步第3层 | +| 第28局 | 血15/攻5/甲4 | 23 | 100%(n=10) | 100%(n=10) | 70%(n=10) | 通关 | +| 第31局 | 血15/攻5/甲5 | 118 | 100%(n=10) | 100%(n=10) | 70%(n=10) | 止步第3层 | +| 第34局 | 血18/攻5/甲5 | 76 | 100%(n=10) | 100%(n=10) | 70%(n=10) | 通关 | +| 第37局 | 血18/攻5/甲5 | 34 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第40局 | 血18/攻6/甲5 | 142 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第43局 | 血18/攻6/甲6 | 100 | 100%(n=10) | 100%(n=10) | 100%(n=10) | 通关 | +| 第46局 | 血18/攻6/甲6 | 195 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第49局 | 血21/攻6/甲6 | 78 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第52局 | 血21/攻6/甲6 | 173 | 100%(n=10) | 100%(n=10) | 80%(n=10) | 通关 | +| 第55局 | 血21/攻7/甲6 | 56 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第58局 | 血21/攻7/甲6 | 164 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | diff --git a/production/qa/balance-verifier-20260923-043341.raw.jsonl b/production/qa/balance-verifier-20260923-043341.raw.jsonl new file mode 100644 index 00000000..47e33c45 --- /dev/null +++ b/production/qa/balance-verifier-20260923-043341.raw.jsonl @@ -0,0 +1,240 @@ +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8000, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8001, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8002, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8003, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8004, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8005, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8006, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8007, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8008, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8009, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8010, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8011, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8012, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8013, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8014, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8015, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8016, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8017, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8018, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 0, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8019, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8020, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8021, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8022, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8023, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "normal", "result": "failed", "seed": 8024, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8025, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8026, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8027, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8028, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8029, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8030, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8031, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8032, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "normal", "result": "failed", "seed": 8033, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "normal", "result": "failed", "seed": 8034, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8035, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8036, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8037, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8038, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8039, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8040, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8041, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8042, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8043, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8044, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8045, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8046, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8047, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8048, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "normal", "result": "failed", "seed": 8049, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8050, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8051, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 0, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "normal", "result": "failed", "seed": 8052, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8053, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8054, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8055, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8056, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8057, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8058, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8059, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8060, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8061, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8062, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8063, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8064, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8065, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8066, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8067, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8068, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8069, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8070, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8071, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8072, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8073, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8074, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8075, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8076, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8077, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8078, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8079, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8080, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8081, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8082, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8083, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8084, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8085, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8086, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8087, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8088, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8089, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8090, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8091, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8092, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 0, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8093, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8094, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8095, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8096, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 0, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8097, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8098, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8099, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8100, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8101, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8102, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8103, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8104, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8105, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8106, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8107, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8108, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8109, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8110, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8111, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8112, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8113, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8114, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8115, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8116, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8117, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8118, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8119, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 0, "keystone_after": 0, "keystone_before": 0, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 1, "seed": 8120, "seg": "campaign", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 10, "keystone_after": 15, "keystone_before": 0, "keystone_income": 15, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["probe_dust", "sapper_order"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 2, "seed": 8121, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 0, "keystone_after": 15, "keystone_before": 15, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 3, "seed": 8122, "seg": "campaign", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 1}, "keystone": 10, "keystone_after": 6, "keystone_before": 15, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["loot_compass", "nest_pendulum"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 20, "tier": 1}], "result": "failed", "run_no": 4, "seed": 8123, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 1}, "keystone": 10, "keystone_after": 17, "keystone_before": 6, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["catacomb_scroll", "blast_kit"], "override": {"armor_class": 0, "atk": 0, "max_hp": 3}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 5, "seed": 8124, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 2}, "keystone": 20, "keystone_after": 16, "keystone_before": 17, "keystone_income": 29, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 3}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 30, "tier": 2}], "result": "failed", "run_no": 6, "seed": 8125, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 10, "keystone_after": 7, "keystone_before": 16, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 6}, "policy": "normal", "purchases": [{"attr": "atk", "price": 20, "tier": 1}], "result": "failed", "run_no": 7, "seed": 8126, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 0, "keystone_after": 7, "keystone_before": 7, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 8, "seed": 8127, "seg": "campaign", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 0, "keystone_after": 7, "keystone_before": 7, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 9, "seed": 8128, "seg": "campaign", "stopped_at": 1} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 3}, "keystone": 30, "keystone_after": 7, "keystone_before": 7, "keystone_income": 45, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 45, "tier": 3}], "result": "completed", "run_no": 10, "seed": 8129, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 2, "max_hp": 3}, "keystone": 30, "keystone_after": 13, "keystone_before": 7, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "atk", "price": 30, "tier": 2}], "result": "completed", "run_no": 11, "seed": 8130, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 1, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 4, "keystone_before": 13, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 20, "tier": 1}], "result": "failed", "run_no": 12, "seed": 8131, "seg": "campaign", "stopped_at": 2} +{"defeat": {}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 30, "keystone_after": 10, "keystone_before": 4, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 1, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 30, "tier": 2}], "result": "completed", "run_no": 13, "seed": 8132, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 20, "keystone_after": 33, "keystone_before": 10, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 14, "seed": 8133, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 44, "keystone_before": 33, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 15, "seed": 8134, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 4}, "keystone": 20, "keystone_after": 0, "keystone_before": 44, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 67, "tier": 4}], "result": "failed", "run_no": 16, "seed": 8135, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 4}, "keystone": 10, "keystone_after": 11, "keystone_before": 0, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 17, "seed": 8136, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 4}, "keystone": 20, "keystone_after": 34, "keystone_before": 11, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 18, "seed": 8137, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 12, "keystone_before": 34, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "atk", "price": 45, "tier": 3}], "result": "failed", "run_no": 19, "seed": 8138, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 35, "keystone_before": 12, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 20, "seed": 8139, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 13, "keystone_before": 35, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 45, "tier": 3}], "result": "failed", "run_no": 21, "seed": 8140, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 36, "keystone_before": 13, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 22, "seed": 8141, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 59, "keystone_before": 36, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 23, "seed": 8142, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 10, "keystone_after": 3, "keystone_before": 59, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "atk", "price": 67, "tier": 4}], "result": "failed", "run_no": 24, "seed": 8143, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 26, "keystone_before": 3, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 25, "seed": 8144, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 49, "keystone_before": 26, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 26, "seed": 8145, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 5, "keystone_before": 49, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 67, "tier": 4}], "result": "failed", "run_no": 27, "seed": 8146, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 41, "keystone_before": 5, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 28, "seed": 8147, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 64, "keystone_before": 41, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 29, "seed": 8148, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 87, "keystone_before": 64, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 30, "seed": 8149, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 23, "keystone_before": 87, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 100, "tier": 5}], "result": "completed", "run_no": 31, "seed": 8150, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 59, "keystone_before": 23, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 32, "seed": 8151, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 95, "keystone_before": 59, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 33, "seed": 8152, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 31, "keystone_before": 95, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "normal", "purchases": [{"attr": "atk", "price": 100, "tier": 5}], "result": "completed", "run_no": 34, "seed": 8153, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 67, "keystone_before": 31, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 35, "seed": 8154, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 3, "keystone_before": 67, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 100, "tier": 5}], "result": "completed", "run_no": 36, "seed": 8155, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 39, "keystone_before": 3, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 37, "seed": 8156, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 75, "keystone_before": 39, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 38, "seed": 8157, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 98, "keystone_before": 75, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 39, "seed": 8158, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 134, "keystone_before": 98, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 40, "seed": 8159, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 20, "keystone_after": 7, "keystone_before": 134, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 150, "tier": 6}], "result": "failed", "run_no": 41, "seed": 8160, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 43, "keystone_before": 7, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 42, "seed": 8161, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 79, "keystone_before": 43, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 43, "seed": 8162, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 115, "keystone_before": 79, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 44, "seed": 8163, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 1, "keystone_before": 115, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [{"attr": "atk", "price": 150, "tier": 6}], "result": "completed", "run_no": 45, "seed": 8164, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 37, "keystone_before": 1, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 46, "seed": 8165, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 73, "keystone_before": 37, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 47, "seed": 8166, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 109, "keystone_before": 73, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 48, "seed": 8167, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 145, "keystone_before": 109, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 49, "seed": 8168, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 31, "keystone_before": 145, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 150, "tier": 6}], "result": "completed", "run_no": 50, "seed": 8169, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 20, "keystone_after": 54, "keystone_before": 31, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 51, "seed": 8170, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 90, "keystone_before": 54, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 52, "seed": 8171, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 126, "keystone_before": 90, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 53, "seed": 8172, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 162, "keystone_before": 126, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 54, "seed": 8173, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 198, "keystone_before": 162, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 55, "seed": 8174, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 9, "keystone_before": 198, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 225, "tier": 7}], "result": "completed", "run_no": 56, "seed": 8175, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 45, "keystone_before": 9, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 57, "seed": 8176, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 81, "keystone_before": 45, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 58, "seed": 8177, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 117, "keystone_before": 81, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 59, "seed": 8178, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 153, "keystone_before": 117, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 60, "seed": 8179, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 10, "keystone_after": 15, "keystone_before": 0, "keystone_income": 15, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["probe_dust", "sapper_order"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 1, "seed": 8180, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 1}, "keystone": 20, "keystone_after": 4, "keystone_before": 15, "keystone_income": 29, "last_enemies": [], "levels_cleared": 2, "new_unlocks": ["loot_compass", "nest_pendulum", "catacomb_scroll", "blast_kit"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 20, "tier": 1}, {"attr": "atk", "price": 20, "tier": 1}], "result": "failed", "run_no": 2, "seed": 8181, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 1}, "keystone": 10, "keystone_after": 15, "keystone_before": 4, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 3}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 3, "seed": 8182, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 20, "keystone_after": 8, "keystone_before": 15, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 3}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 30, "tier": 2}], "result": "failed", "run_no": 4, "seed": 8183, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 3}, "keystone": 30, "keystone_after": 8, "keystone_before": 8, "keystone_income": 45, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 45, "tier": 3}], "result": "completed", "run_no": 5, "seed": 8184, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 2, "max_hp": 3}, "keystone": 20, "keystone_after": 1, "keystone_before": 8, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 30, "tier": 2}], "result": "failed", "run_no": 6, "seed": 8185, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 12, "keystone_before": 1, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 2, "max_hp": 9}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 7, "seed": 8186, "seg": "campaign", "stopped_at": 2} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 3, "max_hp": 3}, "keystone": 30, "keystone_after": 3, "keystone_before": 12, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 2, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 45, "tier": 3}], "result": "completed", "run_no": 8, "seed": 8187, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 1, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 6, "keystone_before": 3, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 20, "tier": 1}], "result": "failed", "run_no": 9, "seed": 8188, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 2, "atk": 3, "max_hp": 3}, "keystone": 30, "keystone_after": 12, "keystone_before": 6, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 1, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 30, "tier": 2}], "result": "completed", "run_no": 10, "seed": 8189, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 30, "keystone_after": 3, "keystone_before": 12, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 2, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 45, "tier": 3}], "result": "completed", "run_no": 11, "seed": 8190, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 30, "keystone_after": 39, "keystone_before": 3, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 12, "seed": 8191, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 62, "keystone_before": 39, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 13, "seed": 8192, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 18, "keystone_before": 62, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 67, "tier": 4}], "result": "failed", "run_no": 14, "seed": 8193, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 30, "keystone_after": 54, "keystone_before": 18, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 15, "seed": 8194, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 10, "keystone_before": 54, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 67, "tier": 4}], "result": "failed", "run_no": 16, "seed": 8195, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 33, "keystone_before": 10, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 17, "seed": 8196, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 2, "keystone_before": 33, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 67, "tier": 4}], "result": "completed", "run_no": 18, "seed": 8197, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 38, "keystone_before": 2, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 19, "seed": 8198, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 61, "keystone_before": 38, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 20, "seed": 8199, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 97, "keystone_before": 61, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 21, "seed": 8200, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 33, "keystone_before": 97, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 100, "tier": 5}], "result": "completed", "run_no": 22, "seed": 8201, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 69, "keystone_before": 33, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 23, "seed": 8202, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 5, "keystone_before": 69, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 100, "tier": 5}], "result": "completed", "run_no": 24, "seed": 8203, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 28, "keystone_before": 5, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 25, "seed": 8204, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 51, "keystone_before": 28, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 26, "seed": 8205, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 87, "keystone_before": 51, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 27, "seed": 8206, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 23, "keystone_before": 87, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 100, "tier": 5}], "result": "completed", "run_no": 28, "seed": 8207, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 59, "keystone_before": 23, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 29, "seed": 8208, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 95, "keystone_before": 59, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 30, "seed": 8209, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 118, "keystone_before": 95, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 31, "seed": 8210, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 4, "keystone_before": 118, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 150, "tier": 6}], "result": "completed", "run_no": 32, "seed": 8211, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 40, "keystone_before": 4, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 33, "seed": 8212, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 76, "keystone_before": 40, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 34, "seed": 8213, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 112, "keystone_before": 76, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 35, "seed": 8214, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 148, "keystone_before": 112, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 36, "seed": 8215, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 34, "keystone_before": 148, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 150, "tier": 6}], "result": "completed", "run_no": 37, "seed": 8216, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 70, "keystone_before": 34, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 38, "seed": 8217, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 106, "keystone_before": 70, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 39, "seed": 8218, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 142, "keystone_before": 106, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 40, "seed": 8219, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 28, "keystone_before": 142, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 150, "tier": 6}], "result": "completed", "run_no": 41, "seed": 8220, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 64, "keystone_before": 28, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 42, "seed": 8221, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 100, "keystone_before": 64, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 43, "seed": 8222, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 136, "keystone_before": 100, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 44, "seed": 8223, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 20, "keystone_after": 159, "keystone_before": 136, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 45, "seed": 8224, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 195, "keystone_before": 159, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 46, "seed": 8225, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 6, "keystone_before": 195, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 225, "tier": 7}], "result": "completed", "run_no": 47, "seed": 8226, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 42, "keystone_before": 6, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 48, "seed": 8227, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 78, "keystone_before": 42, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 49, "seed": 8228, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 20, "keystone_after": 101, "keystone_before": 78, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 50, "seed": 8229, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 137, "keystone_before": 101, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 51, "seed": 8230, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 173, "keystone_before": 137, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 52, "seed": 8231, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 209, "keystone_before": 173, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 53, "seed": 8232, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 20, "keystone_before": 209, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 225, "tier": 7}], "result": "completed", "run_no": 54, "seed": 8233, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 56, "keystone_before": 20, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 55, "seed": 8234, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 92, "keystone_before": 56, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 56, "seed": 8235, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 128, "keystone_before": 92, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 57, "seed": 8236, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 164, "keystone_before": 128, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 58, "seed": 8237, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 200, "keystone_before": 164, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 59, "seed": 8238, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 7, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 11, "keystone_before": 200, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 225, "tier": 7}], "result": "completed", "run_no": 60, "seed": 8239, "seg": "campaign", "stopped_at": 0} diff --git a/production/qa/balance-verifier-20260923-050222.md b/production/qa/balance-verifier-20260923-050222.md new file mode 100644 index 00000000..0066365a --- /dev/null +++ b/production/qa/balance-verifier-20260923-050222.md @@ -0,0 +1,103 @@ +# 数值验证报告(20260923-050222) + +- 采集规模:直入口每格 100 局 · 基线冒险 60 局/画像 · 战役 60 局/画像 · 种子 8000 起逐局独立 · 锻造花费策略 = hp_first +- 切片版本:3309aae · 表状态:判定带与表值溯源见 tools/balance_verifier.py 文件头 + +## ① 直入口基线通关率(验收带判定) + +| 层 | 画像 | 通关/局数 | 通关率±95%CI | 验收带 | 判定 | +|----|------|-----------|--------------|--------|------| + +## ② 零永久强化冒险:止步分布与败退节点(用户判据③) + +### 普通档(60 局) + +- 止步分布:止步第1层 29(48%)、止步第2层 30(50%)、止步第3层 1(2%) +- 第一层通过率(冒险口径交叉核对):51.7% +- 败退节点分布(失败局归因): + - 第一层·节点4·战斗 ×12 + - 第一层·节点6·Boss ×12 + - 第二层·节点1·战斗 ×12 + - 第二层·节点9·Boss ×12 + - 第一层·节点3·战斗 ×5 + - 第二层·节点6·战斗 ×5 + - 第二层·节点0·战斗 ×1 + - 第三层·节点1·战斗 ×1 + +### 完美档(60 局) + +- 止步分布:止步第1层 6(10%)、止步第2层 45(75%)、止步第3层 8(13%)、通关 1(2%) +- 第一层通过率(冒险口径交叉核对):90.0% +- 败退节点分布(失败局归因): + - 第二层·节点1·战斗 ×17 + - 第二层·节点9·Boss ×17 + - 第二层·节点6·战斗 ×11 + - 第一层·节点4·战斗 ×6 + - 第三层·节点1·战斗 ×4 + - 第三层·节点6·战斗 ×2 + - 第三层·节点0·战斗 ×1 + - 第三层·节点9·Boss ×1 + +## ③ 营地循环爬升(用户判据④:5 次通关 → 下一层可过) + +### 普通档(60 局战役) + +- 钥石:全程入账 1553 · 终态余额 92 · 锻造终态 = 生命+21/攻击+6/护甲+6 +- 道具工坊解锁时点(魔法道具面,局内效果未实装只报不判):显影尘 第 2 局、工兵令 第 2 局、探宝罗盘 第 4 局、探巢摆钟 第 4 局、地穴全图卷 第 5 局、爆破工兵包 第 5 局 + +- 判据:累计通过第一层 5 次后,第二层条件通关率(滑窗 10 局)——越上界(高于 45% 达 5.0 点)(触发时注入 = 生命+6/攻击+1/护甲+0) +- 判据:累计通过第二层 5 次后,第三层条件通关率(滑窗 10 局)——带未定(只测不判)(触发时注入 = 生命+9/攻击+3/护甲+2) + +| 局 | 注入(flat) | 钥石 | 第1层率(窗) | 第2层率(窗) | 第3层率(窗) | 终局 | +|--------|--------------|------|-------------|-------------|-------------|-----------| +| 第1局 | 血0/攻0/甲0 | 0 | 0%(n=1) | — | — | 止步第1层 | +| 第4局 | 血0/攻0/甲0 | 6 | 50%(n=4) | 0%(n=2) | — | 止步第2层 | +| 第7局 | 血3/攻1/甲0 | 7 | 71%(n=7) | 20%(n=5) | 0%(n=1) | 止步第3层 | +| 第10局 | 血6/攻1/甲0 | 7 | 60%(n=10) | 33%(n=6) | 50%(n=2) | 通关 | +| 第13局 | 血9/攻2/甲1 | 15 | 80%(n=10) | 33%(n=9) | — | 止步第2层 | +| 第16局 | 血9/攻2/甲2 | 30 | 80%(n=10) | 40%(n=10) | 50%(n=4) | 止步第3层 | +| 第19局 | 血9/攻3/甲2 | 42 | 100%(n=10) | 50%(n=10) | 33%(n=6) | 止步第3层 | +| 第22局 | 血9/攻3/甲3 | 12 | 100%(n=10) | 60%(n=10) | 33%(n=9) | 通关 | +| 第25局 | 血12/攻3/甲3 | 57 | 100%(n=10) | 70%(n=10) | — | 止步第2层 | +| 第28局 | 血12/攻4/甲3 | 59 | 100%(n=10) | 80%(n=10) | 10%(n=10) | 止步第3层 | +| 第31局 | 血12/攻4/甲4 | 87 | 100%(n=10) | 80%(n=10) | 30%(n=10) | 通关 | +| 第34局 | 血15/攻4/甲4 | 95 | 100%(n=10) | 90%(n=10) | 50%(n=10) | 通关 | +| 第37局 | 血15/攻5/甲4 | 3 | 100%(n=10) | 100%(n=10) | 80%(n=10) | 通关 | +| 第40局 | 血15/攻5/甲5 | 98 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第43局 | 血15/攻5/甲5 | 18 | 100%(n=10) | 90%(n=10) | 80%(n=10) | 通关 | +| 第46局 | 血18/攻5/甲5 | 126 | 100%(n=10) | 90%(n=10) | 80%(n=10) | 通关 | +| 第49局 | 血18/攻6/甲5 | 84 | 100%(n=10) | 90%(n=10) | 80%(n=10) | 通关 | +| 第52局 | 血18/攻6/甲5 | 29 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第55局 | 血18/攻6/甲6 | 137 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第58局 | 血18/攻6/甲6 | 20 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | + +### 完美档(60 局战役) + +- 钥石:全程入账 1935 · 终态余额 24 · 锻造终态 = 生命+21/攻击+7/护甲+7 +- 道具工坊解锁时点(魔法道具面,局内效果未实装只报不判):显影尘 第 1 局、工兵令 第 1 局、探宝罗盘 第 2 局、探巢摆钟 第 2 局、地穴全图卷 第 2 局、爆破工兵包 第 2 局 + +- 判据:累计通过第一层 5 次后,第二层条件通关率(滑窗 10 局)——越上界(高于 65% 达 35.0 点)(触发时注入 = 生命+9/攻击+1/护甲+0) +- 判据:累计通过第二层 5 次后,第三层条件通关率(滑窗 10 局)——带未定(只测不判)(触发时注入 = 生命+9/攻击+2/护甲+1) + +| 局 | 注入(flat) | 钥石 | 第1层率(窗) | 第2层率(窗) | 第3层率(窗) | 终局 | +|--------|--------------|------|-------------|-------------|-------------|-----------| +| 第1局 | 血0/攻0/甲0 | 15 | 100%(n=1) | 0%(n=1) | — | 止步第2层 | +| 第4局 | 血3/攻1/甲0 | 8 | 100%(n=4) | 50%(n=4) | 0%(n=2) | 止步第3层 | +| 第7局 | 血9/攻2/甲0 | 4 | 100%(n=7) | 71%(n=7) | 20%(n=5) | 止步第3层 | +| 第10局 | 血9/攻2/甲2 | 11 | 100%(n=10) | 80%(n=10) | 25%(n=8) | 止步第3层 | +| 第13局 | 血9/攻3/甲3 | 61 | 100%(n=10) | 100%(n=10) | 40%(n=10) | 止步第3层 | +| 第16局 | 血12/攻3/甲3 | 9 | 100%(n=10) | 100%(n=10) | 40%(n=10) | 止步第3层 | +| 第19局 | 血12/攻4/甲4 | 50 | 100%(n=10) | 100%(n=10) | 60%(n=10) | 通关 | +| 第22局 | 血15/攻4/甲4 | 45 | 100%(n=10) | 100%(n=10) | 60%(n=10) | 通关 | +| 第25局 | 血15/攻5/甲4 | 40 | 100%(n=10) | 100%(n=10) | 70%(n=10) | 止步第3层 | +| 第28局 | 血15/攻5/甲5 | 48 | 100%(n=10) | 100%(n=10) | 80%(n=10) | 通关 | +| 第31局 | 血15/攻5/甲5 | 118 | 100%(n=10) | 90%(n=10) | 80%(n=10) | 止步第3层 | +| 第34局 | 血18/攻5/甲5 | 76 | 100%(n=10) | 90%(n=10) | 80%(n=10) | 通关 | +| 第37局 | 血18/攻5/甲5 | 34 | 100%(n=10) | 90%(n=10) | 90%(n=10) | 通关 | +| 第40局 | 血18/攻6/甲5 | 142 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第43局 | 血18/攻6/甲6 | 100 | 100%(n=10) | 100%(n=10) | 100%(n=10) | 通关 | +| 第46局 | 血18/攻6/甲6 | 195 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第49局 | 血21/攻6/甲6 | 78 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第52局 | 血21/攻6/甲6 | 186 | 100%(n=10) | 100%(n=10) | 90%(n=10) | 通关 | +| 第55局 | 血21/攻7/甲6 | 69 | 100%(n=10) | 100%(n=10) | 100%(n=10) | 通关 | +| 第58局 | 血21/攻7/甲6 | 177 | 100%(n=10) | 100%(n=10) | 100%(n=10) | 通关 | diff --git a/production/qa/balance-verifier-20260923-050222.raw.jsonl b/production/qa/balance-verifier-20260923-050222.raw.jsonl new file mode 100644 index 00000000..6e2c3c47 --- /dev/null +++ b/production/qa/balance-verifier-20260923-050222.raw.jsonl @@ -0,0 +1,240 @@ +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8000, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8001, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8002, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8003, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8004, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8005, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8006, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8007, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8008, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8009, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8010, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8011, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8012, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8013, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8014, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8015, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8016, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8017, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8018, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 0, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8019, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8020, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8021, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8022, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8023, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8024, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8025, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8026, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8027, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8028, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8029, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8030, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8031, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8032, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8033, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "normal", "result": "failed", "seed": 8034, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8035, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8036, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8037, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8038, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 3, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8039, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8040, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8041, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8042, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8043, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8044, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8045, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8046, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8047, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8048, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8049, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8050, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8051, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8052, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8053, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8054, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8055, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8056, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "normal", "result": "failed", "seed": 8057, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8058, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "normal", "result": "failed", "seed": 8059, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8060, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8061, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8062, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8063, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 0, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8064, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8065, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8066, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8067, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8068, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8069, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8070, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8071, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8072, "seg": "adventure", "stopped_at": 2} +{"defeat": {}, "keystone": 30, "last_enemies": [], "levels_cleared": 3, "policy": "perfect", "result": "completed", "seed": 8073, "seg": "adventure", "stopped_at": 0} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8074, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8075, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8076, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8077, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8078, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8079, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8080, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8081, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8082, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8083, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8084, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8085, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8086, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8087, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8088, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8089, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8090, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8091, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8092, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8093, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8094, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8095, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8096, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8097, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8098, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8099, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8100, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8101, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8102, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8103, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8104, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8105, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8106, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8107, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8108, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8109, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8110, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8111, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "keystone": 0, "last_enemies": [], "levels_cleared": 0, "policy": "perfect", "result": "failed", "seed": 8112, "seg": "adventure", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8113, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8114, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "keystone": 20, "last_enemies": [], "levels_cleared": 2, "policy": "perfect", "result": "failed", "seed": 8115, "seg": "adventure", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8116, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8117, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8118, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "keystone": 10, "last_enemies": [], "levels_cleared": 1, "policy": "perfect", "result": "failed", "seed": 8119, "seg": "adventure", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 0, "keystone_after": 0, "keystone_before": 0, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 1, "seed": 8120, "seg": "campaign", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 10, "keystone_after": 15, "keystone_before": 0, "keystone_income": 15, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["probe_dust", "sapper_order"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 2, "seed": 8121, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 1, "node_id": 4, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 0, "keystone_after": 15, "keystone_before": 15, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 3, "seed": 8122, "seg": "campaign", "stopped_at": 1} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 1}, "keystone": 10, "keystone_after": 6, "keystone_before": 15, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["loot_compass", "nest_pendulum"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 20, "tier": 1}], "result": "failed", "run_no": 4, "seed": 8123, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 1}, "keystone": 10, "keystone_after": 17, "keystone_before": 6, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["catacomb_scroll", "blast_kit"], "override": {"armor_class": 0, "atk": 0, "max_hp": 3}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 5, "seed": 8124, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 1}, "keystone": 10, "keystone_after": 8, "keystone_before": 17, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 0, "max_hp": 3}, "policy": "normal", "purchases": [{"attr": "atk", "price": 20, "tier": 1}], "result": "failed", "run_no": 6, "seed": 8125, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 20, "keystone_after": 7, "keystone_before": 8, "keystone_income": 29, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 3}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 30, "tier": 2}], "result": "failed", "run_no": 7, "seed": 8126, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 0, "keystone_after": 7, "keystone_before": 7, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 8, "seed": 8127, "seg": "campaign", "stopped_at": 1} +{"defeat": {"level_index": 1, "node_id": 6, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 0, "keystone_after": 7, "keystone_before": 7, "keystone_income": 0, "last_enemies": [], "levels_cleared": 0, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 9, "seed": 8128, "seg": "campaign", "stopped_at": 1} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 3}, "keystone": 30, "keystone_after": 7, "keystone_before": 7, "keystone_income": 45, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 45, "tier": 3}], "result": "completed", "run_no": 10, "seed": 8129, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 2, "max_hp": 3}, "keystone": 30, "keystone_after": 13, "keystone_before": 7, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "atk", "price": 30, "tier": 2}], "result": "completed", "run_no": 11, "seed": 8130, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 1, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 4, "keystone_before": 13, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 20, "tier": 1}], "result": "failed", "run_no": 12, "seed": 8131, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 1, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 15, "keystone_before": 4, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 1, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 13, "seed": 8132, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 1, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 26, "keystone_before": 15, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 1, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 14, "seed": 8133, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 7, "keystone_before": 26, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 1, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 30, "tier": 2}], "result": "failed", "run_no": 15, "seed": 8134, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 20, "keystone_after": 30, "keystone_before": 7, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 16, "seed": 8135, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 10, "keystone_after": 41, "keystone_before": 30, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 17, "seed": 8136, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 19, "keystone_before": 41, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "atk", "price": 45, "tier": 3}], "result": "failed", "run_no": 18, "seed": 8137, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 42, "keystone_before": 19, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 3, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 19, "seed": 8138, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 20, "keystone_before": 42, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 3, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 45, "tier": 3}], "result": "failed", "run_no": 20, "seed": 8139, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 43, "keystone_before": 20, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 21, "seed": 8140, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 30, "keystone_after": 12, "keystone_before": 43, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 67, "tier": 4}], "result": "completed", "run_no": 22, "seed": 8141, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 35, "keystone_before": 12, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 23, "seed": 8142, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 10, "keystone_after": 46, "keystone_before": 35, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 24, "seed": 8143, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 2, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 10, "keystone_after": 57, "keystone_before": 46, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 25, "seed": 8144, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 13, "keystone_before": 57, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "atk", "price": 67, "tier": 4}], "result": "failed", "run_no": 26, "seed": 8145, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 36, "keystone_before": 13, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 27, "seed": 8146, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 59, "keystone_before": 36, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 28, "seed": 8147, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 15, "keystone_before": 59, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 67, "tier": 4}], "result": "failed", "run_no": 29, "seed": 8148, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 51, "keystone_before": 15, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 30, "seed": 8149, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 87, "keystone_before": 51, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 31, "seed": 8150, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 23, "keystone_before": 87, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 100, "tier": 5}], "result": "completed", "run_no": 32, "seed": 8151, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 59, "keystone_before": 23, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 33, "seed": 8152, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 95, "keystone_before": 59, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 34, "seed": 8153, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 31, "keystone_before": 95, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "normal", "purchases": [{"attr": "atk", "price": 100, "tier": 5}], "result": "completed", "run_no": 35, "seed": 8154, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 67, "keystone_before": 31, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 36, "seed": 8155, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 3, "keystone_before": 67, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 100, "tier": 5}], "result": "completed", "run_no": 37, "seed": 8156, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 39, "keystone_before": 3, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 38, "seed": 8157, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 62, "keystone_before": 39, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 39, "seed": 8158, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 98, "keystone_before": 62, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 40, "seed": 8159, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 121, "keystone_before": 98, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 41, "seed": 8160, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 10, "keystone_after": 132, "keystone_before": 121, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 42, "seed": 8161, "seg": "campaign", "stopped_at": 2} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 18, "keystone_before": 132, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 150, "tier": 6}], "result": "completed", "run_no": 43, "seed": 8162, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 54, "keystone_before": 18, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 44, "seed": 8163, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 90, "keystone_before": 54, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 45, "seed": 8164, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 126, "keystone_before": 90, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 46, "seed": 8165, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 12, "keystone_before": 126, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "normal", "purchases": [{"attr": "atk", "price": 150, "tier": 6}], "result": "completed", "run_no": 47, "seed": 8166, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 48, "keystone_before": 12, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 48, "seed": 8167, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 84, "keystone_before": 48, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 49, "seed": 8168, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 120, "keystone_before": 84, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 50, "seed": 8169, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 20, "keystone_after": 143, "keystone_before": 120, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "failed", "run_no": 51, "seed": 8170, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 29, "keystone_before": 143, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [{"attr": "armor_class", "price": 150, "tier": 6}], "result": "completed", "run_no": 52, "seed": 8171, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 65, "keystone_before": 29, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 53, "seed": 8172, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 101, "keystone_before": 65, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 54, "seed": 8173, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 137, "keystone_before": 101, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 55, "seed": 8174, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 173, "keystone_before": 137, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 56, "seed": 8175, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 209, "keystone_before": 173, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 57, "seed": 8176, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 20, "keystone_before": 209, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "normal", "purchases": [{"attr": "max_hp", "price": 225, "tier": 7}], "result": "completed", "run_no": 58, "seed": 8177, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 56, "keystone_before": 20, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 59, "seed": 8178, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 92, "keystone_before": 56, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "normal", "purchases": [], "result": "completed", "run_no": 60, "seed": 8179, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 0, "max_hp": 0}, "keystone": 10, "keystone_after": 15, "keystone_before": 0, "keystone_income": 15, "last_enemies": [], "levels_cleared": 1, "new_unlocks": ["probe_dust", "sapper_order"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 1, "seed": 8180, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 1}, "keystone": 20, "keystone_after": 4, "keystone_before": 15, "keystone_income": 29, "last_enemies": [], "levels_cleared": 2, "new_unlocks": ["loot_compass", "nest_pendulum", "catacomb_scroll", "blast_kit"], "override": {"armor_class": 0, "atk": 0, "max_hp": 0}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 20, "tier": 1}, {"attr": "atk", "price": 20, "tier": 1}], "result": "failed", "run_no": 2, "seed": 8181, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 1}, "keystone": 10, "keystone_after": 15, "keystone_before": 4, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 3}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 3, "seed": 8182, "seg": "campaign", "stopped_at": 2} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 2}, "keystone": 20, "keystone_after": 8, "keystone_before": 15, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 3}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 30, "tier": 2}], "result": "failed", "run_no": 4, "seed": 8183, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 0, "atk": 1, "max_hp": 3}, "keystone": 30, "keystone_after": 8, "keystone_before": 8, "keystone_income": 45, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 6}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 45, "tier": 3}], "result": "completed", "run_no": 5, "seed": 8184, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 0, "atk": 2, "max_hp": 3}, "keystone": 20, "keystone_after": 1, "keystone_before": 8, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 1, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 30, "tier": 2}], "result": "failed", "run_no": 6, "seed": 8185, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 1, "atk": 2, "max_hp": 3}, "keystone": 20, "keystone_after": 4, "keystone_before": 1, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 0, "atk": 2, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 20, "tier": 1}], "result": "failed", "run_no": 7, "seed": 8186, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 30, "keystone_after": 10, "keystone_before": 4, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 1, "atk": 2, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 30, "tier": 2}], "result": "completed", "run_no": 8, "seed": 8187, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 2, "atk": 2, "max_hp": 3}, "keystone": 20, "keystone_after": 33, "keystone_before": 10, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 9, "seed": 8188, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 1, "node_type": "battle"}, "forge": {"armor_class": 2, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 11, "keystone_before": 33, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 2, "atk": 2, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 45, "tier": 3}], "result": "failed", "run_no": 10, "seed": 8189, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 30, "keystone_after": 2, "keystone_before": 11, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 2, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 45, "tier": 3}], "result": "completed", "run_no": 11, "seed": 8190, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 30, "keystone_after": 38, "keystone_before": 2, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 12, "seed": 8191, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 3}, "keystone": 20, "keystone_after": 61, "keystone_before": 38, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 13, "seed": 8192, "seg": "campaign", "stopped_at": 3} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 20, "keystone_after": 17, "keystone_before": 61, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 9}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 67, "tier": 4}], "result": "failed", "run_no": 14, "seed": 8193, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 3, "max_hp": 4}, "keystone": 30, "keystone_after": 53, "keystone_before": 17, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 15, "seed": 8194, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 6, "node_type": "battle"}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 9, "keystone_before": 53, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 3, "atk": 3, "max_hp": 12}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 67, "tier": 4}], "result": "failed", "run_no": 16, "seed": 8195, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 3, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 45, "keystone_before": 9, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 17, "seed": 8196, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 14, "keystone_before": 45, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 3, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 67, "tier": 4}], "result": "completed", "run_no": 18, "seed": 8197, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 30, "keystone_after": 50, "keystone_before": 14, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 19, "seed": 8198, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 4}, "keystone": 20, "keystone_after": 73, "keystone_before": 50, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 20, "seed": 8199, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 9, "keystone_before": 73, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 12}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 100, "tier": 5}], "result": "completed", "run_no": 21, "seed": 8200, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 45, "keystone_before": 9, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 22, "seed": 8201, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 4, "max_hp": 5}, "keystone": 30, "keystone_after": 81, "keystone_before": 45, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 23, "seed": 8202, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 17, "keystone_before": 81, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 4, "max_hp": 15}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 100, "tier": 5}], "result": "completed", "run_no": 24, "seed": 8203, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 40, "keystone_before": 17, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 25, "seed": 8204, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 4, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 76, "keystone_before": 40, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 26, "seed": 8205, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 12, "keystone_before": 76, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 4, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 100, "tier": 5}], "result": "completed", "run_no": 27, "seed": 8206, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 48, "keystone_before": 12, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 28, "seed": 8207, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 2, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 10, "keystone_after": 59, "keystone_before": 48, "keystone_income": 11, "last_enemies": [], "levels_cleared": 1, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 29, "seed": 8208, "seg": "campaign", "stopped_at": 2} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 30, "keystone_after": 95, "keystone_before": 59, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 30, "seed": 8209, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 5}, "keystone": 20, "keystone_after": 118, "keystone_before": 95, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 31, "seed": 8210, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 4, "keystone_before": 118, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 15}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 150, "tier": 6}], "result": "completed", "run_no": 32, "seed": 8211, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 40, "keystone_before": 4, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 33, "seed": 8212, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 76, "keystone_before": 40, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 34, "seed": 8213, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 112, "keystone_before": 76, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 35, "seed": 8214, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 5, "max_hp": 6}, "keystone": 30, "keystone_after": 148, "keystone_before": 112, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 36, "seed": 8215, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 34, "keystone_before": 148, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 5, "max_hp": 18}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 150, "tier": 6}], "result": "completed", "run_no": 37, "seed": 8216, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 70, "keystone_before": 34, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 38, "seed": 8217, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 106, "keystone_before": 70, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 39, "seed": 8218, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 5, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 142, "keystone_before": 106, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 40, "seed": 8219, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 28, "keystone_before": 142, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 5, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 150, "tier": 6}], "result": "completed", "run_no": 41, "seed": 8220, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 64, "keystone_before": 28, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 42, "seed": 8221, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 100, "keystone_before": 64, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 43, "seed": 8222, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 136, "keystone_before": 100, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 44, "seed": 8223, "seg": "campaign", "stopped_at": 0} +{"defeat": {"level_index": 3, "node_id": 9, "node_type": "boss"}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 20, "keystone_after": 159, "keystone_before": 136, "keystone_income": 23, "last_enemies": [], "levels_cleared": 2, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "failed", "run_no": 45, "seed": 8224, "seg": "campaign", "stopped_at": 3} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 6}, "keystone": 30, "keystone_after": 195, "keystone_before": 159, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 46, "seed": 8225, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 6, "keystone_before": 195, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 18}, "policy": "perfect", "purchases": [{"attr": "max_hp", "price": 225, "tier": 7}], "result": "completed", "run_no": 47, "seed": 8226, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 42, "keystone_before": 6, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 48, "seed": 8227, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 78, "keystone_before": 42, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 49, "seed": 8228, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 114, "keystone_before": 78, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 50, "seed": 8229, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 150, "keystone_before": 114, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 51, "seed": 8230, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 186, "keystone_before": 150, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 52, "seed": 8231, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 6, "max_hp": 7}, "keystone": 30, "keystone_after": 222, "keystone_before": 186, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 53, "seed": 8232, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 33, "keystone_before": 222, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 6, "max_hp": 21}, "policy": "perfect", "purchases": [{"attr": "atk", "price": 225, "tier": 7}], "result": "completed", "run_no": 54, "seed": 8233, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 69, "keystone_before": 33, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 55, "seed": 8234, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 105, "keystone_before": 69, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 56, "seed": 8235, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 141, "keystone_before": 105, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 57, "seed": 8236, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 177, "keystone_before": 141, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 58, "seed": 8237, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 6, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 213, "keystone_before": 177, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [], "result": "completed", "run_no": 59, "seed": 8238, "seg": "campaign", "stopped_at": 0} +{"defeat": {}, "forge": {"armor_class": 7, "atk": 7, "max_hp": 7}, "keystone": 30, "keystone_after": 24, "keystone_before": 213, "keystone_income": 36, "last_enemies": [], "levels_cleared": 3, "new_unlocks": [], "override": {"armor_class": 6, "atk": 7, "max_hp": 21}, "policy": "perfect", "purchases": [{"attr": "armor_class", "price": 225, "tier": 7}], "result": "completed", "run_no": 60, "seed": 8239, "seg": "campaign", "stopped_at": 0} diff --git a/production/session-state/active.md b/production/session-state/active.md index 98214195..c6acc1af 100644 --- a/production/session-state/active.md +++ b/production/session-state/active.md @@ -12,6 +12,14 @@ ## 当前状态快照(收口批先更新本节,再追加台账;≤10 行) +- **更新于**:2026-09-23(**关间大奖励+L2 收紧双刀批**,worktree hp-bonus-scan-20260923,批次 a4edb1e/合并 b39ee62,台账 134):用户确立**双合格线**(零强化过墙率得低+循环成长后逐渐上升达可观值)并指令数值判定改真实游玩口径(与并行批次 132/133 直入口退役同向衔接,本批扫描只跑 adventure+campaign 两段)。两刀——adventure.tres 关间大奖励 10→5;enemy.tres L2 群行 22→26×3/24→28+卓尔 112→130(B 包第 7 轮留档候选 L2 部分,L3 未动);满配锚 (400,200)→(900,400) 先例式抬锚(L2 抬血后旧档不再满通,11 项冒烟同根因连锁;抬血不够改抬攻)。读数(同种子 8000):零强化过第二关率 普通 15→2%✓/完美 40→15%(模拟上界,真人更低);营地循环爬升成立(普通档过 L2 第 4 局 0%→第 19 局 50%→第 37 局 100%,L3 第 31 局起通关)。用户拍板收敛转真人试玩;第三刀候选(卓尔 150)与检查点带重划留档。冒烟 553 绿三闸(worktree+合并后主区双跑——主区笔含 132/133 改动共存验证) + +- **更新于**:2026-09-23(**测量面去单关直入口批**,worktree measure-adventure-only,批次 d5783a5/合并 61874f7,台账 133):用户拍板续批——直入口模拟数据失真曾误导数值调优,全部测量链改造:verifier level 段删除,逐关读数改冒险条件口径派生(通关数/到达数);判定端直入口验收带退役(带重锚归曲线调参批,重锚前只测不判,营地检查点判定同批暂停);退役 level_monte_carlo/level_debug;run_level 降格机制夹具/单战锚专用(smoke 机制断言与 rhythm/defense/damage 单战扫描保留零改动)。--quick 端到端 36 局 2.7 分钟实证新口径(完美档逐关 87.5%→42.9%→0%)。冒烟 553/0 + doc 三闸对基线一致(8/7/1 既有) + +- **更新于**:2026-09-23(**单关测试直入口退役批**,worktree adventure-only-entry,批次 96cdc66/合并 7040dbc,台账 132):用户拍板唯一试玩入口 = 完整三关冒险——首页 L2/L3「测试直入口」两按钮摘除,`_start_full_level` 单关 UI 分支删除(headless 单关路径 `LevelRunner.start_level` 保留归 QA 工具面);ui_click_probe L2 行为段重接冒险真实路径(大奖励屏确认→推进 L2→岔路选路,加成 200/100→400/200);文档现行口径五处(存档序列化 v1.1 / 冒险结构 v0.8 / 03-内容规模 / entities.yaml / README),历史行与 level.tres 批注不动。冒烟 553 项 0 失败 + 四探针 PASS(点击探针种子 7/13 双绿)+ doc 三闸失败集与 master 基线逐项一致(8/7/1 既有) + +- **更新于**:2026-09-23(**数值重基线重投批**,纯测量零代码零决策,报告 production/qa/balance-verifier-20260923-033239.md,台账 131):B 包落籍后 verifier 全段重投(840 局·种子 8000 起·同口径可比,旧 840 局报告作废)——直入口:L1 普通 53% 落带✓ / L1 完美 78% 越上界 13(更松)/ L2 普通 5%·完美 12% 双穿下界(过调 45/23 点)/ L3 0–2% 带未定;零强化冒险通关普通 1/60·完美 4/60(旧 42%/48%),完美档最大败退点转移=L1·节点4·战斗×13;检查点 L1→L2 普通 90%/完美 80% 仍越上界(触发注入缩水至 血+6/攻+1——锻造基价 20 生效)。判读三结构:①「太容易」方向性修复(零强化通关 45%→2–7%,与第 7 轮 S0 全通关 6% 互洽);②形态转「L1 松/L2 崖/L3 墙」陡崖断层;③L2 强化梯度过陡(零强化 5%→微注入 90%,墙纸翻面无中间带)。归曲线调参批,待真人试玩手感并入定杠杆;产物与登记未提交待收口 + - **更新于**:2026-09-23(**美术清单复用盘点批**,worktree art-reuse-backfill-20260923,批次 b09f6d8,台账 130):用户拍板**复用优先**(能从公开素材站轻改复用的不去生成,尽可能少生成)。清单落三件——①§0 立**素材站复用渠道**(♻,CC0 优先)与**复用闸四道**(色板量化/禁入带吸色/灰度色弱可辨/授权干净);②新登记三条此前漏登需求:§3.4 增益状态效果图标 9 枚(♻ 通用图标改色+极性框,键族读 §4.6.1)、§3.5 营地与元进度件(钥石/永久强化图标/柜台贴图,归 UI 贴图重构批)、§3.6 字体(拉丁 Kenney CC0+中文缝合像素字体);③逐条目来源标注(必须自产=角色级/砖面语义件/徽章/样张;可复用=UI 九宫格/字体/粒子/节点图标/效果图标/纹理底噪);§5 补魔法道具图标(Alpha 后)与封面图(Alpha 后)排期。doc 三闸对基线一致(68/7/1) - **更新于**:2026-09-22(**美术圣经 §5 角色设计落地批 + 提示词卡 v2.0 重生成批**,worktree art-char-s5-20260922,批次 cf03cda,台账 129):用户拍板 B 正序(先补圣经 §5 角色章,再重生成提示词卡)。art-bible v1.6 新增 §5 角色设计——§5.1 剪影自 §3.1 迁入+禁黑描边固化 / §5.2 头身比体量档 / §5.3 护甲类型视觉区分候选方案(甲面覆盖率×甲材质色,清偿 §4.6.4 待设计项)/ §5.4 主角三态 / §5.5 八敌种逐卡 / §5.6 意图动画三档承载;comfyui-prompts.md v2.0 重生成——主角三态+八敌种逐资产自包含完整提示词(整段可直贴),继承 seed 纪律/禁入带/#F2F2F2,新增灰矮人/钩爪恐魔/灰矮人石君王三卡;清单与战斗表现引用随迁。doc 三闸对基线一致(68/7/1);§6–9(D1/D2/D4/D5)仍待后续批 @@ -349,3 +357,12 @@ 129. **美术圣经 §5 角色设计落地批 + 提示词卡 v2.0 重生成批(2026-09-22,本会话——用户问「美术圣经有对应素材的文生图 prompt 吗,想要每素材一段完整可直贴的 prompt」,呈报 v1.0 卡已删待圣经定调/圣经 §5 欠章两现状后拍板 B 正序「先补圣经 §5 角色章,再重生成 prompt 卡」;worktree art-char-s5-20260922,批次 cf03cda/合并 ff,纯文档)**:**art-bible v1.6 新增 §5 角色设计(D 框架 D3 落地)**——①§5.1 角色剪影与轮廓通道(自 §3.1 迁入:轮廓通道硬规则「亮色暖白描边+落影底盘」并随批固化「禁黑描边」+角色四类 archetype;道具点剪影留在 §3.1 并改题「道具点剪影」);②§5.2 头身比与体量档位(2~3 头身两档/普通<精英 Stri seed_val, level, "(关卡模式 · HP 延续)" if level_mode else ""] -# 关卡终局文案(result = victory/defeat;载荷 = runner level_finished 快照) -static func level_end_text(result: String, payload: Dictionary, effective_max_hp: int) -> String: - if result == "victory": - return "关卡通关!\n剩余 HP %d/%d" % [ - int(payload.get("hp", 0)), effective_max_hp] - return "关卡失败……探险者倒在了节点 %d(%s)。" % [ - int(payload.get("node_index", 0)) + 1, String(payload.get("node_type", ""))] - - # 调试战斗终局文案(level_end = 关内两层模式的关卡末) static func battle_end_text(result: String, level_end: bool) -> String: if level_end: diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd index de67f9f7..57c5f248 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/main.gd @@ -7,14 +7,14 @@ # debug_session.gd(规范 1.1 审视线 + 调试语义单一实现)。 # 组合根(composition root):唯一的模式流转与 core↔view 接线处。 # 职责边界:① 构建四区视图并接线信号(节点构建归 ui_assembler.gd——规范 1.1,本类只接线) -# ② 模式管理(完整关卡 关卡节点地图 runner / 调试两层——后者编排归 debug_session.gd;单场原语仅探针使用) +# ② 模式管理(正式冒险 AdventureRunner——唯一试玩入口;调试两层编排归 debug_session.gd;单场原语仅探针使用) # ③ 核心写调用只在此处发生(minesweeper.settle_batch / 刷新编排入口 / runner 推进; # E4 收口:加成值零表写——面板百分比经 runner.set_hero_override / debug_session 生效值 Callable # 以 encounter 参数入战斗,db.hero 运行期只读) # ④ 全屏 States 状态机(挖掘/结算/终局)与一次性提示去重。 # 2026-09-15 格面资源批:道具窗口与库存面板随可选类道具删除下线——E 区移除,窗口接线/选择序列删除。 # GP+商店房实施批(2026-09-21):商店覆盖层挂接与信号接线(装配器零信号连接纪律——句柄返回、 -# 本类连接,仿 lv2btn 模式)+ runner.wallet_changed 转发试玩日志(wallet 行族)+ A 区顶栏金币余额。 +# 本类连接)+ runner.wallet_changed 转发试玩日志(wallet 行族)+ A 区顶栏金币余额。 # 渲染与文案归 views/,核心状态→文案装配归 hud_presenter.gd 与 battle_narrator.gd,节点构建归 # ui_assembler.gd,模态层级归 modal_stack.gd,批量模拟编排归 tune_sim_controller.gd,调试模式编排归 # debug_session.gd——本类不拼呈现字符串。 @@ -31,7 +31,7 @@ const MetaProgressionScript := preload("res://core/meta_progression.gd") # 元 var db var settlement = null # 当前战斗编排器(关卡与调试模式统一读它) -var runner = null # 关卡节点地图 图版推进器(完整关卡模式;冒险模式 = 每关重取 adventure.runner()) +var runner = null # 关卡推进器(冒险模式每关重取 adventure.runner();单关 UI 直入口已退役——LevelRunner 仅存 headless 测试面) var adventure = null # 冒险结构编排器(冒险结构实现批——三关连探;转发信号照 runner 接线原样对接) var save_manager = null # 存档序列化承载(存档序列化批——启动读盘/冒险收束写盘;只经访问器与 apply 原语,禁读内部结构) var meta = null # 元进度账本服务(元进度实现批——余额/定价/购买/工坊解锁/Boss两档入账/注入计算;零信号纯被动) @@ -163,9 +163,7 @@ func _build_ui() -> void: var start: Dictionary = UiAssembler.build_start_overlay(self, db) _start_overlay = start.overlay _seed_edit = start.seed_edit - start.lvbtn.pressed.connect(_start_full_level.bind(1)) - start.lv2btn.pressed.connect(_start_full_level.bind(2)) - start.lv3btn.pressed.connect(_start_full_level.bind(3)) + start.lvbtn.pressed.connect(_start_adventure_from_menu) start.tunebtn.pressed.connect(_show_tune_panel) start.dbgbtn.pressed.connect(_start_debug_levels) start.campbtn.pressed.connect(_open_camp) @@ -216,36 +214,11 @@ func _input_locked() -> bool: or _start_overlay.visible or _inter_overlay.visible or settlement == null -# ==================== 完整关卡模式(关卡节点地图 图版推进器)==================== +# ==================== 冒险模式入口(唯一试玩入口——单关测试直入口退役 2026-09-23 用户拍板)==================== -func _start_full_level(level_index: int = 1) -> void: +func _start_adventure_from_menu() -> void: _start_overlay.visible = false - if level_index == 1: - _start_adventure() # 冒险首关即 L1——正式序列入口(冒险结构实现批) - return - # E4:加成经 runner.set_hero_override → encounter 参数入战斗(零表写——无双写叠加隐患) - runner = LevelRunner.new(db, get_node("/root/RngService")) - runner.set_hero_override(tune_panel.atk_pct(), tune_panel.hp_pct()) - runner.step_row.connect(_on_step_row) - runner.round_started.connect(_on_round_started) - runner.board_changed.connect(_on_board_changed) - runner.node_entered.connect(_on_runner_node) - runner.choices_presented.connect(_on_choices_presented) - runner.level_finished.connect(_on_level_finished) - runner.wallet_changed.connect(_on_wallet_changed) - _level_active = true - _adventure_mode = false - route_overlay.set_abandon_available(false) # 单关测试直入口无冒险可放弃(放弃语义对象 = 整局冒险) - _reset_run_scope() - log_view.clear() - var seed_val := _seed_value() - logger.start_session(seed_val) # 各战斗的 attach 在 _on_runner_node 内(settlement 逐战创建) - if not runner.start_level(level_index, seed_val): - _fatal_screen("关卡启动失败——见输出日志") - return - log_view.append_bb(Narrator.level_open_line(String(runner.level_row.get("display_name", "")), - seed_val, int(db.hero.atk), int(db.hero.max_hp), - tune_panel.atk_pct() > 0 or tune_panel.hp_pct() > 0)) + _start_adventure() # 冒险模式(三关连探——AdventureRunner 编排;转发信号签名与 runner 一致,接线照原样对接; @@ -322,28 +295,6 @@ func _on_runner_node(node: Dictionary, info: Dictionary) -> void: _refresh_presentations() -func _on_level_finished(payload: Dictionary) -> void: - _level_active = false - var result: String = String(payload.get("result", "")) - settlement = null - _close_modal(route_overlay) # 终局兜底(放弃入口新场景:选路层在开态——走模态栈恢复其遮挡面;未开过时 close 容错) - _sync_settlement_visuals() # → 全关 - info_panel.set_status_cleared_feedback() # 状态槽全清可见反馈(增益状态×4④) - stage.gray_all_enemies() # 死亡兜底:站桩灰化残位(禁瞬消语义的战斗收尾面) - if result == "victory": - # 胜利终局 overlay(金蜡封落于棋盘中央) - _end_overlay.open_victory(Narrator.level_end_text("victory", payload, runner.effective_max_hp()), - "返回冒险", board_view.get_global_rect()) - else: - _end_overlay.open_defeat(Narrator.level_end_text("defeat", payload, 0), - "返回", board_view.get_global_rect()) - logger.log_level_end(payload) # 试玩时间线:关卡终局 - runner.restore_hero_base() # 关卡结束——覆盖值归零(下次从面板重新应用) - strip_view.refresh(runner) - _open_modal(_end_overlay) - _refresh_presentations() - - # ---- 冒险模式终局面(大奖励屏 / 冒险结算屏——冒险结构实现批)---- # 大奖励兑付(非末关通关恰一次):复用 _inter_overlay(label + 确认按钮,零新增交互范式); @@ -364,7 +315,7 @@ func _on_adventure_finished(summary: Dictionary) -> void: info_panel.set_status_cleared_feedback() # 状态槽全清可见反馈(增益状态×4④) stage.gray_all_enemies() # 死亡兜底:站桩灰化残位(禁瞬消语义的战斗收尾面) # 存档入账(元进度实现批):settle = Boss 两档入账 + 工坊解锁 + 摘要入档 + 写盘(唯一写档点不变—— - # 单关测试入口与调试两层不经过本处理器,天然不写档不污染生涯数据)。 + # 调试两层不经过本处理器,天然不写档不污染生涯数据)。 var detail: Dictionary = {} if meta != null: detail = meta.settle_adventure(summary) @@ -490,7 +441,7 @@ func _show_board_fx_for_node(node_type: String = "") -> void: func _on_battle_finished(payload: Dictionary) -> void: - # 仅调试模式接线(完整关卡的结束归 关卡节点地图 runner._on_level_finished) + # 仅调试模式接线(冒险的关卡结束归 AdventureRunner._on_level_finished——大奖励/冒险终局分派) var result: String = String(payload.get("result", "")) _sync_settlement_visuals() # → 全关(battle_over 反馈面) stage.gray_all_enemies() # 死亡兜底:站桩灰化残位(禁瞬消语义的战斗收尾面) diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd index 7a827e03..366253a3 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/ui_assembler.gd @@ -85,7 +85,7 @@ static func build_overlays(host: Control, db, base_atk: int, base_hp: int) -> Di var end_overlay := BattleEndOverlay.new() host.add_child(end_overlay) - # 商店覆盖层(GP+商店房实施批 2026-09-21——商店房节点兑付呈现;按钮接线归组合根 lv2btn 模式) + # 商店覆盖层(GP+商店房实施批 2026-09-21——商店房节点兑付呈现;按钮接线归组合根,装配器零信号连接) var shop_overlay := ShopOverlay.new() host.add_child(shop_overlay) @@ -129,13 +129,9 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary: seed_edit.custom_minimum_size = Vector2(120, 0) seed_row.add_child(seed_edit) - # 冒险结构实现批(2026-09-21):lvbtn = 正式「开始冒险」入口(三关序列);L2/L3 保留测试直入口 + # 唯一试玩入口 = 正式「开始冒险」(三关序列);单关测试直入口(L2/L3)退役(2026-09-23 用户拍板) var lvbtn := UiKit.button("▶ 开始冒险(三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城)") box.add_child(lvbtn) - var lv2btn := UiKit.button("▶ 测试直入口 · 第二关 · 幽暗地域(分支节点图试玩——岔路口选下一跳)") - box.add_child(lv2btn) - var lv3btn := UiKit.button("▶ 测试直入口 · 第三关 · 灰矮人矿城(基线红档属预期,配合调整板加成试玩)") - box.add_child(lv3btn) var tunebtn := UiKit.button("测试用 · 角色数值调整板(模拟天赋树属性提升)") box.add_child(tunebtn) var dbgbtn := UiKit.button("调试 · 连续关卡两层(HP 关内延续)") @@ -151,7 +147,7 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary: box.add_child(help) return {"overlay": overlay, "box": box, "seed_edit": seed_edit, - "lvbtn": lvbtn, "lv2btn": lv2btn, "lv3btn": lv3btn, "tunebtn": tunebtn, "dbgbtn": dbgbtn, + "lvbtn": lvbtn, "tunebtn": tunebtn, "dbgbtn": dbgbtn, "campbtn": campbtn} diff --git a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd index 53e7f852..3405a5a6 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/presentation/views/route_overlay.gd @@ -7,7 +7,7 @@ # 无任何写面;图形为程序化占位质量(占位纪律)。 # 放弃入口(2026-09-21 用户拍板「放弃接口也要有」——台账 119;推翻 冒险结构.md「MVP 无界面入口」 # 后置条款):选路停点 = 天然非战斗期(接口契约:战斗中放弃一律拒绝),按钮常驻本层底部; -# 可见性归组合根(冒险模式开、单关测试直入口关——放弃的语义对象是"整局冒险")。 +# 可见性归组合根(只在冒险模式开——放弃的语义对象是"整局冒险";调试两层无节点图天然不可达)。 class_name RouteOverlay extends Control @@ -25,7 +25,7 @@ const NODE_LABELS := {"battle": "战", "reward": "赏", "rest": "疗", "boss": " var _runner = null var _btn_box: VBoxContainer var _title: Label -var abandon_btn: Button # 放弃入口(可见性归组合根 set_abandon_available——冒险模式开/单关测试直入口关) +var abandon_btn: Button # 放弃入口(可见性归组合根 set_abandon_available——只在冒险模式开) func _init() -> void: @@ -58,7 +58,7 @@ func _init() -> void: visible = false -# 放弃入口可见性(组合根在冒险启动/单关直入口启动时切换——语义对象 = 整局冒险) +# 放弃入口可见性(组合根在冒险启动时开、默认关——语义对象 = 整局冒险) func set_abandon_available(v: bool) -> void: abandon_btn.visible = v diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/board_stat_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/board_stat_probe.gd index ac146da0..7f75e7de 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/board_stat_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/board_stat_probe.gd @@ -3,7 +3,7 @@ # 棋盘板形统计探针(清图支配性对账重跑批取数工具——判式"实测板形"口径的数据源): # 对 board_gen.tres 每行 (L, D) 生成 N 张板,统计幸存雷数 |M| 与安全格数 |S| # 的均值 / 最小 / 最大("先布后删"后的落地值——名义值 density×(W×H−9) 不含删除段)。 -# 只读诊断,零游戏代码改动;装载面与 level_monte_carlo 同源(config_db.load_tables)。 +# 只读诊断,零游戏代码改动;装载面与冒险扫描工具同源(config_db.load_tables)。 # 运行:Godot_console.exe --headless --path . --script res://smoke/board_stat_probe.gd -- [N] [seed0] extends SceneTree diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_autoplay.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/level_autoplay.gd index 0d93034f..6bd14add 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_autoplay.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/level_autoplay.gd @@ -2,9 +2,12 @@ # Date: 2026-09-11(2026-09-12 增完整遥测接线——用户要求:任何模拟运行与真人试玩同日志合规: # 操作记录 / 轮次状态 / 战斗结束 / 通关结束 全量 JSONL。logger=null 时自建会话(每局一文件), # 批量调用方传共享 logger(log_run 局次标记切分)。 -# 关卡自动通关策略(理性玩家近似)——呈现层数值调整板的批量模拟与 headless 期望扫描(level_monte_carlo) +# 关卡自动通关策略(理性玩家近似)——呈现层数值调整板的批量模拟与 headless 扫描 # 共用同一实现,保证"面板模拟读数"与"扫描表读数"同口径。策略与 smoke_all 战斗自动玩家同族: # 挖最近可挖格 / 无可挖停手 / 奖励恢复点立即确认。 +# 2026-09-23 单关直入口口径退役(用户拍板):run_level 降格为机制夹具/单战锚点专用 +# (smoke_all 机制断言、rhythm/defense/damage 单战扫描)——通关率/难度类测量禁用本入口 +# (满血零上下文进关,与真实冒险条件通关率脱节),一律走 run_adventure。 # 2026-09-15 格面资源批:道具窗口选择与可选类获取计数随可选类道具删除下线。 # 2026-09-14 增完美策略档(policy="perfect",默认 "normal" 零行为变更——既有调用方签名兼容): # 零盲挖/全标旗/卡死刷新——上界测量仪,求解器与动作语义见 auto_player.gd 完美策略档节。 @@ -14,24 +17,21 @@ # 2026-09-21 冒险结构实现批:run_adventure 三关连探驱动(AdventureRunner——主种子恰一次、 # 大奖励立即确认 continue_to_next_level、adventure_finished 置 result/summary;外层每关重取 # runner 实例经 _drive_level 复用单关驱动)。run_level 驱动段抽成 _drive_level——签名与 -# 返回结构零变化,行为逐位不变(MC 同种子对照闸承载)。 -# 2026-09-23 换算率标定批:run_level 增 hero_override 尾参(永久强化 flat 注入透传至 -# LevelRunner.start_level——缺省 {} 与既有调用方逐位一致零行为变更,契约同 run_adventure 同名尾参; -# 采集端 verifier_batch.gd inject 档消费,服务换算率标定 OFAT 读数)。 -# 运行前提:db 已 load_tables;每个 run_level 全新 RngService(同种子 ⇒ 全程逐步可回放)。 +# 返回结构零变化,行为逐位不变。 +# 运行前提:db 已 load_tables;run_level/run_adventure 均须全新 RngService(同种子 ⇒ 全程逐步可回放)。 # 实现注:信号处理体全部为静态方法 + bind 传状态——GDScript 多行 lambda 内嵌 match/控制流的解析不可靠。 extends RefCounted const AutoPlayer := preload("res://smoke/auto_player.gd") # O4 收口:自动玩家策略单一实现 -static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct: int, collect_rows: bool = false, logger = null, policy: String = "normal", route: String = "min", hero_override: Dictionary = {}) -> Dictionary: +static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct: int, collect_rows: bool = false, logger = null, policy: String = "normal", route: String = "min") -> Dictionary: var own_session := logger == null if own_session: logger = load("res://presentation/playtest_logger.gd").new() logger.start_session(seed_val) logger.ap_per_round = int(db.action_economy.ap_per_round) - logger.log_run({"seed": seed_val, "level_index": level_index, "atk_pct": atk_pct, "hp_pct": hp_pct, "policy": policy, "route": route, "hero_override": hero_override}) + logger.log_run({"seed": seed_val, "level_index": level_index, "atk_pct": atk_pct, "hp_pct": hp_pct, "policy": policy, "route": route}) var rng = load("res://core/rng_service.gd").new() rng.set_master_seed(seed_val) var runner = load("res://core/level_runner.gd").new(db, rng) @@ -47,7 +47,7 @@ static func run_level(db, seed_val: int, level_index: int, atk_pct: int, hp_pct: runner.node_entered.connect(_on_node_entered.bind(runner, st, logger)) runner.level_finished.connect(_on_level_finished.bind(st, logger)) runner.set_hero_override(atk_pct, hp_pct) - if not runner.start_level(level_index, seed_val, hero_override): + if not runner.start_level(level_index, seed_val): st.result = "start_failed" runner.restore_hero_base() if own_session: diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_debug.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/level_debug.gd deleted file mode 100644 index ca7a3642..00000000 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_debug.gd +++ /dev/null @@ -1,34 +0,0 @@ -# VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11 -# 单关卡诊断:跑一遍完整关卡并打印进度与统计(定位挂起/数值问题的临时工具)。 -# 运行:Godot_console.exe --headless --path . --script res://smoke/level_debug.gd -- [seed] [atk%] [hp%] -extends SceneTree - - -func _initialize() -> void: - var args := OS.get_cmdline_user_args() - var seed_val := 4200 - var atk_pct := 0 - var hp_pct := 0 - if args.size() >= 1 and args[0].is_valid_int(): - seed_val = int(args[0]) - if args.size() >= 2 and args[1].is_valid_int(): - atk_pct = int(args[1]) - if args.size() >= 3 and args[2].is_valid_int(): - hp_pct = int(args[2]) - var db = load("res://core/config_db.gd").new() - if not db.load_tables("res://data/tables", false): - print("表加载失败") - for d in db.diagnostics(): - if d.severity == "error": - print(" error: [%s] %s" % [d.category, d.message]) - quit(1) - return - var autoplay = load("res://smoke/level_autoplay.gd") - var t0 := Time.get_ticks_msec() - print("开始:seed=%d atk+%d%% hp+%d%%" % [seed_val, atk_pct, hp_pct]) - var st = autoplay.run_level(db, seed_val, 1, atk_pct, hp_pct) - print("结果: %s · 用时 %.2f 秒" % [st.result, float(Time.get_ticks_msec() - t0) / 1000.0]) - print(" 战斗节点=%d 轮数=%d 整关承伤=%d 剩余HP=%d 进BossHP=%d 踩雷=%d" % [st.battles, st.rounds, st.hero_dmg, st.hp_left, st.hp_at_boss, st.mine_hits]) - print(" 败北节点=%d(%s) 恢复点回复=%d(前HP %d)" % [st.defeat_node_index, st.defeat_node_type, st.rest_healed, st.hp_before_rest]) - quit(0) diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_debug.gd.uid b/prototypes/dungeon-sweeper-vertical-slice/smoke/level_debug.gd.uid deleted file mode 100644 index 3656d79b..00000000 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_debug.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://bflo5h8xysqsl diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_monte_carlo.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/level_monte_carlo.gd deleted file mode 100644 index e922ad9b..00000000 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_monte_carlo.gd +++ /dev/null @@ -1,169 +0,0 @@ -# VERTICAL SLICE - NOT FOR PRODUCTION -# Date: 2026-09-11 -# 关卡期望扫描(难度曲线与Boss 调参期关卡侧批量工具的原型——对应 棋盘生成 F4 / 战斗侧 monte_carlo.gd): -# 扫描 atk% × hp% 网格(模拟天赋树数值提升档位),输出每档"通关率 / 整关承伤期望 / 败北节点分布 / -# 通关剩余 HP 期望 / 进 Boss HP 期望 / 平均轮数"——把"多少数值能通关、通关要掉多少血"变成可测量数据。 -# 运行:Godot_console.exe --headless --path . --script res://smoke/level_monte_carlo.gd -- [N] [seed0] [normal|perfect|both] [level_index] [shared|unique] -# 种子模式(2026-09-19 掷点测量修复批 A 案):shared(默认,旧行为)= 同批次全部格子×策略共用种子 -# seed0+i——同种子历史坐标可比,但同一 (种子, scope) 被反复消费,聚合掷点统计被头部窗口彩票放大 -# (验收重测批实证);unique = 逐局独立种子(seed0 + 全局递增序号),每个掷点恰消费一次 → 聚合 -# 掷点统计回归标准二项分布(±2σ gate 口径重新有效)。验收掷点面用 unique;同种子 A/B 对照用 shared。 -extends SceneTree - - -var _run_cursor := 0 # unique 模式全局局序号(seed = seed0 + cursor) - - -func _initialize() -> void: - var args := OS.get_cmdline_user_args() - var n := 30 - if args.size() >= 1 and args[0].is_valid_int(): - n = maxi(5, int(args[0])) - var seed0 := 4200 - if args.size() >= 2 and args[1].is_valid_int(): - seed0 = int(args[1]) - # 关卡轴(分支节点图批 2026-09-17:L2 幽暗地域图版扫描——第 4 参 level_index,默认 1 零行为变更) - var level_arg := 1 - if args.size() >= 4 and args[3].is_valid_int(): - level_arg = maxi(1, int(args[3])) - var db = load("res://core/config_db.gd").new() - if not db.load_tables("res://data/tables", false): - print("表加载失败") - quit(1) - return - # 共享日志会话(2026-09-12 用户要求:模拟运行与真人试玩同日志合规——操作/轮次/战斗/通关全量 JSONL, - # 一文件多局,run 行携带种子/档位切分局次) - var logger = load("res://presentation/playtest_logger.gd").new() - logger.ap_per_round = int(db.action_economy.ap_per_round) - var log_path: String = logger.start_session(seed0) - print("模拟日志: %s" % log_path) - var autoplay = load("res://smoke/level_autoplay.gd") - var t0 := Time.get_ticks_msec() - # 策略轴(2026-09-14 OQ7 完美策略档——技能轴上界测量):normal = 原理性玩家近似; - # perfect = 零盲挖/全标旗/卡死刷新(auto_player.gd 完美策略档节);both = 双档对照。 - var policy_arg := "normal" - if args.size() >= 3 and args[2] in ["normal", "perfect", "both"]: - policy_arg = args[2] - var policies: Array = ["normal"] - if policy_arg == "perfect": - policies = ["perfect"] - elif policy_arg == "both": - policies = ["normal", "perfect"] - # 种子模式(掷点测量修复批 A 案——见文件头注记):缺省 shared = 旧行为零变更 - var seed_mode := "shared" - if args.size() >= 5 and args[4] in ["shared", "unique"]: - seed_mode = args[4] - # 基线格模式(2026-09-20 重投批工具口径):第 6 参 baseline = 只跑 atk0/hp0 一格—— - # 全网格 10 格在大 N 下成本不可行(~1.35s/局),基线判读只需零加成格的大样本精度 - var baseline_only := false - if args.size() >= 6 and args[5] == "baseline": - baseline_only = true - var atk_axis: Array = [0, 50, 100, 150, 200] - var hp_axis: Array = [0, 100] - if baseline_only: - atk_axis = [0] - hp_axis = [0] - var seed_label := "种子 %d+%d" % [seed0, n] if seed_mode == "shared" else "种子 %d 起逐局独立" % seed0 - print("=== 关卡期望扫描:level %d · N=%d/格 · %s · 策略=%s · 种子模式=%s ===" % [level_arg, n, seed_label, policy_arg, seed_mode]) - print("%-6s %-10s %-8s %-14s %-14s %-14s %-10s %-12s %-12s %-10s %-10s %-8s %-8s" % ["策略", "atk%/hp%", "通关率", "整关承伤均/p90", "通关剩余HP均(胜)", "进BossHP均", "平均轮数", "踩雷/战", "普通承伤/场%", "跳战率", "Boss承伤%", "踩雷/局", "刷新/局"]) - var perfect_mine_total := 0 # 完美档构造保证 = 零踩雷(只挖已证安全格)——扫描末断言 - for policy in policies: - var tag := "基线" if policy == "normal" else "完美" - for atk_pct in atk_axis: - for hp_pct in hp_axis: - var wins := 0 - var dmg_all: Array = [] - var hp_left_win: Array = [] - var hp_boss: Array = [] - var rounds_all: Array = [] - var mines_per_battle: Array = [] - var normal_dmg_pct: Array = [] # 每普通战斗承伤占生效 max_hp 比(难度曲线与Boss F4 口径——≤20% 带) - var boss_dmg_pct: Array = [] # Boss 战承伤占生效 max_hp 比(难度曲线与Boss F4 口径——≤50% 带) - var wipes := 0 # 普通战斗 round-1 即胜数(首轮全灭跳战——拍板④观测面) - var normal_battles := 0 - var death_nodes := {} - var mine_per_run: Array = [] - var refresh_per_run: Array = [] - for i in range(n): - var seed_val := seed0 + i if seed_mode == "shared" else seed0 + _run_cursor - _run_cursor += 1 - var st = autoplay.run_level(db, seed_val, level_arg, atk_pct, hp_pct, true, logger, policy) - dmg_all.append(st.hero_dmg) - rounds_all.append(st.rounds) - mine_per_run.append(int(st.mine_hits)) - refresh_per_run.append(int(st.refreshes)) - mines_per_battle.append(float(st.mine_hits) / float(maxi(1, st.battles))) - var eff_max := maxi(1, int(round(float(db.hero.max_hp) * (100.0 + float(hp_pct)) / 100.0))) - # 逐战斗承伤切分(round_index 回卷 = 新战斗;末段 = Boss 战——当且仅当本局抵达 Boss 节点) - var segs := _damage_segments(st.rows) - for k in segs.size(): - var pct := 100.0 * float(segs[k].dmg) / float(eff_max) - if k == segs.size() - 1 and int(st.hp_at_boss) >= 0: - boss_dmg_pct.append(pct) - else: - normal_dmg_pct.append(pct) - normal_battles += 1 - if bool(segs[k].r1_win): - wipes += 1 - if st.result == "victory": - wins += 1 - hp_left_win.append(st.hp_left) - hp_boss.append(st.hp_at_boss) - elif st.result == "defeat": - var key := "%d.%s" % [st.defeat_node_index, st.defeat_node_type] - death_nodes[key] = int(death_nodes.get(key, 0)) + 1 - var death_txt := "—" - if not death_nodes.is_empty(): - var parts: Array = [] - for k in death_nodes.keys(): - parts.append("%s×%d" % [k, death_nodes[k]]) - death_txt = " ".join(parts) - var mine_mean := _mean(mine_per_run) - if policy == "perfect": - perfect_mine_total += int(round(mine_mean * float(n))) - print("%-6s atk%+3d%% hp%+3d%% %5.0f%% %6.1f / %-6.1f %6.1f %6.1f %6.1f %5.2f %6.1f %5.0f%% %6.1f %6.2f %6.2f %s" % [ - tag, atk_pct, hp_pct, 100.0 * float(wins) / float(n), - _mean(dmg_all), _p90(dmg_all), _mean(hp_left_win), _mean(hp_boss), _mean(rounds_all), _mean(mines_per_battle), - _mean(normal_dmg_pct), 100.0 * float(wipes) / float(maxi(1, normal_battles)), _mean(boss_dmg_pct), mine_mean, _mean(refresh_per_run), death_txt]) - print("(F4 带:承伤 ≤20%%/普通场 · ≤50%%/Boss 场,占生效 max_hp · F5 带:基线通关率 L1 [35,55]%% / L2 [25,45]%%——2026-09-20 用户拍板分带 · 跳战率 = 普通战斗 round-1 即胜(首轮全灭)占比 · 承伤含败者至死 · 败北节点 0-3=战斗节点序 4=Boss · 踩雷/战=每战斗负向兑付触发期望(格面资源批口径) · 完美档 = 技能轴上界测量(零盲挖/全标旗/卡死刷新——口径见 auto_player.gd)· 耗时 %.1f 秒)" % [float(Time.get_ticks_msec() - t0) / 1000.0]) - if "perfect" in policies and perfect_mine_total > 0: - push_error("[level_monte_carlo] 完美策略档出现踩雷 %d 次——构造保证被破坏(只挖已证安全格),求解器/驱动有缺陷" % perfect_mine_total) - quit(1) - return - logger.close_session() - quit(0) - - -# 逐战斗段切分:round_index 回卷 = 新战斗(defense_scan 同口径) -# 每段 = {dmg: 英雄承伤合计, r1_win: round-1 即胜(首轮全灭跳战签名——verdict 胜利行 value=1)} -func _damage_segments(rows: Array) -> Array: - var segs: Array = [] - var last_round := 0 - for row in rows: - var r: int = int(row.get("round_index", 0)) - if segs.is_empty() or r < last_round: - segs.append({"dmg": 0, "r1_win": false}) - last_round = r - var seg: Dictionary = segs[segs.size() - 1] - if String(row.get("type", "")) == "damage" and String(row.get("source_class", "")) == "enemy_action": - seg.dmg = int(seg.dmg) + int(row.get("value", 0)) - if String(row.get("type", "")) == "verdict" and r == 1 and int(row.get("value", 0)) == 1: - seg.r1_win = true - return segs - - -func _mean(a: Array) -> float: - if a.is_empty(): - return 0.0 - var t := 0.0 - for v in a: - t += float(v) - return t / float(a.size()) - - -func _p90(a: Array) -> float: - if a.is_empty(): - return 0.0 - var b := a.duplicate() - b.sort() - return float(b[mini(b.size() - 1, int(0.9 * b.size()))]) diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_monte_carlo.gd.uid b/prototypes/dungeon-sweeper-vertical-slice/smoke/level_monte_carlo.gd.uid deleted file mode 100644 index b5b3319a..00000000 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/level_monte_carlo.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://h3mghae7yvvx diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd index 9bfdea57..36322a49 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/smoke_all.gd @@ -124,7 +124,7 @@ func _smoke_adventure_table() -> void: func _smoke_adventure_api() -> void: print("--- 冒险结构 API 闸(重复开始拒绝 · 放弃两态受理)---") var adr = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(42)) - adr.set_hero_override(400, 200) # 首战速胜档(放弃的非战斗受理要走到选路态) + adr.set_hero_override(900, 400) # 首战速胜档(放弃的非战斗受理要走到选路态) check(adr.start_adventure(42), "冒险启动受理(主种子注入恰一次——state=running)") check(not adr.start_adventure(43), "进行中重复 start_adventure 拒绝(重开须待结算完毕)") check(adr.runner().current_battle() != null, "首战在飞(接口①开始关卡直达战斗节点)") @@ -170,10 +170,10 @@ func _smoke_adventure() -> void: miss += 1 check(miss == 0, "行集内每个战斗/Boss 节点在 board_gen + enemy 有精确行(缺失 %d)" % miss) # ② 满配通关 + ④ 大奖励兑付(恰 2 次 · 读数=表值 · 回满=新上限 · 覆盖值通道传播 L2/L3 首战上限) - var st: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) var sum: Dictionary = st["summary"] check(String(st["result"]) == "completed" and bool(sum.get("cleared", false)), - "满配通关(42 / atk+400 / hp+200——cleared=true;v2 怪阶梯后旧 200/100 档不再满配)") + "满配通关(42 / atk+900 / hp+400——cleared=true;v2 怪阶梯后旧 200/100 档不再满配)") check(int(sum.get("levels_cleared", -1)) == 3, "通关几关 = 3(levels_cleared)") check(int(sum.get("keystone_total", -1)) == 3 * int(_db.adventure.keystone_per_level), "钥石合计 = 3 × keystone_per_level(%d)" % int(sum.get("keystone_total", -1))) @@ -191,7 +191,7 @@ func _smoke_adventure() -> void: reward_ok = false check(reward_ok, "大奖励读数:hp_bonus=表值 · 新上限累加 · 回满=新上限 · 钥石逐关注账") var seq: Array = st["encounter_max_hp_seq"] - var k := 3.0 # hp+200 ⇒ TunePanel 百分比后乘 ×3(加算先加、百分比后乘——生效次序口径) + var k := 5.0 # hp+400 ⇒ TunePanel 百分比后乘 ×5(加算先加、百分比后乘——生效次序口径) var exp_base := maxi(1, int(round(float(int(_db.hero.max_hp)) * k))) var exp_l2 := maxi(1, int(round(float(int(_db.hero.max_hp) + hp_bonus) * k))) var exp_l3 := maxi(1, int(round(float(int(_db.hero.max_hp) + 2 * hp_bonus) * k))) @@ -202,7 +202,7 @@ func _smoke_adventure() -> void: check(idx_l2 > 0 and idx_l3 > idx_l2, "L2/L3 首战上限入参 = 基础+加算(%d→%d——大奖励经覆盖值通道传播)" % [exp_l2, exp_l3]) # ③ 种子域可复现(同种子两局:summary + 上限序列 + 行进序列逐位一致) - var st2: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st2: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) check(st2["summary"] == sum and st2["encounter_max_hp_seq"] == seq and st2["visited_ids"] == st["visited_ids"], "同种子两局逐位可复现(summary/上限序列/行进序列——主种子单点派生)") @@ -242,7 +242,7 @@ func _smoke_adventure() -> void: "L2 败北败退明细:层号=2 · 节点在案(数值验证取数面 2026-09-22)") # ⑥ 重复宣布拒绝(settle 后再调 _on_level_finished——摘要零变化) var adr6 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(7)) - adr6.set_hero_override(400, 200) + adr6.set_hero_override(900, 400) check(adr6.start_adventure(7), "重复拒绝场景:冒险启动(seed 7)") var b6 = adr6.runner().current_battle() var st6 := _adv_st() @@ -273,7 +273,7 @@ func _smoke_adventure() -> void: var same := {} for s in range(42, 92): var a8 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(s)) - a8.set_hero_override(400, 200) + a8.set_hero_override(900, 400) if not a8.start_adventure(s): continue if _adv_drive_to_shop(a8, _adv_st(), autoplay): @@ -313,7 +313,7 @@ func _smoke_adventure() -> void: "同一公式两个落点逐位一致(LevelRunner.rest_heal_amount 内置默认)") # ⑩ 放弃(战斗中拒绝 · 非战斗期受理同失败型结算) var a10 = load("res://core/adventure_runner.gd").new(_db, _fresh_rng(15)) - a10.set_hero_override(400, 200) + a10.set_hero_override(900, 400) check(a10.start_adventure(15), "放弃场景:冒险启动(seed 15——首战在飞)") check(not a10.abandon(), "战斗中 abandon 拒绝(战斗域单事务在飞)") var b10 = a10.runner().current_battle() @@ -2907,7 +2907,7 @@ func _smoke_shop_room() -> void: var shop_run := {} for s in range(42, 92): var runner = load("res://core/level_runner.gd").new(_db, _fresh_rng(s)) - runner.set_hero_override(400, 200) # 行进段快速通关档(购买断言与百分比轴正交——加算区单独断言) + runner.set_hero_override(900, 400) # 行进段快速通关档(购买断言与百分比轴正交——加算区单独断言) runner.start_level(2, s) var st := {"result": "", "rounds": 0, "refreshes": 0, "mine_hits": 0, "hero_dmg": 0, "policy": "normal"} var guard := 40 @@ -3481,7 +3481,7 @@ func _smoke_save() -> void: # ⑨ 摘要集成(冒险结构批产物驱动):run_adventure 真局摘要 → apply 原语 → 域读数 → 写盘读回保持 var autoplay = load("res://smoke/level_autoplay.gd") - var st9: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st9: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) var f9 = sm_script.new(paths[8]) f9.apply_adventure_summary(st9.get("summary", {})) var kpl := int(_db.adventure.keystone_per_level) @@ -3492,7 +3492,7 @@ func _smoke_save() -> void: "集成三关首杀标记齐") check(f9.recent_summaries().size() == 1 and int(f9.recent_summaries()[0].get("master_seed", -1)) == 42, "集成 recent 1 条且 seed 42") - var st9b: Dictionary = autoplay.run_adventure(_db, 42, 400, 200) + var st9b: Dictionary = autoplay.run_adventure(_db, 42, 900, 400) f9.apply_adventure_summary(st9b.get("summary", {})) check(f9.clear_count(1) == 2 and f9.clear_count(2) == 2 and f9.clear_count(3) == 2, "第二局后通关次数全 2") check(f9.keystone_balance() == 6 * kpl, "第二局后余额翻倍(6 × keystone_per_level)") diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd index f0646c99..c4f5c487 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_click_probe.gd @@ -24,7 +24,7 @@ var _tested_legend := false var _tested_review := false var _tested_refresh_chain := false var _tested_tooltip := false -var _tested_l2 := false # 分支节点图批:L2 入口行为段(首页直入口 + 岔路选路真实点击) +var _inter_confirms := 0 # 大奖励屏确认计数(冒险推进停点——首见确认推进 L2,再见 = L2 通关收口) var _route_clicks := 0 # 选路覆盖层点击计数(岔路使用率观测面) @@ -84,9 +84,9 @@ func _ready() -> void: var iso_reset = load("res://core/save_manager.gd").new("user://smoke_click_probe_reset.json") iso_reset.load_from_disk() main.meta = load("res://core/meta_progression.gd").new(main.db, iso_reset) - main.tune_panel.set_sliders(200, 100) + main.tune_panel.set_sliders(400, 200) # 高加成保 L1 可通关——L2 岔路选路段只能经冒险推进到达(单关直入口退役) var t1 := Time.get_ticks_msec() - main._start_full_level() + main._start_adventure_from_menu() var t_entry := Time.get_ticks_msec() - t1 # 性能 AC:进入战斗屏到首格可点 ≤500ms(棋盘 install 完成口径); # 场景实例化冷启动总时长(含全部脚本首载编译——引擎启动域,非 AC 口径)另列观测 @@ -98,7 +98,7 @@ func _ready() -> void: _problems.append("首格未可点(cells=0)") print("[click_probe] 首格可点计时 %dms(进入战斗屏口径,≤500ms AC)· 场景冷启动 %dms(含 UI 构建 %dms,观测项)" % [ first_cell_ms, t_total, t_ui_ready]) - var action_budget := 9000 + var action_budget := 20000 while not _done and action_budget > 0: action_budget -= 1 await get_tree().process_frame @@ -117,24 +117,33 @@ func _ready() -> void: main.shop_overlay.leave_pressed.emit() _flags_placed.clear() continue + if main._inter_overlay.visible: + # 大奖励屏(冒险级停点——非末关通关恰一次):首见确认推进 L2(真实按钮信号路径);再见 = L2 已通关,收口 + if not main._input_locked(): + _problems.append("大奖励屏打开时输入未锁定") + _inter_confirms += 1 + if _inter_confirms == 1: + var next_btn: Button = _find_button_by_prefix(main._inter_overlay, "进入下一层") + if next_btn == null: + _problems.append("大奖励屏确认按钮缺失") + else: + next_btn.pressed.emit() + await get_tree().process_frame + await get_tree().process_frame + if main.runner == null or int(main.runner.level_row.get("level_index", -1)) != 2: + _problems.append("大奖励确认后未推进到第二关(level_index != 2)") + else: + _done = true + print("[click_probe] 第二关大奖励屏(L2 通关)——探针收口 · 选路口点击 %d 次" % _route_clicks) + break + _flags_placed.clear() + continue if main._end_overlay.is_open(): - # 终局 overlay 模态断言(pattern 6:打开时输入锁定) + # 冒险终局(失败/放弃/打穿)——单关直入口退役后无二段入口,见终局即收口(模态断言照旧) if not main._input_locked(): _problems.append("终局 overlay 打开时输入未锁定") - if not _tested_l2: - # L1 终局 → 首页直入口切换 L2(分支节点图批行为段:真实"返回"路径 + start_level(2)) - _tested_l2 = true - print("[click_probe] L1 结束:%s——切换关卡 2 试玩入口" % main._end_overlay.verdict_text().replace("\n", " ")) - main._on_battle_end_continue() # 终局出口(真实"返回"按钮处理器——全量清理回开始层) - if not main._start_overlay.visible: - _problems.append("终局返回后未回到开始覆盖层") - main.tune_panel.set_sliders(200, 100) - main._start_full_level(2) - if main.runner == null or int(main.runner.level_row.get("level_index", -1)) != 2: - _problems.append("关卡 2 直入口启动失败(level_index != 2)") - continue _done = true - print("[click_probe] 关卡结束:%s · 选路口点击 %d 次" % [ + print("[click_probe] 冒险终局:%s · 选路口点击 %d 次" % [ main._end_overlay.verdict_text().replace("\n", " "), _route_clicks]) break if main.settlement == null or main.runner == null: diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_layout_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_layout_probe.gd index 5b08e6e7..c01d0d26 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_layout_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_layout_probe.gd @@ -10,7 +10,7 @@ func _ready() -> void: var main = load("res://presentation/main.tscn").instantiate() add_child(main) await get_tree().process_frame - main._start_full_level() + main._start_adventure_from_menu() for i in range(3): await get_tree().process_frame var win := get_window() diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd index 26fd3603..603a8655 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_probe.gd @@ -1,7 +1,7 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # 实现 GDD:design/ux/battle.md(场景级 headless 探针——四区布局实例化断言;entry 17②③)。 # Date: 2026-09-12(战斗屏改造批扩展;基础 = 2026-09-11 首战棋盘探针——既有断言全保留) -# 项目运行模式(autoload 在位)实例化 main.tscn,直接驱动 _start_full_level(), +# 项目运行模式(autoload 在位)实例化 main.tscn,直接驱动 _start_adventure_from_menu()(完整冒险——唯一试玩入口), # 断言四区真实构建(棋盘/进度条/主角站桩/敌方站桩/AP 点阵/明细带/数据框;E 区道具面板已删除; # 2026-09-20 全站桩拍板——英雄卡/敌人卡断言随站桩改造批换装)。 # 运行:Godot_console.exe --headless --path . res://smoke/ui_probe.tscn @@ -14,9 +14,9 @@ func _ready() -> void: add_child(main) await get_tree().process_frame var problems: Array = [] - # ---- 放弃入口(2026-09-21 用户拍板——台账 119):默认隐藏(单关测试直入口无冒险可放弃)---- + # ---- 放弃入口(2026-09-21 用户拍板——台账 119):默认隐藏(非冒险模式无冒险可放弃——开始层/调试两层)---- if main.route_overlay.abandon_btn == null or main.route_overlay.abandon_btn.visible: - print("[ui_probe] FAIL — 放弃按钮默认应隐藏(单关测试直入口关)") + print("[ui_probe] FAIL — 放弃按钮默认应隐藏(非冒险模式关)") get_tree().quit(1) return # ---- 营地覆盖层(元进度实现批——主菜单入口/开合/余额文案/购买禁用态; @@ -58,7 +58,7 @@ func _ready() -> void: var iso_zero = load("res://core/save_manager.gd").new("user://smoke_ui_probe_camp.json") iso_zero.load_from_disk() main.meta = load("res://core/meta_progression.gd").new(main.db, iso_zero) - main._start_full_level() + main._start_adventure_from_menu() await get_tree().process_frame await get_tree().process_frame # ---- 放弃入口·冒险模式可见 + 战斗中按下被拒(真实按钮路径——入口挂选路停点,战斗中拒绝为防御分支)---- diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_tune_probe.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_tune_probe.gd index 3ddc0802..17465696 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_tune_probe.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/ui_tune_probe.gd @@ -61,7 +61,7 @@ func _ready() -> void: # (攻击 ×2 / 生命 +50%)——旧缺陷(残留值被当基线再乘)在 encounter 参数链上同样被抓获 main.tune_panel.set_sliders(100, 50) main.tune_panel.press_apply_for_probe() - main._start_full_level() # 完整关卡路径(_start_single 按语义清零滑条 = 恒基线,不承载加成断言) + main._start_adventure_from_menu() # 完整冒险路径(唯一试玩入口;_start_single 按语义清零滑条 = 恒基线,不承载加成断言) await get_tree().process_frame await get_tree().process_frame var hero: Dictionary = main.settlement.presentation_snapshot().hero diff --git a/prototypes/dungeon-sweeper-vertical-slice/smoke/verifier_batch.gd b/prototypes/dungeon-sweeper-vertical-slice/smoke/verifier_batch.gd index cb8f5629..720a4555 100644 --- a/prototypes/dungeon-sweeper-vertical-slice/smoke/verifier_batch.gd +++ b/prototypes/dungeon-sweeper-vertical-slice/smoke/verifier_batch.gd @@ -1,23 +1,24 @@ # VERTICAL SLICE - NOT FOR PRODUCTION # Date: 2026-09-22(数值验证工具批——判定端 tools/balance_verifier.py 的数据源,本文件零判定逻辑) -# 三段一次采集,stdout 以「VJSON 」前缀行出机器读 JSON(其余行为人读进度/摘要): -# level 段 直入口单关基线(level_autoplay.run_level 零加成)——L1/L2/L3 × 双画像 × n, -# 供验收带判定(分带批 2026-09-20 口径:L1 普通 [35,55] / L2 普通 [25,45] / 完美 [35,65]) -# adventure 段 全冒险连探基线(run_adventure 零永久强化)× 双画像 × na——止步分布与败退节点 -# (摘要 defeat 明细 + 末场战斗敌方名),回答「零加成倒在第几层哪个节点」 +# 2026-09-23 单关直入口口径退役(用户拍板):原 level 段(直入口单关基线——满血零上下文进关, +# 与真实冒险的条件通关率脱节,曾误导曲线调参)整段移除;逐关难度读数由 adventure 段行内 +# levels_cleared/stopped_at 派生(判定端 analyze_adventure_levels),零补采。 +# 2026-09-23 换算率标定批:① adventure 段增 inject 注入档(永久强化 flat OFAT——标定换算率表的 +# 边际读数:每档与白板同种子流配对,逐关条件通关率差 = 该档的带平移量实测); +# ② campaign 段增 armor_first 花费序 + 行带 spend 标签(多轨迹合并采集按序分组)。 +# 两段一次采集,stdout 以「VJSON 」前缀行出机器读 JSON(其余行为人读进度/摘要): +# adventure 段 全冒险连探基线(run_adventure 零永久强化)× 双画像 × na——止步分布、败退节点 +# (摘要 defeat 明细 + 末场战斗敌方名)与逐关条件通关率派生源;inject 档行带 +# inject_tag/override(flat 三键) # campaign 段 营地循环战役 × 双画像 × k 局——SaveManager 隔离档 + MetaProgression 真实账本: # 逐局 hero_override() 注入 → 冒险 → settle_adventure 入账 → 花费策略买锻造, # 回答「累计几次通关冒险后下一关可过」(元进度换算率标定的模拟读数源) -# 2026-09-23 换算率标定批:① level 段增 inject 注入档(永久强化 flat OFAT——标定换算率表的 -# 边际读数:每档与基线同种子流配对,通关率差 = 该档的带平移量实测)+ levels 层裁剪; -# ② campaign 段增 armor_first 花费序(甲轴真实账本轨迹——护甲行强条目重测读数源)。 # 运行:Godot_console.exe --headless --path . --script res://smoke/verifier_batch.gd -- [k=v ...] -# n=60(直入口每格局数) na=40(基线冒险局数) k=40(战役局数) seed0=8000 -# only=level,adventure,campaign(缺省全段) spend=hp_first|atk_first|armor_first(锻造花费优先序) -# inject=max_hp:3,atk:1(直入口 flat 注入档——三键 {max_hp, atk, armor_class},缺省全零白板) -# levels=1,2,3(直入口层集——标定批只收 1,2,第三层带未定零判定面) +# na=40(基线冒险局数) k=40(战役局数) seed0=8000 +# only=adventure,campaign(缺省全段) spend=hp_first|atk_first|armor_first(锻造花费优先序) +# inject=max_hp:3,atk:1(冒险段 flat 注入档——三键 {max_hp, atk, armor_class},缺省全零白板) # 种子纪律:unique 逐局独立(掷点测量修复批 A 案——seed0 + 全局游标,每掷点恰消费一次)。 -# 同 seed0 跨档复用 = 配对读数(同序种子流——分析侧按局序配对消方差)。 +# 同 seed0 跨档复用 = 配对读数(同序种子流——分析侧按种子配对消方差)。 # 日志合规:全段共享 playtest_logger 会话(与真人试玩同日志),分析工具可直接消费。 # 存档红线:战役档用 user://verifier_campaign_<画像>.json 隔离路径,段首清陈旧段尾清理—— # 绝不碰 user://save.json(与 smoke 存档隔离纪律同源)。 @@ -46,48 +47,37 @@ func _initialize() -> void: print("模拟日志: %s" % log_path) var autoplay = load("res://smoke/level_autoplay.gd") var t0 := Time.get_ticks_msec() - var counts := {"level": 0, "adventure": 0, "campaign": 0} - if "level" in opt.only: - _seg_level(db, autoplay, logger, opt, counts) + var counts := {"adventure": 0, "campaign": 0} if "adventure" in opt.only: _seg_adventure(db, autoplay, logger, opt, counts) if "campaign" in opt.only: _seg_campaign(db, autoplay, logger, opt, counts) logger.close_session() - print("数值验证采集完成:level %d 局 · adventure %d 局 · campaign %d 局,耗时 %.1f 秒" - % [counts.level, counts.adventure, counts.campaign, float(Time.get_ticks_msec() - t0) / 1000.0]) + print("数值验证采集完成:adventure %d 局 · campaign %d 局,耗时 %.1f 秒" + % [counts.adventure, counts.campaign, float(Time.get_ticks_msec() - t0) / 1000.0]) quit(0) func _parse_args(args: PackedStringArray) -> Dictionary: - var opt := {"n": 60, "na": 40, "k": 40, "seed0": 8000, "only": "level,adventure,campaign", - "spend": "hp_first", "inject": "", "levels": "1,2,3"} + var opt := {"na": 40, "k": 40, "seed0": 8000, "only": "adventure,campaign", + "spend": "hp_first", "inject": ""} for a in args: var kv := String(a).split("=", true, 1) if kv.size() != 2: continue var key := String(kv[0]) if opt.has(key): - if key in ["only", "spend", "inject", "levels"]: + if key in ["only", "spend", "inject"]: opt[key] = String(kv[1]) else: opt[key] = int(kv[1]) var segs: Array = [] for s in String(opt.only).split(","): - if s in ["level", "adventure", "campaign"]: + if s in ["adventure", "campaign"]: segs.append(s) opt["only"] = segs if not SPEND_ORDERS.has(String(opt.spend)): opt["spend"] = "hp_first" - var lv: Array = [] - for s in String(opt.levels).split(","): - var li := int(s) - if li >= 1 and li <= 3 and not lv.has(li): - lv.append(li) - lv.sort() - if lv.is_empty(): - lv = [1, 2, 3] - opt["levels"] = lv opt["override"] = _parse_inject(String(opt.inject)) return opt @@ -102,6 +92,15 @@ func _parse_inject(raw: String) -> Dictionary: return out +# 注入档人读标签(白板 = "白板";行键 inject_tag 供判定端分档聚合) +func _inject_tag(ov: Dictionary) -> String: + var parts: Array = [] + for k in OVERRIDE_KEYS: + if int(ov.get(k, 0)) != 0: + parts.append("%s+%d" % [k, int(ov[k])]) + return "白板" if parts.is_empty() else ",".join(parts) + + func _next_seed(seed0: int) -> int: var s: int = seed0 + _cursor _cursor += 1 @@ -112,47 +111,22 @@ func _emit(row: Dictionary) -> void: print("VJSON " + JSON.stringify(row)) -# ---- level 段:直入口单关基线(零加成——分带批验收带判定的同口径读数); -# inject 档 = 同种子流配对的 OFAT 边际读数(换算率标定批——行带 override flat 三键) ---- +# ---- adventure 段:全冒险连探基线(零永久强化——止步分布/败退节点归因/逐关条件通关率派生源); +# inject 档 = 同种子流配对的 OFAT 边际读数(换算率标定批——行带 inject_tag/override flat 三键) ---- -func _seg_level(db, autoplay, logger, opt: Dictionary, counts: Dictionary) -> void: +func _seg_adventure(db, autoplay, logger, opt: Dictionary, counts: Dictionary) -> void: var ov: Dictionary = opt.override var tag := _inject_tag(ov) - for policy in ["normal", "perfect"]: - for li in opt.levels: - for i in range(int(opt.n)): - var seed_val := _next_seed(int(opt.seed0)) - var st: Dictionary = autoplay.run_level(db, seed_val, li, 0, 0, false, logger, policy, "min", ov) - _emit({ - "seg": "level", "level": li, "policy": policy, "seed": seed_val, - "inject_tag": tag, "override": ov.duplicate(), - "result": String(st.result), - "defeat_node_id": int(st.defeat_node_id), "defeat_node_type": String(st.defeat_node_type), - "battles": int(st.battles), "rounds": int(st.rounds), - }) - counts.level += 1 - print("进度 level 第%d层 %s %d/%d(%s)" % [li, policy, int(opt.n), int(opt.n), tag]) - - -# 注入档人读标签(白板 = "白板";行键 inject_tag 供判定端分档聚合) -func _inject_tag(ov: Dictionary) -> String: - var parts: Array = [] - for k in OVERRIDE_KEYS: - if int(ov.get(k, 0)) != 0: - parts.append("%s+%d" % [k, int(ov[k])]) - return "白板" if parts.is_empty() else ",".join(parts) - - -# ---- adventure 段:全冒险连探基线(零永久强化——止步分布与败退节点归因) ---- - -func _seg_adventure(db, autoplay, logger, opt: Dictionary, counts: Dictionary) -> void: for policy in ["normal", "perfect"]: for i in range(int(opt.na)): var seed_val := _next_seed(int(opt.seed0)) - var st: Dictionary = autoplay.run_adventure(db, seed_val, 0, 0, false, logger, policy, "min") - _emit(_adventure_row(st, policy, seed_val)) + var st: Dictionary = autoplay.run_adventure(db, seed_val, 0, 0, false, logger, policy, "min", ov) + var row := _adventure_row(st, policy, seed_val) + row["inject_tag"] = tag + row["override"] = ov.duplicate() + _emit(row) counts.adventure += 1 - print("进度 adventure %s %d/%d" % [policy, int(opt.na), int(opt.na)]) + print("进度 adventure %s %d/%d(%s)" % [policy, int(opt.na), int(opt.na), tag]) # 冒险局共用取数行(adventure/campaign 两段同构——summary 缺席 = 编排异常局,原样带 result 供判定端计异常) diff --git a/tools/balance_verifier.py b/tools/balance_verifier.py index a7460173..a79319ef 100644 --- a/tools/balance_verifier.py +++ b/tools/balance_verifier.py @@ -2,26 +2,25 @@ # -*- coding: utf-8 -*- r"""数值验证工具(判定端)——自动化评判 + 元进度爬升测量,替代「亲手试玩再反馈」循环。 -三段采集(数据源 = smoke/verifier_batch.gd,本文件驱动它并做全部判定): - level 段 直入口单关基线(零加成)——验收带判定;换算率标定批起支持 inject 注入档 - (永久强化 flat OFAT——同种子流配对读数,通关率差 = 带平移量实测) - adventure 段 全冒险连探基线(零永久强化)——止步分布 + 败退节点归因(层/节点/敌人) +两段采集(数据源 = smoke/verifier_batch.gd,本文件驱动它并做全部判定): + adventure 段 全冒险连探基线(零永久强化)——逐关条件通关率派生 + 止步分布 + 败退节点归因(层/节点/敌人); + 换算率标定批起支持 inject 注入档(永久强化 flat OFAT——与白板同种子流配对,行带 + inject_tag/override,标定面 = 逐关条件通关率差) campaign 段 营地循环战役(隔离档真实元进度账本:注入→冒险→收束入账→买锻造)——爬升曲线; - 换算率标定批起行带 spend 花费序标签(多轨迹合并采集按序分组判定) + 行带 spend 花费序标签(多轨迹合并采集按序分组判定) 评判标准(溯源): - ① 直入口基线通关率带(分带批 2026-09-20 用户拍板,难度曲线与Boss v0.16): - 第一层 普通 [35,55]% · 第二层 普通 [25,45]% · 完美档 [35,65]%(两关同带);第三层带未定——只测不判。 - 带平移(元进度定稿批口径):注入/锻造状态按 meta.tres 换算率表折算平移量后套用—— - 判读口径不变、带随解锁平移(表值驱动,本文件解析 meta.tres 取数,零硬编码)。 + ① 逐关条件通关率(冒险口径派生——打通 k-1 关才到达第 k 关,通关数/到达数):单关直入口口径 + (分带批 2026-09-20,难度曲线与Boss v0.16)满血零上下文进关,与真实冒险的条件通关率脱节, + 曾误导曲线调参——已随单关试玩入口一并退役(2026-09-23 用户拍板);旧带值锚定直入口读数不可比, + 带重锚归曲线调参批——重锚前本表只测不判。 ② 元循环目标(用户提案 2026-09-22,数字待确认):累计通过 5 次第 k 层的冒险后,第 k+1 层的 - 条件通关率(滑窗)应进入该层验收带——「5 次通过第一层的冒险后能过第二层;5 次通过第二层后能过第三层」。 - 第三层带未定,只给爬升曲线与首次读数,不出判定。 + 条件通关率(滑窗)应进入该层验收带——判定同①随口径退役暂停(重锚前只给滑窗读数与触发点)。 ③ 魔法道具面:道具工坊六件按通关次数解锁(阈值 1/1/2/2/3/3),局内效果未实装(归 Alpha 魔法道具批)—— 本工具只报解锁时点,不入判定。 - ④ 换算率标定(2026-09-23 批新增):OFAT 注入档 vs 白板的配对通关率差 → 每级平移量点估计±SE - → 与 meta.tres 现行表值对照、给建议投值。护甲行强条目:读数必须按解锁后参数实测(本段即重测面), - 不得用基线外推。 + ④ 换算率标定(2026-09-23 批新增):OFAT 注入档 vs 白板的同种子配对逐关条件通关率差 + → 每级带平移量点估计±SE(配对 bootstrap)→ 与 meta.tres 现行表值对照、给建议投值。 + 护甲行强条目:读数必须按解锁后参数实测(本段即重测面),不得用基线外推。 表值溯源(单一事实源 = meta.tres,本文件启动时解析——解析失败即 FAIL,不做静默兜底): · 锻造三档 flat(forge_products.flat_value)· 换算率三行(conversion.per_level_shift_pct) @@ -29,16 +28,19 @@ r"""数值验证工具(判定端)——自动化评判 + 元进度爬升测 · 工坊阈值(meta.tres workshop_items):1/1/2/2/3/3(本文件只做中文名映射,不消费数值) 用法: - python tools/balance_verifier.py # 全段默认规模(约 20–35 分钟) - python tools/balance_verifier.py --quick # 小规模快跑(约 5–10 分钟,读数精度低) - python tools/balance_verifier.py --n 100 --na 60 --k 60 --seed0 9000 --spend atk_first - python tools/balance_verifier.py --only level --levels 1,2 --inject max_hp:3 --n 100 + python tools/balance_verifier.py # 全段默认规模 + python tools/balance_verifier.py --quick # 小规模快跑(读数精度低) + python tools/balance_verifier.py --na 60 --k 60 --seed0 9000 --spend atk_first + python tools/balance_verifier.py --only adventure --inject max_hp:3 --na 100 python tools/balance_verifier.py --from-raw # 免重跑,对既有采集重新判定/出报告 输出:控制台判定结论 + production/qa/balance-verifier-<时间戳>.md(报告)+ 同名 .raw.jsonl(原始逐局数据)。 +兼容注:2026-09-23 前的旧 raw.jsonl 含 level 段(直入口单关)行——本版判定自动忽略, +逐关读数一律由冒险行派生。 """ import argparse import json import math +import random import re import subprocess import sys @@ -54,21 +56,19 @@ VJSON_PREFIX = "VJSON " ERROR_MARKERS = ("SCRIPT ERROR", "Parse Error") # ---- 判定标准区(溯源见文件头) ---- -LEVEL_BANDS = { - ("normal", 1): (35, 55), - ("normal", 2): (25, 45), - ("perfect", 1): (35, 65), - ("perfect", 2): (35, 65), -} +# 直入口验收带(原 LEVEL_BANDS)已随单关直入口口径退役(2026-09-23 用户拍板)—— +# 逐关/检查点判定全部暂停(judge_band 传 band=None = 只测不判),带重锚归曲线调参批。 +# 带重锚后换算率平移随之启用:带按 band_shift_for(override) 平移后套用(表值驱动,④ 段供数)。 CAMPAIGN_CLEARS_TARGET = 5 # 元循环检查点:累计通过第 k 层的冒险次数(用户提案 2026-09-22,待确认) CAMPAIGN_WINDOW = 10 # 检查点滑窗局数(条件通关率的窗口) CAMPAIGN_MIN_ATTEMPTS = 5 # 滑窗内少于此局数 = 数据不足(不出判定) LEVEL_CN = {1: "第一层", 2: "第二层", 3: "第三层"} NODE_TYPE_CN = {"battle": "战斗", "boss": "Boss", "rest": "恢复", "reward": "奖励", "shop": "商店房"} OVERRIDE_ATTRS = ["max_hp", "atk", "armor_class"] # 注入契约三键(词表同 MetaTable.FORGE_ATTRS) +ATTR_CN = {"max_hp": "生命上限", "atk": "基础攻击", "armor_class": "护甲等级"} +SPEND_CN = {"hp_first": "生命优先", "atk_first": "攻击优先", "armor_first": "护甲优先"} WORKSHOP_CN = {"probe_dust": "显影尘", "sapper_order": "工兵令", "loot_compass": "探宝罗盘", "nest_pendulum": "探巢摆钟", "catacomb_scroll": "地穴全图卷", "blast_kit": "爆破工兵包"} -SPEND_CN = {"hp_first": "生命优先", "atk_first": "攻击优先", "armor_first": "护甲优先"} # ---- meta.tres 表值(启动时解析——表值锚配置推导化:判定阈值随配置表走,零硬编码) ---- META_TRES = SLICE / "data" / "tables" / "meta.tres" @@ -148,7 +148,7 @@ def band_shift_for(override): def shifted_band(band, shift): - """验收带随平移量平移(clamp [0,100];band=None = 带未定不平移)。""" + """验收带随平移量平移(clamp [0,100];band=None = 带未定不平移——重锚前恒此态)。""" if band is None: return None return (max(0.0, band[0] + shift), min(100.0, band[1] + shift)) @@ -174,10 +174,9 @@ def pad(s, w, right=False): def collect(args): segs = args.only.split(",") cmd = [args.godot, "--headless", "--path", str(SLICE), "--script", SCRIPT, "--", - f"n={args.n}", f"na={args.na}", f"k={args.k}", f"seed0={args.seed0}", - f"only={args.only}", f"spend={args.spend}", - f"inject={args.inject}", f"levels={args.levels}"] - print(f"[数值验证] 采集启动({' · '.join(segs)},约 {args.est_min} 分钟)…") + f"na={args.na}", f"k={args.k}", f"seed0={args.seed0}", + f"only={args.only}", f"spend={args.spend}", f"inject={args.inject}"] + print(f"[数值验证] 采集启动({' · '.join(segs)},约 {args.est_min:.0f} 分钟)…") t0 = time.time() try: proc = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8", @@ -227,7 +226,7 @@ def binom_ci(wins, n): def judge_band(rate_pct, band): - """落带判定:返回 (结论, 是否达标)。band=None = 带未定,只报读数。""" + """落带判定:返回 (结论, 是否达标)。band=None = 带未定(直入口口径退役后待重锚),只报读数。""" if band is None: return "带未定(只测不判)", None lo, hi = band @@ -235,7 +234,7 @@ def judge_band(rate_pct, band): return f"越下界(低于 {lo}% 达 {lo - rate_pct:.1f} 点)", False if rate_pct > hi: return f"越上界(高于 {hi}% 达 {rate_pct - hi:.1f} 点)", False - return f"落带 [{lo},{hi}] ✓", True + return f"落带 [{lo:g},{hi:g}] ✓", True def node_label(defeat): @@ -257,31 +256,38 @@ def node_label(defeat): # ---------------------------------------------------------------- 分段分析 -def analyze_level(rows, baseline_only=False): - """直入口基线:按(画像, 层, 注入档)聚合计数。baseline_only=True 只留白板档(① 基线判定面)。""" - agg = {} - for r in rows: - if r.get("seg") != "level": - continue - tag = r.get("inject_tag", "白板") - if baseline_only and tag != "白板": - continue - key = (r["policy"], int(r["level"]), tag) - a = agg.setdefault(key, {"n": 0, "wins": 0, "deaths": {}, "override": r.get("override") or {}}) - a["n"] += 1 - if r.get("result") == "victory": - a["wins"] += 1 - elif r.get("result") == "defeat": - k = (int(r.get("defeat_node_id", -1)), r.get("defeat_node_type", "")) - a["deaths"][k] = a["deaths"].get(k, 0) + 1 - return agg +def valid_adventure_runs(rows, policy, baseline_only=False): + """冒险段有效局(summary 在场——levels_cleared >= 0);编排异常局单列。 + baseline_only=True 只留白板档(①② 基线判定面——注入档行归 ④ 标定段)。""" + runs = [r for r in rows if r.get("seg") == "adventure" and r.get("policy") == policy + and int(r.get("levels_cleared", -1)) >= 0 + and (not baseline_only or r.get("inject_tag", "白板") == "白板")] + invalid = sum(1 for r in rows if r.get("seg") == "adventure" and r.get("policy") == policy + and int(r.get("levels_cleared", -1)) < 0) + return runs, invalid + + +def analyze_adventure_levels(rows): + """逐关条件通关率(冒险口径派生——直入口口径退役 2026-09-23;白板档): + 到达第 k 关 ⇔ levels_cleared >= k-1;通关第 k 关 ⇔ levels_cleared >= k。 + 条件通关率 = 通关数 / 到达数(L1 的到达数 = 全部有效局——冒险即从第一关开始)。""" + out = {} + for policy in ("normal", "perfect"): + runs, invalid = valid_adventure_runs(rows, policy, baseline_only=True) + levels = {} + for k in (1, 2, 3): + reached = sum(1 for r in runs if int(r.get("levels_cleared", 0)) >= k - 1) + cleared = sum(1 for r in runs if int(r.get("levels_cleared", 0)) >= k) + levels[k] = {"reached": reached, "cleared": cleared} + out[policy] = {"n": len(runs), "invalid": invalid, "levels": levels} + return out def analyze_adventure(rows): out = {} for policy in ("normal", "perfect"): - runs = [r for r in rows if r.get("seg") == "adventure" and r.get("policy") == policy] - stopped, death_nodes, l1 = {}, {}, {"n": 0, "wins": 0} + runs, invalid = valid_adventure_runs(rows, policy, baseline_only=True) + stopped, death_nodes = {}, {} for r in runs: sa = int(r.get("stopped_at", -1)) if sa == 0: @@ -292,11 +298,7 @@ def analyze_adventure(rows): if d: lb = node_label(d) death_nodes[lb] = death_nodes.get(lb, 0) + 1 - if int(r.get("levels_cleared", -1)) >= 0: - l1["n"] += 1 - if int(r.get("levels_cleared", 0)) >= 1: - l1["wins"] += 1 - out[policy] = {"n": len(runs), "stopped": stopped, "death_nodes": death_nodes, "l1": l1} + out[policy] = {"n": len(runs), "invalid": invalid, "stopped": stopped, "death_nodes": death_nodes} return out @@ -343,7 +345,7 @@ def analyze_campaign(rows, spend_tag="hp_first"): continue series = campaign_series(runs) res["series"] = series - # 检查点判定:累计通过第 k 层达目标后,第 k+1 层滑窗条件通关率 vs 验收带 + # 检查点:累计通过第 k 层达目标后,第 k+1 层滑窗条件通关率——带待重锚(直入口口径退役)只报读数 checkpoints = [] for k in (1, 2): clears = 0 @@ -369,8 +371,7 @@ def analyze_campaign(rows, spend_tag="hp_first"): ov = chunk[0][2].get("override", {}) cp["forge_at"] = ov cp["band_shift"] = band_shift_for(ov) - band = shifted_band(LEVEL_BANDS.get((policy, k + 1)), cp["band_shift"]) - cp["verdict"], cp["pass"] = judge_band(rate, band) + cp["verdict"], cp["pass"] = judge_band(rate, None) # 带重锚归曲线调参批 checkpoints.append(cp) res["checkpoints"] = checkpoints # 工坊解锁时点(魔法道具面——只报不判) @@ -388,42 +389,62 @@ def analyze_campaign(rows, spend_tag="hp_first"): return out -# ---------------------------------------------------------------- 换算率标定(④) +# ---------------------------------------------------------------- 换算率标定(④,冒险条件口径) def ofat_cells(rows): - """OFAT 分组:白板基线 {(policy, level): [rows]} 与单轴注入档 {attr: {flat: {(policy, level): [rows]}}}。""" + """OFAT 分组(冒险行):白板基线 {policy: [rows]} 与单轴注入档 {attr: {flat: {policy: [rows]}}}。""" base, cells = {}, {} for r in rows: - if r.get("seg") != "level": + if r.get("seg") != "adventure" or int(r.get("levels_cleared", -1)) < 0: continue ov = r.get("override") or {} nonzero = [a for a in OVERRIDE_ATTRS if int(ov.get(a, 0)) != 0] - key = (r["policy"], int(r["level"])) + policy = r["policy"] if not nonzero: - base.setdefault(key, []).append(r) + base.setdefault(policy, []).append(r) elif len(nonzero) == 1: a = nonzero[0] - cells.setdefault(a, {}).setdefault(int(ov[a]), {}).setdefault(key, []).append(r) + cells.setdefault(a, {}).setdefault(int(ov[a]), {}).setdefault(policy, []).append(r) return base, cells -def paired_rate_delta(base_rows, cell_rows): - """同种子配对通关率差(百分点)与配对 SE——跨档同序种子流复用,配对消方差。""" - bmap = {int(r["seed"]): 1 if r.get("result") == "victory" else 0 for r in base_rows} - diffs = [] - for r in cell_rows: - s = int(r["seed"]) - if s in bmap: - diffs.append((1 if r.get("result") == "victory" else 0) - bmap[s]) - n = len(diffs) +def cond_rate(rows, k): + """第 k 关条件通关率(%):通关数/到达数;到达数 0 = None。""" + reached = sum(1 for r in rows if int(r.get("levels_cleared", 0)) >= k - 1) + cleared = sum(1 for r in rows if int(r.get("levels_cleared", 0)) >= k) + if reached <= 0: + return None, reached + return 100.0 * cleared / reached, reached + + +def paired_cond_delta(base_rows, cell_rows, k, reps=2000): + """同种子配对第 k 关条件通关率差(点)与配对 bootstrap SE。 + + 点估计 = 全配对样本上 两档条件率之差;SE = 配对 bootstrap(同一次重采样同时进两档—— + 保种子级相关)。bootsrap 确定性种子固定,复判可重现。 + """ + bmap = {int(r["seed"]): r for r in base_rows} + pairs = [(bmap[int(r["seed"])], r) for r in cell_rows if int(r["seed"]) in bmap] + n = len(pairs) if n == 0: return None - m_raw = sum(diffs) / n - se = None - if n > 1: - var = sum((d - m_raw) ** 2 for d in diffs) / (n - 1) - se = math.sqrt(var / n) * 100.0 - return m_raw * 100.0, se, n + rate_b, reached_b = cond_rate([p[0] for p in pairs], k) + rate_c, reached_c = cond_rate([p[1] for p in pairs], k) + if rate_b is None or rate_c is None: + return None + rng = random.Random(20260923) + deltas = [] + for _ in range(reps): + idx = [rng.randrange(n) for _ in range(n)] + rb, _ = cond_rate([pairs[i][0] for i in idx], k) + rc, _ = cond_rate([pairs[i][1] for i in idx], k) + if rb is not None and rc is not None: + deltas.append(rc - rb) + if not deltas: + return None + se = math.sqrt(sum((d - sum(deltas) / len(deltas)) ** 2 for d in deltas) / (len(deltas) - 1)) if len(deltas) > 1 else 0.0 + return {"n": n, "reached_b": reached_b, "reached_c": reached_c, + "rate_b": rate_b, "rate_c": rate_c, "delta": rate_c - rate_b, "se": se} def calibration_estimate(rows): @@ -435,17 +456,19 @@ def calibration_estimate(rows): detail, pts = [], [] for flat in sorted(flats): lv = flat / per_flat - for key in sorted(flats[flat]): - d = paired_rate_delta(base.get(key, []), flats[flat][key]) - if d is None: - continue - mean_pp, se_pp, n = d - per_lvl = mean_pp / lv - per_lvl_se = (se_pp / lv) if se_pp is not None else None - detail.append({"flat": flat, "key": key, "n": n, "mean_pp": mean_pp, - "se_pp": se_pp, "per_lvl": per_lvl, "per_lvl_se": per_lvl_se}) - if per_lvl_se is not None and per_lvl_se > 0: - pts.append((per_lvl, 1.0 / per_lvl_se ** 2)) + for policy in sorted(flats[flat]): + for k in (1, 2, 3): + d = paired_cond_delta(base.get(policy, []), flats[flat][policy], k) + if d is None: + continue + per_lvl = d["delta"] / lv + per_lvl_se = d["se"] / lv if d["se"] > 0 else None + detail.append({"flat": flat, "policy": policy, "k": k, "n": d["n"], + "rate_b": d["rate_b"], "rate_c": d["rate_c"], + "delta": d["delta"], "se": d["se"], + "per_lvl": per_lvl, "per_lvl_se": per_lvl_se}) + if per_lvl_se is not None and per_lvl_se > 0: + pts.append((per_lvl, 1.0 / per_lvl_se ** 2)) if pts: pooled = sum(p * w for p, w in pts) / sum(w for _, w in pts) pooled_se = math.sqrt(1.0 / sum(w for _, w in pts)) @@ -460,9 +483,6 @@ def calibration_estimate(rows): return out -ATTR_CN = {"max_hp": "生命上限", "atk": "基础攻击", "armor_class": "护甲等级"} - - # ---------------------------------------------------------------- 报告 def fmt_table(header, rows): @@ -480,28 +500,32 @@ def report(args, rows, meta): A = lines.append A(f"# 数值验证报告({meta['ts']})") A("") - A(f"- 采集规模:直入口每格 {args.n} 局(层集 {args.levels} · 注入档 {args.inject or '白板'})" - f" · 基线冒险 {args.na} 局/画像 · 战役 {args.k} 局/画像" - f" · 种子 {args.seed0} 起逐局独立 · 锻造花费策略 = {args.spend}") - A(f"- 切片版本:{meta['commit']} · 换算率表值(meta.tres 启动解析):" + A(f"- 采集规模:基线冒险 {args.na} 局/画像 · 战役 {args.k} 局/画像" + f" · 种子 {args.seed0} 起逐局独立 · 锻造花费策略 = {args.spend}" + + (f" · 注入档 = {args.inject}" if args.inject else "")) + A(f"- 切片版本:{meta['commit']} · 口径:逐关读数 = 冒险条件口径(单关直入口口径已退役 2026-09-23," + f"带待重锚只测不判——重锚归曲线调参批) · 换算率表值(meta.tres 启动解析):" + " · ".join(f"{ATTR_CN[a]}每级平移{CONVERSION.get(a, 0)}点" for a in OVERRIDE_ATTRS)) A("") - # ① 直入口基线(只留白板档——注入档读数归 ④ 标定段) - A("## ① 直入口基线通关率(验收带判定,白板档)") + # ① 逐关条件通关率(冒险口径派生,白板档) + A("## ① 逐关条件通关率(冒险口径——打通 k-1 关才到达第 k 关;带待重锚只测不判)") A("") - lvl = analyze_level(rows, baseline_only=True) + alv = analyze_adventure_levels(rows) tbl = [] - for key, a in sorted(lvl.items()): - policy, li = key[0], key[1] - rate = 100.0 * a["wins"] / max(1, a["n"]) - ci = 1.96 * math.sqrt((rate / 100) * (1 - rate / 100) / max(1, a["n"])) * 100 - band = LEVEL_BANDS.get((policy, li)) - verdict, _ = judge_band(rate, band) - tbl.append([f"{LEVEL_CN[li]}", "普通档" if policy == "normal" else "完美档", - f"{a['wins']}/{a['n']}", f"{rate:.1f}% ±{ci:.1f}", - f"[{band[0]:g},{band[1]:g}]" if band else "未定", verdict]) - A(fmt_table(["层", "画像", "通关/局数", "通关率±95%CI", "验收带", "判定"], tbl)) + for policy in ("normal", "perfect"): + d = alv[policy] + cn = "普通档" if policy == "normal" else "完美档" + for k in (1, 2, 3): + lv = d["levels"][k] + if lv["reached"] <= 0: + tbl.append([LEVEL_CN[k], cn, f"—/{d['n']}", "—(未到达)", "未定"]) + continue + rate = 100.0 * lv["cleared"] / lv["reached"] + ci = binom_ci(lv["cleared"], lv["reached"]) * 100 + tbl.append([LEVEL_CN[k], cn, f"{lv['cleared']}/{lv['reached']}", + f"{rate:.1f}% ±{ci:.1f}", "未定"]) + A(fmt_table(["层", "画像", "通关/到达", "条件通关率±95%CI", "验收带"], tbl)) A("") # ② 冒险基线:止步分布与败退节点 @@ -510,15 +534,11 @@ def report(args, rows, meta): adv = analyze_adventure(rows) for policy in ("normal", "perfect"): d = adv[policy] - if d["n"] == 0: - continue cn = "普通档" if policy == "normal" else "完美档" A(f"### {cn}({d['n']} 局)") A("") stop_line = "、".join(f"{k} {v}({100.0 * v / max(1, d['n']):.0f}%)" for k, v in sorted(d["stopped"].items())) A(f"- 止步分布:{stop_line or '—'}") - l1r = 100.0 * d["l1"]["wins"] / max(1, d["l1"]["n"]) - A(f"- 第一层通过率(冒险口径交叉核对):{l1r:.1f}%") A("- 败退节点分布(失败局归因):") for lb, c in sorted(d["death_nodes"].items(), key=lambda x: -x[1]): A(f" - {lb} ×{c}") @@ -555,7 +575,8 @@ def report(args, rows, meta): A(f"- 判据:累计通过{LEVEL_CN[cp['level']]} {CAMPAIGN_CLEARS_TARGET} 次后,{LEVEL_CN[cp['level'] + 1]}" f"条件通关率(滑窗 {CAMPAIGN_WINDOW} 局)——{cp['verdict']}" + (f"(触发时注入 = 生命+{cp['forge_at'].get('max_hp', 0)}/攻击+{cp['forge_at'].get('atk', 0)}" - f"/护甲+{cp['forge_at'].get('armor_class', 0)},表值平移 {cp.get('band_shift', 0.0):+.1f} 点)" + f"/护甲+{cp['forge_at'].get('armor_class', 0)}" + f",表值平移 {cp.get('band_shift', 0.0):+.1f} 点——带重锚后随平移判)" if "forge_at" in cp else "")) A("") tbl = [] @@ -578,82 +599,77 @@ def report(args, rows, meta): A(fmt_table(["局", "注入(flat)", "钥石", "第1层率(窗)", "第2层率(窗)", "第3层率(窗)", "终局"], tbl)) A("") - # ④ 换算率标定(OFAT 注入档配对读数——护甲行强条目重测面) - A("## ④ 换算率标定(OFAT 注入档 vs 白板,同种子配对)") + # ④ 换算率标定(OFAT 注入档配对读数——护甲行强条目重测面;冒险条件口径) + A("## ④ 换算率标定(OFAT 注入档 vs 白板,同种子配对逐关条件通关率差)") A("") est = calibration_estimate(rows) if not any(e["detail"] for e in est.values()): A("- 无注入档数据(本采集未带 inject 档——标定面跳过)") A("") else: - any_detail = False for attr in OVERRIDE_ATTRS: e = est.get(attr) if not e or not e["detail"]: continue - any_detail = True per_flat = max(1, FORGE_FLAT.get(attr, 1)) A(f"### {ATTR_CN[attr]}(每级 flat +{per_flat})") A("") tbl = [] for d in e["detail"]: - policy, li = d["key"] + cn = "普通档" if d["policy"] == "normal" else "完美档" tbl.append([ - f"+{d['flat']}({d['flat'] // per_flat} 级)", - "普通档" if policy == "normal" else "完美档", f"{LEVEL_CN[li]}", - str(d["n"]), - f"{d['mean_pp']:+.1f}" + (f" ±{d['se_pp']:.1f}" if d["se_pp"] is not None else ""), + f"+{d['flat']}({d['flat'] // per_flat} 级)", cn, LEVEL_CN[d["k"]], + str(d["n"]), f"{d['rate_b']:.1f}→{d['rate_c']:.1f}", + f"{d['delta']:+.1f} ±{d['se']:.1f}", f"{d['per_lvl']:+.1f}" + (f" ±{d['per_lvl_se']:.1f}" if d["per_lvl_se"] is not None else ""), ]) - A(fmt_table(["注入档", "画像", "层", "配对局数", "通关率差(点)", "折每级(点/级)"], tbl)) - A("") - if any_detail: - A("### 三行汇总与建议投值") - A("") - tbl = [] - for attr in OVERRIDE_ATTRS: - e = est.get(attr) - if not e or (not e["detail"] and e["pooled"] is None): - tbl.append([ATTR_CN[attr], str(e["table_val"] if e else CONVERSION.get(attr, 0)), - "—", "—", "—"]) - continue - pooled_s = "—" if e["pooled"] is None else f"{e['pooled']:+.1f}" - if e["pooled"] is not None and e["pooled_se"] is not None: - pooled_s += f" ±{e['pooled_se']:.1f}" - if e["suggest"] is None: - state = "无读数" - elif e["table_val"] == 0: - state = "表值未投值(现行 0)" - elif e["table_val"] == e["suggest"]: - state = "与表值一致 ✓" - else: - state = f"与表值偏差 {e['suggest'] - e['table_val']:+d}" - tbl.append([ATTR_CN[attr], str(e["table_val"]), pooled_s, - "—" if e["suggest"] is None else str(e["suggest"]), state]) - A(fmt_table(["属性", "现行表值(点/级)", "实测每级(点/级, 合并)", "建议投值", "状态"], tbl)) - A("- 折算语义:每级该属性强化 ≈ 通关率带平移量(百分点)——配对同种子读数,护甲行即解锁后实测(强条目)") - A("- 合并口径:逆方差加权跨(档位×画像×层);带平移为线性单值近似——近带顶/带底的读数受天花板压缩,判读看 ④ 明细表") + A(fmt_table(["注入档", "画像", "层", "配对局数", "条件率 白板→档", "差(点)", "折每级(点/级)"], tbl)) A("") + A("### 三行汇总与建议投值") + A("") + tbl = [] + for attr in OVERRIDE_ATTRS: + e = est.get(attr) + if not e or (not e["detail"] and e["pooled"] is None): + tbl.append([ATTR_CN[attr], str(CONVERSION.get(attr, 0)), "—", "—", "—"]) + continue + pooled_s = "—" if e["pooled"] is None else f"{e['pooled']:+.1f}" + if e["pooled"] is not None and e["pooled_se"] is not None: + pooled_s += f" ±{e['pooled_se']:.1f}" + if e["suggest"] is None: + state = "无读数" + elif e["table_val"] == 0: + state = "表值未投值(现行 0)" + elif e["table_val"] == e["suggest"]: + state = "与表值一致 ✓" + else: + state = f"与表值偏差 {e['suggest'] - e['table_val']:+d}" + tbl.append([ATTR_CN[attr], str(e["table_val"]), pooled_s, + "—" if e["suggest"] is None else str(e["suggest"]), state]) + A(fmt_table(["属性", "现行表值(点/级)", "实测每级(点/级, 合并)", "建议投值", "状态"], tbl)) + A("- 折算语义:每级该属性强化 ≈ 通关率带平移量(百分点)——配对同种子读数,护甲行即解锁后实测(强条目)") + A("- 合并口径:逆方差加权跨(档位×画像×层,配对 bootstrap SE);带平移为线性单值近似——近带顶/带底的读数受天花板压缩,判读看 ④ 明细表") + A("") return "\n".join(lines) def console_verdict(args, rows): """控制台判定结论(先读数后细节)。""" - lvl = analyze_level(rows, baseline_only=True) + alv = analyze_adventure_levels(rows) print("\n判定结论(detail 见报告文件)") - for key, a in sorted(lvl.items()): - policy, li = key[0], key[1] - rate = 100.0 * a["wins"] / max(1, a["n"]) - band = LEVEL_BANDS.get((policy, li)) - verdict, ok = judge_band(rate, band) - mark = {True: "✓", False: "✗", None: "·"}[ok] - print(f" [{mark}] 直入口{LEVEL_CN[li]}{'普通档' if policy == 'normal' else '完美档'}:" - f"{rate:.1f}%({a['wins']}/{a['n']})→ {verdict}") + for policy in ("normal", "perfect"): + d = alv[policy] + cn = "普通档" if policy == "normal" else "完美档" + cells = [] + for k in (1, 2, 3): + lv = d["levels"][k] + if lv["reached"] > 0: + rate = 100.0 * lv["cleared"] / lv["reached"] + cells.append(f"{LEVEL_CN[k]} {rate:.1f}%({lv['cleared']}/{lv['reached']})") + print(f" [·] 逐关条件通关率·{cn}:{' · '.join(cells) or '—'}(冒险口径——带待重锚只测不判)") adv = analyze_adventure(rows) for policy in ("normal", "perfect"): d = adv[policy] - if d["n"] == 0: - continue cn = "普通档" if policy == "normal" else "完美档" top = sorted(d["death_nodes"].items(), key=lambda x: -x[1])[:2] print(f" [·] 零强化冒险·{cn}:止步分布 {'、'.join(f'{k}{v}' for k, v in sorted(d['stopped'].items()))}" @@ -689,22 +705,19 @@ def main(): sys.stdout.reconfigure(encoding="utf-8", errors="replace") ap = argparse.ArgumentParser(description="数值验证工具(判定端)") ap.add_argument("--godot", default=GODOT) - ap.add_argument("--n", type=int, default=100, help="直入口每格局数(±95%CI 约 ±9 点——带边判读须看 CI)") - ap.add_argument("--na", type=int, default=60, help="基线冒险局数/画像") + ap.add_argument("--na", type=int, default=60, help="基线冒险局数/画像(±95%CI 约 ±9 点——判读须看 CI)") ap.add_argument("--k", type=int, default=60, help="战役局数/画像") ap.add_argument("--seed0", type=int, default=8000) - ap.add_argument("--only", default="level,adventure,campaign") + ap.add_argument("--only", default="adventure,campaign") ap.add_argument("--spend", default="hp_first", choices=["hp_first", "atk_first", "armor_first"]) - ap.add_argument("--inject", default="", help="直入口注入档(flat:max_hp:3,atk:1 式——OFAT 标定用)") - ap.add_argument("--levels", default="1,2,3", help="直入口层集(标定批常用 1,2——第三层带未定)") + ap.add_argument("--inject", default="", help="冒险段注入档(flat:max_hp:3,atk:1 式——OFAT 标定用)") ap.add_argument("--timeout", type=int, default=5400) - ap.add_argument("--quick", action="store_true", help="小规模快跑(12/8/10)") + ap.add_argument("--quick", action="store_true", help="小规模快跑(8/10)") ap.add_argument("--from-raw", default=None, help="跳过采集,对既有 raw.jsonl 重新判定出报告") args = ap.parse_args() if args.quick: - args.n, args.na, args.k = 12, 8, 10 - n_levels = len([s for s in args.levels.split(",") if s.strip()]) - args.est_min = (n_levels * 2 * args.n * 1.5 + 2 * args.na * 3.5 + 2 * args.k * 3.5) / 60 + args.na, args.k = 8, 10 + args.est_min = (2 * args.na * 4.0 + 2 * args.k * 4.0) / 60 load_meta_table() # 表值锚配置推导化——解析失败即 FAIL,零硬编码兜底