merge: 缺陷修批Y断点随存——attune_refresh_y入断点+续玩优先读断点堵满血复活漏洞+单测⑥段+文档三件随批(8e04807, worktree ybpfix-20261013)

This commit is contained in:
DKChan committed 2026-10-13 02:05:38 +08:00
commit e0d931d1af
5 files changed
+16 -4

No files matched your search

+2 -2
View File
@@ -103,11 +103,11 @@
- **① AP 上限 clamp 缺位(缺陷)**:树「开局姿态」(每关首轮 AP+1)、AP 件、时沙同走 `action_economy.gd:239 _pending_ap_delta` 排队,轮始兑现仅下限钳制(`:254 maxi(0, …)`,无上限)——旧单源时代缺陷不可观测,新叠加源使其可观测化。**已裁(2026-10-13 用户):暂不设上限**——provisional 天花板亦不投,随 Alpha 收官 M4 数值批一并调整(届时连同全部 AP 数值统一标定)。
- **② 三选一刷新软上限(设计问)**:停点内 GP 付费刷新倍率增长(×1.8/次曲线)×停点间基础价随进度递增,全程无软上限——是否设上限归调参批裁决。**已裁(2026-10-13 用户):维持现状**——定性确认=设计问非缺陷,归 M4 数值批调参窗口处理,不提前单开讨论。
- **③ Y(_attune_refresh_y)不入断点存档(可利用漏洞)**:断点快照存 `_refresh_stock`(adventure_runner.gd:236 回填)与 Y 升级档(账号级 attune_refresh_level),不存当局 Y 余量;续玩路径自参数面重新整额注入(:225)——用完 Y 退菜单再续玩即满血复活。V15 仅验账本一致性,未覆盖该面;刷新链路可用性不受影响。**已裁(2026-10-13 用户):须修**,但不单独开工——用户令「所有都确定完了之后再一起修」,归确认工作收官后的集中修批执行;修法届时零待裁点(断点扩列一行+续玩优先读断点,`_snapshot_breakpoint` 内六个同款先例〔refresh_stock/battery_pending/feat_ticket_pity 等,扩列向后兼容〕)。
- **③ Y(_attune_refresh_y)不入断点存档(可利用漏洞)**:断点快照存 `_refresh_stock`(adventure_runner.gd:236 回填)与 Y 升级档(账号级 attune_refresh_level),不存当局 Y 余量;续玩路径自参数面重新整额注入(:225)——用完 Y 退菜单再续玩即满血复活。V15 仅验账本一致性,未覆盖该面;刷新链路可用性不受影响。**已裁(2026-10-13 用户):须修**,但不单独开工——用户令「所有都确定完了之后再一起修」,归确认工作收官后的集中修批执行;修法届时零待裁点(断点扩列一行+续玩优先读断点,`_snapshot_breakpoint` 内六个同款先例〔refresh_stock/battery_pending/feat_ticket_pity 等,扩列向后兼容〕)。**✅ 已修复(2026-10-13 同日用户令提前单独开修——「C类先不做,把还没修的 bug 修了,按正常流程走」)**:断点快照扩列 `attune_refresh_y`(`_snapshot_breakpoint`)+ 续玩 `resume_adventure` 优先读断点(缺键回退参数面=旧档行为零变化)+ 单测⑥段两断言(余量随断点还原/旧档回退);批末冒烟 938/0+单测 24 套全绿。本件销号。
**归属**:① [行动经济](systems/排雷循环/行动经济.md);② 行动经济+三选一/商店刷新经济(数值归 Alpha 收官 M4 数值批);③ [存档序列化](systems/表现与支撑/存档序列化.md)(断点域)+ [冒险结构](systems/冒险循环/冒险结构.md)(续玩参数面)——三件均系缺陷修批/调参批输入,未排批
**状态**:**三件已全裁(2026-10-13 用户逐件:① 暂不设上限随 M4 数值批/② 维持现状归 M4 数值批/③ 须修随集中修批)**——①② 批内零动作等 M4;③ 等确认工作收官后的集中修批(用户令「先所有都确定完了之后再一起修」),本条转为记账条,无待裁点
**状态**:**三件终态(2026-10-13)**:① 暂不设上限随 M4 数值批/② 维持现状归 M4 数值批(两件批内零动作,数值统一标定归 M4);③ ✅ 同日缺陷修批已修复销号(用户令提前单独开修)——本条转为记账条,无待裁点
#### 现役 UI/文案两处自相冲突(2026-10-09 登记——审查批呈报 B5,用户裁「记录待办、后续迭代解决」)
@@ -191,7 +191,7 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗
冒险进行中随时关游戏走人(**中断**),下次启动可从最近停点继续——承载 = 存档 `breakpoint` 域(格式归[存档序列化](../表现与支撑/存档序列化.md),内容口径归本文)。
- **停点粒度**:快照只挂选路停点(入口呈现/战斗胜利后/兑付确认后的选路态)——这是唯一可恢复停点形态。战斗进行中不写快照:中断恢复后**当场战斗从头打**,棋盘中局不入档。
- **七字段拍板面**:关卡序号 / 节点位 / 生命 / 本关加成区 / GP 钱包 / 商店已购档 / 已抽模板。附随件(续玩正确性必需,随批登记):主种子 + 取数计数器(rng 快照契约回填——续玩从断点号位精确续接原随机时间线,已抽模板零重抽)、钥石累计(Boss 掉落逐杀入账的中途值,终局摘要不失真)、已到节点序(关卡画面图条重建)、秘宝库存(奖励节点已选件防静默丢失)、**奖励选择态**(三选一停点中断:已选件 / 同调位替换在途——续玩已选不丢失;候选一致性=快照现状非强求 feature,2026-10-01 用户裁决)、**件获取次数计数**(kind 维度派生账本——断点附随件与读数承载)、**令牌池余库**(bonus_deck 逐枚还原——TP0 扩列,池消耗即上限的续玩正确性承载;旧版断点缺键=满库重建防御口径,单版本周期)、**商店货架态**(当前货架三件 + 本次进店已购次数——P2 甲扩列随迭代 11 第②批;离开店=空架合法态,货架续玩由确定性重放承载:重进店同种子同货架逐位)。
- **七字段拍板面**:关卡序号 / 节点位 / 生命 / 本关加成区 / GP 钱包 / 商店已购档 / 已抽模板。附随件(续玩正确性必需,随批登记):主种子 + 取数计数器(rng 快照契约回填——续玩从断点号位精确续接原随机时间线,已抽模板零重抽)、钥石累计(Boss 掉落逐杀入账的中途值,终局摘要不失真)、已到节点序(关卡画面图条重建)、秘宝库存(奖励节点已选件防静默丢失)、**奖励选择态**(三选一停点中断:已选件 / 同调位替换在途——续玩已选不丢失;候选一致性=快照现状非强求 feature,2026-10-01 用户裁决)、**件获取次数计数**(kind 维度派生账本——断点附随件与读数承载)、**令牌池余库**(bonus_deck 逐枚还原——TP0 扩列,池消耗即上限的续玩正确性承载;旧版断点缺键=满库重建防御口径,单版本周期)、**商店货架态**(当前货架三件 + 本次进店已购次数——P2 甲扩列随迭代 11 第②批;离开店=空架合法态,货架续玩由确定性重放承载:重进店同种子同货架逐位)、**Y 刷新池余量**(attune_refresh_y——冒险周期池消耗余量随断点:续玩优先读断点、不自参数面整额重注入,堵「用完 Y 退菜单再续玩满血复活」可利用漏洞;旧断点缺键回退参数面=旧档行为零变化。2026-10-13 缺陷修批)。
- **中断与退出两口径分离**(2026-09-29 用户裁决):中断(关游戏)= 留断点可续;**退出冒险**(放弃流程)= 失败同型结算 + **清除断点**——退出后「继续上局」不再出现。
- **续玩**:自断点重建到最近停点(账面逐字段回填 + 随机流回填),停点处玩家重新选路。三结局(通关/失败/放弃)一律清断点——断点只活在一个进行中的冒险上。
- 与测量面的关系:断点面只在注入存档承载的正式冒险路径生效;模拟/冒烟不注入 = 整面静默,MC 对拍零扰动。
@@ -326,3 +326,4 @@ GP(显示名「金币」)是冒险内的一次性属性提升货币:战斗
| —— | 2026-10-09 | 缺号注记:v0.15 未登记(对应批次=MC-1 商店独立刷新机制批〔2026-10-04,git ac3cee7 提交信息明记「冒险结构v0.15回写」、版本行未入表〕,登记见正文「共享池账本」节 v0.15 标签),卫生批仅注记不补写 |
| v0.19 | 2026-10-09 | 文档正确性审查批·独立复核(worktree docaudit-2026-10-09):「秘宝件受同调位约束」段与验收「同调位约束」条补现状注——道具件已随迭代 11 第①批 T7 出池,三渠道零投放、替换交互无现役触发面(与关卡节点地图 v1.7「满位替换子交互随之不再触发」口径对齐),约束保留作渠道恢复契约;段内「(06 在册)」悬空指针改「原 06 条目已随收口移除」 |
| v0.20 | 2026-10-12 | **迭代 20 反哺落文批·关卡大奖励换代(用户裁②——通关兑付=专长三选一按档配比加权抽取+回血,2026-10-11 迭代 20 Q1 已裁形态对齐)**:①章节标题/概览行/三层奖励框架表「提升三选一」→「专长三选一」(通关渠道=专长独占兼唯一直接渠道,未选候选不落袋);②提升池七种×档位表与洗牌抽取段整体退役——池机制事实源移交[奇物]「池结构与抽取」节(案D 四级 104/曝光槽 2+1/令牌语义/概率与 cap 解耦),本节压缩为结构层段(共享池冒险级单例/库存=剩余令牌数/reward_pick 封闭流/MC 策略 316-f/断点余库还原);③本文件「提升三选一」指通关兑付处换代「专长三选一」、指奖励节点选择处换代「奖励节点三选一」(生命周期图/加算区同账段/共享池账本段/关卡序列图/验收步骤 6/结构冻结——版本历史行引述豁免);④不负责表换代(池结构与抽取机制→奇物;共享池库存账本留本文);⑤~~秘宝件~~出池删除线行随提升池表退役(渠道恢复契约口径由「秘宝件受同调位约束」段承载不变);⑥刷新句「提升三选一免费双源」中性化「三选一免费双源」 |
| v0.21 | 2026-10-13 | **Y 断点随存缺陷修批(06「天赋树实装批登记欠账三条」③——用户令单独开修)**:「冒险断点」节附随件清单扩 **Y 刷新池余量**(attune_refresh_y——续玩优先读断点、不自参数面整额重注入,堵「用完 Y 退菜单再续玩满血复活」可利用漏洞;旧断点缺键回退参数面=旧档行为零变化);快照时点不变(停点整体覆写已覆盖 Y 消耗后状态)。断点域登记与版本口径归[存档序列化](../表现与支撑/存档序列化.md) v1.8(v7 域后扩列不升版) |
@@ -195,3 +195,4 @@ MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单
| v1.5 | 2026-10-12 | **锻造工坊完备性检查批随迁(用户令:新加内容现在补、不等实装批)**:①**预登记锻造路线域**(计划 v7):域清单表 + 版本沿革补 `forge_routes`(三武器等级+三甲等级+当前选中标记、无特效域、旧档破坏性废弃归锻造工坊实装批;域名以实装批定名为准);②**清偿 forge_levels 残留**——JSON 示例、域清单表删该域(代码侧已随迭代 21 T5 删除:`save_manager.gd:12-14/:399-401` 白名单收口);迁移链 v4→v5 的「三体系迁移」体改述为已删除(`save_manager.gd:96-98`、`meta_progression.gd:294-295`);③**补登两漏域**(代码实证 `save_manager.gd:119-139`):`tree_struct`(树结构版本标记,迭代 21 T5,缺失=换代前结构加载废弃重置,owner 天赋树)、`first_adventure_done`(首冒险完成标记,新档默认 false、旧档缺省按已完成兜底,`meta_progression.gd:100` 置位,owner 元进度);④消费面纪律句「读写锻造等级」→「读写树等级」(访问器已随行族退役删除)。版本号常量仍 =6(v7 未落地) |
| v1.6 | 2026-10-12 | **迭代 22 反哺落文批(实现报告 §三⑥,用户裁「落文」)**:域清单表补 `vision_used` 行(真视使用终身计数,迭代 22 新增,v6 域后扩列补零不升版本——迭代 21 先例;断点随件 `vision_counter_used` 同批新增、旧随件键 `bonus_aux_carry` 随替换子交互拆除退役);缺键补齐纪律句补 v6 扩列注;零迁移口径复核=SAVE_FORMAT_VERSION 仍 6(`save_manager.gd:49`),无迁移分支新增 |
| v1.7 | 2026-10-12 | **锻造工坊实装批随迁(迭代 23 T5——v7 落地;承 v1.6 的 vision_used 登记)**:①域清单表 `forge_routes` 计划行→实际落地态({levels 六路线等级 + unlocked 直购解锁清单 + weapon/armor 当前选中标记},域内键名以实装批定名);②版本与迁移节——当前 =7、迁移链补 v6→v7(空迁移=缺键补齐模式,解锁态派生不落档三通道);③旧档口径订正——「破坏性废弃」→「缺键补齐 = 初始持有态」(开发阶段禁迁移禁折算纪律不变,契约 4);④域界注记——forge_routes 属 meta 永久进度域(契约 2 反面清单不涉) |
| v1.8 | 2026-10-13 | **Y 断点随存缺陷修批(06「天赋树实装批登记欠账三条」③——用户令单独开修)**:断点域扩列随件键 `attune_refresh_y`(Y 冒险周期池消耗余量——续玩优先读断点、不自参数面整额重注入=堵「用完退菜单再续玩满血复活」可利用漏洞;旧断点缺键回退参数面整额注入=旧档行为零变化);**v7 域后扩列不升版**(v1.6 vision_used 先例同款,SAVE_FORMAT_VERSION 仍 7、无迁移分支新增);断点字段口径 owner=冒险结构(v0.21 随批登记) |
+2 -1
View File
@@ -230,7 +230,7 @@ func resume_adventure(bp: Dictionary, params: Dictionary = {}) -> bool:
_shop_mode = "pool" if String(params.get("shop_mode", "legacy")) == "pool" else "legacy" # 迭代 11 第②批 T3——续玩参数面同 start_adventure(缺省 legacy)
_treasure_unlocked = params.get("treasure_unlocked", {}) if params.get("treasure_unlocked", {}) is Dictionary else {}
_attunement = params.get("attunement", []) if params.get("attunement", []) is Array else [] # additive(迭代 11 第①批 T5)
_attune_refresh_y = maxi(0, int(params.get("attune_refresh_y", 0))) # additive(迭代 11 第①批 T5b——Y 冒险周期池)
_attune_refresh_y = maxi(0, int(bp.get("attune_refresh_y", int(params.get("attune_refresh_y", 0))))) # 2026-10-13 缺陷修批——Y 余量优先读断点(花掉不回血=堵「用完退菜单再续玩满血复活」可利用漏洞);缺键=旧版断点,回退参数面整额注入(旧档行为零变化)
_seed_attune_charges() # 迭代 11 第①批 T6——冒险开始充能账本按装备主动件重置(每冒险充能语义)
_tree_rules = params.get("tree_rules", []) if params.get("tree_rules", []) is Array else [] # 迭代 12 T10——A/B 面 rule 键集(尾裁微批b 2026-10-08 卡⓪受理闭环:续玩参数面同 start_adventure :135 同式,消费面 set_tree_rules 下传现成零改)
# 三选一停点续玩分支(迭代 10——选择态/已兑付态不重跑关卡;奖励选择态不重抽、已兑付不重付)
@@ -1105,6 +1105,7 @@ func _snapshot_breakpoint() -> void:
"adventure_counters": adventure_counters.duplicate(true), # 迭代 20 T6/T7——adventure 域计数器随断点(续玩跨战账不丢)
"vision_counter_used": int(vision_counter.get("used", 0)), # 迭代 22 秘宝批 T3——真视使用计数随断点(续玩跨战账不丢)
"refresh_stock": _refresh_stock, # 迭代 20 T4/T7——刷新存量账随断点(F-1 新账)
"attune_refresh_y": _attune_refresh_y, # 2026-10-13 缺陷修批——Y 冒险周期池余量随断点(续玩不再自参数面整额重注入=堵「用完退菜单再续玩满血复活」可利用漏洞;扩列向后兼容——旧档缺键回退参数面)
"battery_pending": _battery_pending, # 迭代 20 T4/T7——电池待分配充能随断点
"bonus_result": _curio_result.duplicate(true), # 已兑付待推进态(空 = 无——中断续玩不重兑付)
"keystone_drops": _keystone_drops.duplicate(true), # 逐杀掉落明细(摘要归因续接——迭代 10)
@@ -52,6 +52,15 @@ func _init() -> void:
Kit.check_quiet(lr.spend_gp(31) == false and int(lr.gp) == 30, "余额不足拒绝零副作用")
Kit.check_quiet(lr.spend_gp(20) == true and int(lr.gp) == 10, "足额支出扣账(30→10)")
# ---- ⑥ Y 断点随存(2026-10-13 缺陷修批——旧缺陷:续玩自参数面整额重注入=用完 Y 退菜单再续玩满血复活)----
var bp_y := {"level_index": 1, "hero_hp": 10, "attune_refresh_y": 2}
var adr_r = load("res://core/adventure_runner.gd").new(db, load("res://core/rng_service.gd").new())
Kit.check_quiet(adr_r.resume_adventure(bp_y, {"hero_override": {}, "attune_refresh_y": 3}), "续玩受理(最小断点+参数面)")
Kit.check_quiet(adr_r._attune_refresh_y == 2, "断点有键=Y 余量随断点还原(花 1 剩 2——不再整额重注入=满血复活堵死)")
var adr_o = load("res://core/adventure_runner.gd").new(db, load("res://core/rng_service.gd").new())
Kit.check_quiet(adr_o.resume_adventure({"level_index": 1, "hero_hp": 10}, {"hero_override": {}, "attune_refresh_y": 3}), "旧断点续玩受理(快照缺键)")
Kit.check_quiet(adr_o._attune_refresh_y == 3, "旧断点缺键=回退参数面整额注入(旧档行为零变化)")
quit(Kit.finish("curio_refresh_paid"))