merge(迭代33 卡② 主菜单三入口化批): 6 钮→3 钮(进入存档/设置/退出游戏——裁决 1)
- 全量闸全绿(回执 commit=94f8614 domain=full 实测 all_green):冒烟 1213/0、单元 40 套件、探针全件、静态扫描/渲染闸(golden 三钮基线重制)/熵增闸+文档域六闸;回放对拍未触面(MC 零跑) - 独立验收审计通过(无缺漏):mn1-mn14 全过;变异A(旧钮接回→渲染面计数锚红)/变异B(接错层→屏流 5 红)实测闭合 - _refresh_resume_button 净删除+消费点全清(mn7);断点确认主菜单侧摘除(mn6,归卡④大门);_start_adventure_from_menu/_resume_from_menu/_open_career 保留探针直调中间态(mn10,已知中间态登记) - 产出物与反哺点见 reports/iter33-实现报告/追认单/反哺点(迭代33 三卡齐)
This commit is contained in:
commit
508f190b8c
21 files changed
+318
-284
No files matched your search
@@ -16,13 +16,12 @@ var runner_get: Callable # () -> LevelRunner
|
||||
var open_modal: Callable
|
||||
var close_modal: Callable
|
||||
var refresh_presentations: Callable
|
||||
var refresh_resume_button: Callable
|
||||
|
||||
|
||||
func _init(db_ref, meta_get_cb: Callable, save_get_cb: Callable, camp_overlay_ref: CampOverlay,
|
||||
shop_overlay_ref: ShopOverlay, toast_ref: ToastStack, start_overlay_ref: Control,
|
||||
logger_ref, runner_get_cb: Callable, open_modal_cb: Callable, close_modal_cb: Callable,
|
||||
refresh_presentations_cb: Callable, refresh_resume_button_cb: Callable) -> void:
|
||||
refresh_presentations_cb: Callable) -> void:
|
||||
db = db_ref
|
||||
meta_get = meta_get_cb
|
||||
save_get = save_get_cb
|
||||
@@ -35,4 +34,3 @@ func _init(db_ref, meta_get_cb: Callable, save_get_cb: Callable, camp_overlay_re
|
||||
open_modal = open_modal_cb
|
||||
close_modal = close_modal_cb
|
||||
refresh_presentations = refresh_presentations_cb
|
||||
refresh_resume_button = refresh_resume_button_cb
|
||||
@@ -1,6 +1,6 @@
|
||||
## VERTICAL SLICE - NOT FOR PRODUCTION
|
||||
## 营地/商店投影控制器:营地开合/快照投影/锻造·同调·天赋树·Fork 购买切换 + 商店房购买/离开(pool 与 product 双面)。
|
||||
## 信号连接只归组合根(campbtn/camp_overlay/shop_overlay 信号接至本类 on_* 入口);模态栈/呈现刷新/续玩刷新与 runner 现值经组合根回调注入。
|
||||
## 信号连接只归组合根(camp_overlay/shop_overlay 信号接至本类 on_* 入口);模态栈/呈现刷新与 runner 现值经组合根回调注入(续玩刷新已随主菜单三入口化退役——卡② mn7)。
|
||||
## 写调用唯一经 MetaProgression 购买原语与 LevelRunner.buy_*——本类零直写,拒绝兜底 toast 保留原地。
|
||||
extends RefCounted
|
||||
|
||||
@@ -16,7 +16,6 @@ var _runner_get: Callable # () → 关卡推进器现值(组合根 la
|
||||
var _open_modal: Callable
|
||||
var _close_modal: Callable
|
||||
var _refresh_presentations: Callable
|
||||
var _refresh_resume_button: Callable
|
||||
|
||||
|
||||
func _init(ctx: CampFlowContext) -> void:
|
||||
@@ -33,7 +32,6 @@ func _init(ctx: CampFlowContext) -> void:
|
||||
_open_modal = ctx.open_modal
|
||||
_close_modal = ctx.close_modal
|
||||
_refresh_presentations = ctx.refresh_presentations
|
||||
_refresh_resume_button = ctx.refresh_resume_button
|
||||
|
||||
|
||||
# 打开营地(主菜单入口——开合与开始层互斥仿设置面先例:开始覆盖层非模态且树序在后,
|
||||
@@ -52,7 +50,6 @@ func open_camp() -> void:
|
||||
func on_camp_closed() -> void:
|
||||
_close_modal.call(camp_overlay) # 模态栈单口
|
||||
start_overlay.visible = true
|
||||
_refresh_resume_button.call() # 回菜单按断点在档态刷新
|
||||
_refresh_presentations.call() # 关闭后刷新顶栏(工坊解锁可能变了余额侧读数面)
|
||||
|
||||
|
||||
|
||||
+12
-41
@@ -67,8 +67,7 @@ var meta: MetaProgressionCore:
|
||||
var logger = null # 试玩日志器(JSONL 持久化 + 卡死诊断转储——呈现层组件)
|
||||
var _debug_entry := false # 调试会话门控(写死=true——恒开:启动即开浮窗+两屏角标点亮;_ready 赋值)
|
||||
var _seed_edit: LineEdit
|
||||
var _resume_btn: Button # 继续上局按钮句柄(有断点才亮)
|
||||
var confirm_dialog: ConfirmDialog # 通用确认弹窗(新冒险互斥确认弹窗化)
|
||||
var confirm_dialog: ConfirmDialog # 通用确认弹窗(消费方编排——现行消费方=选档删档确认;新冒险互斥确认已随卡②主菜单撤出,归卡④大门)
|
||||
var _confirm_consumer := "" # 确认弹窗消费方状态量(契约 3 编排——open 前设、分派后清)
|
||||
var _confirm_consumer_slot := 0 # 消费方附随槽号(delete_slot 消费方专用)
|
||||
var curio_overlay: CurioPickOverlay # 提升三选一覆盖层(level-clear.md v2 选择面承载;奖励节点共用)
|
||||
@@ -195,7 +194,6 @@ func _ready() -> void:
|
||||
_debug.battle_ready.connect(_on_debug_battle_ready)
|
||||
_build_ui()
|
||||
_begin_session(false) # 闲时会话(gp_ledger 等探针注入面自 _ready 起恒在——ui_probe 合成段时序)
|
||||
_refresh_resume_button() # 启动读盘后按断点在档态点亮「继续上局」
|
||||
_start_overlay.visible = true
|
||||
_debug_entry = true # 调试入口门控写死=true(不读 DS_DEBUG 环境变量;发布前清)
|
||||
debug_badge.visible = _debug_entry # 浮层角标可见性须门控落定后赋值(构建/连接在 _build_ui)
|
||||
@@ -315,10 +313,9 @@ func _build_ui() -> void:
|
||||
curio_overlay.continue_pressed.connect(_bonus.on_continue)
|
||||
curio_overlay.refresh_requested.connect(_bonus.on_refresh)
|
||||
|
||||
# 菜单屏接线(句柄经屏壳暴露)
|
||||
_menu_screen.lvbtn.pressed.connect(_start_adventure_from_menu)
|
||||
_menu_screen.resumebtn.pressed.connect(_resume_from_menu) # 续玩入口
|
||||
_resume_btn = _menu_screen.resumebtn
|
||||
# 菜单屏接线(句柄经屏壳暴露;三入口化——进入存档/设置/退出游戏,卡② mn3:
|
||||
# 进入存档钮落点=卡③选档层 _open_save_select,点击链在此闭环)
|
||||
_menu_screen.entersavebtn.pressed.connect(_open_save_select)
|
||||
# 调试入口=UI 最顶层全局浮层角标(任何 UI 不遮挡——菜单/战斗/地图三枚
|
||||
# 屏内角标由全局浮层承载;连接归组合根,树序/登记面见 LAYER_CONTRACT 末位)
|
||||
debug_badge = UiAssembler.build_debug_badge(self)
|
||||
@@ -328,7 +325,7 @@ func _build_ui() -> void:
|
||||
# 购买写调用唯一经 MetaProgression/LevelRunner core 单口——组合根 lambda 现值注入)
|
||||
_camp_pres = CampShopPresenter.new(CampFlowContext.new(db, func() -> Variant: return meta, func() -> Variant: return save_manager, camp_overlay, shop_overlay,
|
||||
board_zone.toast, _start_overlay, logger, func() -> Variant: return run_scope.runner,
|
||||
_open_modal, _close_modal, _refresh_presentations, _refresh_resume_button)) # 构造参数收拢 context
|
||||
_open_modal, _close_modal, _refresh_presentations)) # 构造参数收拢 context
|
||||
shop_overlay.buy_requested.connect(_camp_pres.on_shop_buy)
|
||||
shop_overlay.refresh_requested.connect(_camp_pres.on_shop_refresh) # MC-1
|
||||
shop_overlay.leave_pressed.connect(_camp_pres.on_shop_leave)
|
||||
@@ -340,8 +337,6 @@ func _build_ui() -> void:
|
||||
camp_overlay.forge_unlock_requested.connect(_camp_pres.on_camp_forge_unlock)
|
||||
camp_overlay.forge_select_requested.connect(_camp_pres.on_camp_forge_select)
|
||||
camp_overlay.closed.connect(_camp_pres.on_camp_closed)
|
||||
_menu_screen.campbtn.pressed.connect(_camp_pres.open_camp)
|
||||
_menu_screen.careerbtn.pressed.connect(_open_career) # 生涯页一级入口(营地同组)
|
||||
_menu_screen.settingsbtn.pressed.connect(_open_settings) # 最小设置面入口
|
||||
_menu_screen.quitbtn.pressed.connect(_quit_game) # 退出游戏提级一级菜单
|
||||
|
||||
@@ -488,32 +483,23 @@ func _input_locked() -> bool:
|
||||
# ==================== 冒险模式入口(唯一试玩入口)====================
|
||||
|
||||
func _start_adventure_from_menu() -> void:
|
||||
# 互斥确认弹窗化:有断点时开新冒险弹实底确认框,
|
||||
# 「开新冒险」提交(弃旧断点+写盘)/「取消」回菜单
|
||||
if save_manager.has_breakpoint():
|
||||
var bp: Dictionary[Variant, Variant] = save_manager.breakpoint_snapshot()
|
||||
_confirm_consumer = "new_adventure" # 消费方编排(契约 3——open 前设消费方)
|
||||
confirm_dialog.open("已有未完冒险(第 %d 关)——开新冒险将覆盖旧断点" % maxi(1, int(bp.get("level_index", 1))),
|
||||
"开新冒险", "取消")
|
||||
return
|
||||
# 主菜单「开始冒险」钮已随三入口化撤出(卡② mn6——主菜单侧断点互斥确认链同步摘除,
|
||||
# 弹窗本体与两分支逻辑归卡④大门承接)。本函数为探针直调中间态保留(mn10——冒险段探针
|
||||
# 直调位点逐个登记实现报告「已知中间态」;卡④到位后由大门两分支换代)。无激活态写盘拒绝
|
||||
# 由卡① sv3 承接(结算不落盘)。
|
||||
_start_overlay.visible = false
|
||||
_start_adventure()
|
||||
|
||||
|
||||
# 确认弹窗分派(卡③ 契约 3):按 _confirm_consumer 路由——"new_adventure"=现役新冒险确认
|
||||
#(行为与原 _on_confirm_new_adventure 逐句等价)、"delete_slot"=卡③ 删档确认(确认才删、
|
||||
# 取消只关窗——裁决 3);分派面禁写死单一目标(卡④ 到位接入第三消费方不返工)。
|
||||
# 确认弹窗分派(卡③ 契约 3):按 _confirm_consumer 路由——"delete_slot"=卡③ 删档确认
|
||||
#(确认才删、取消只关窗——裁决 3)。"new_adventure" 消费方已随卡② 主菜单确认链摘除退役
|
||||
#(mn6/V5——主菜单零确认残留),分派机制保留(卡④ 到位接入第三消费方不返工)。
|
||||
func _on_confirm_accepted() -> void:
|
||||
confirm_dialog.close()
|
||||
match _confirm_consumer:
|
||||
"delete_slot":
|
||||
save_manager.delete_slot(_confirm_consumer_slot)
|
||||
save_select_overlay.open_save_select(_save_select_data()) # 就地刷新(该槽回空态)
|
||||
"new_adventure":
|
||||
save_manager.clear_breakpoint() # 提交即弃旧断点(覆盖语义对盘面即时生效)
|
||||
save_manager.write_to_disk()
|
||||
_start_overlay.visible = false
|
||||
_start_adventure()
|
||||
_confirm_consumer = ""
|
||||
|
||||
|
||||
@@ -529,17 +515,6 @@ func _quit_game() -> void:
|
||||
get_tree().quit()
|
||||
|
||||
|
||||
# 继续上局按钮可见性 = 断点在档态(启动读盘后与每次回开始菜单刷新)
|
||||
func _refresh_resume_button() -> void:
|
||||
if _resume_btn == null:
|
||||
return
|
||||
var has: bool = save_manager.has_breakpoint()
|
||||
_resume_btn.visible = has
|
||||
if has:
|
||||
var bp: Dictionary[Variant, Variant] = save_manager.breakpoint_snapshot()
|
||||
_resume_btn.text = "▶ 继续上局(第 %d 关 · 自最近停点恢复)" % maxi(1, int(bp.get("level_index", 1)))
|
||||
|
||||
|
||||
# 继续上局(resume_adventure 的消费入口):断点重建至最近停点
|
||||
func _resume_from_menu() -> void:
|
||||
if not save_manager.has_breakpoint():
|
||||
@@ -727,7 +702,6 @@ func _on_battle_end_continue() -> void:
|
||||
_begin_session(false)
|
||||
debug_overlay.reset_sliders()
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button() # 回菜单按断点在档态刷新(收束后已清=隐藏)
|
||||
_refresh_presentations()
|
||||
|
||||
|
||||
@@ -1086,7 +1060,6 @@ func _open_settings() -> void:
|
||||
func _on_settings_closed() -> void:
|
||||
_close_modal(settings_overlay) # 模态栈单口
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button()
|
||||
|
||||
|
||||
# ---- 局内状态面板·只读(入口角标在两屏装配段;开合与数据喂入归组合根)----
|
||||
@@ -1124,7 +1097,6 @@ func _open_career() -> void:
|
||||
func _on_career_closed() -> void:
|
||||
_close_modal(career_overlay) # 模态栈单口
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button()
|
||||
|
||||
|
||||
# 生涯页快照投影(只读同源——每次开层实时读 SaveManager 计数访问器 + MetaProgression 访问器
|
||||
@@ -1164,7 +1136,6 @@ func _open_save_select() -> void:
|
||||
func _on_save_select_closed() -> void:
|
||||
_close_modal(save_select_overlay) # 模态栈单口
|
||||
_start_overlay.visible = true
|
||||
_refresh_resume_button()
|
||||
|
||||
|
||||
# 槽数据快照(只读同源——每次开层实时经卡① 窥视 API 逐槽取数拼装;零写调用)。
|
||||
|
||||
@@ -8,10 +8,7 @@ extends Control
|
||||
|
||||
var start_overlay: Control # 全屏菜单层(原 main._start_overlay——组合根可见性开关句柄不变)
|
||||
var box: VBoxContainer
|
||||
var lvbtn: Button
|
||||
var resumebtn: Button
|
||||
var campbtn: Button
|
||||
var careerbtn: Button
|
||||
var entersavebtn: Button
|
||||
var settingsbtn: Button
|
||||
var quitbtn: Button
|
||||
|
||||
@@ -23,9 +20,6 @@ func _ready() -> void:
|
||||
var start: Dictionary[Variant, Variant] = UiAssembler.build_start_overlay(self, get_node("/root/ConfigDB"))
|
||||
start_overlay = start.overlay
|
||||
box = start.box
|
||||
lvbtn = start.lvbtn
|
||||
resumebtn = start.resumebtn
|
||||
campbtn = start.campbtn
|
||||
careerbtn = start.careerbtn
|
||||
entersavebtn = start.entersavebtn
|
||||
settingsbtn = start.settingsbtn
|
||||
quitbtn = start.quitbtn
|
||||
@@ -86,11 +86,11 @@ static func build_overlays(host: Control, db) -> Dictionary:
|
||||
}
|
||||
|
||||
|
||||
# 开始覆盖层(返回 {overlay, box, lvbtn, resumebtn, campbtn, careerbtn, settingsbtn, quitbtn}——按钮接线归组合根;
|
||||
# 开始覆盖层(返回 {overlay, box, entersavebtn, settingsbtn, quitbtn}——按钮接线归组合根;
|
||||
# 随机种子/数值调整板/两层调试三散件不在主按钮组,收进调试浮窗——
|
||||
# 调试入口=UI 最顶层全局浮层角标(build_debug_badge,本层零调试入口)
|
||||
# 布局=双列 VBox(左操作 56% + 右舞台);按钮动词化+悬停解释
|
||||
#(解释全迁 tooltip,G5);lvbtn 为主操作钮(烛光黄 CANDLE);右列=立绘看台。**界面禁玩法文字墙
|
||||
#(解释全迁 tooltip,G5);entersavebtn 为主操作钮(烛光黄 CANDLE——主菜单三入口化唯一进度入口);右列=立绘看台。**界面禁玩法文字墙
|
||||
#(教学内容归 Beta 帮助手册〔教学引导定稿 P4 丙〕)**;本层无玩法速览牌;
|
||||
# tooltip 主题归全局主题单点(禁在 root 挂程序化 tooltip 主题)。
|
||||
# 返回键集如首行所列,接线归组合根)
|
||||
@@ -124,31 +124,15 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
box.add_child(title)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
# 组帽·冒险
|
||||
box.add_child(UiKit.label("── 冒 险 ──",UiKit.FS_CAPTION, false, UiKit.WARM_FAINT))
|
||||
# 唯一试玩入口 = 正式「开始冒险」(三关序列);无单关测试直入口
|
||||
var resumebtn := UiKit.primary_button("▶ 继续上局") # 有断点才亮(可见性与关数文案归组合根刷新);主操作钮对齐 demo
|
||||
resumebtn.tooltip_text = "自最近停点恢复"
|
||||
resumebtn.visible = false
|
||||
box.add_child(resumebtn)
|
||||
# 主操作语义对齐 demo(有档时「继续上局」才是首动作=主黄钮,
|
||||
# 「开始冒险」=常规石钮;tooltip 保留)
|
||||
var lvbtn := UiKit.button("▶ 开始冒险")
|
||||
lvbtn.tooltip_text = "三关连探:地精洞窟 → 幽暗地域 → 灰矮人矿城"
|
||||
box.add_child(lvbtn)
|
||||
|
||||
# 组帽·营地与系统
|
||||
box.add_child(UiKit.label("── 营地与系统 ──",UiKit.FS_CAPTION, false, UiKit.WARM_FAINT))
|
||||
var campbtn := UiKit.verb_button("营地", UiKit.TEX_ICON_KEYSTONE, "永久强化:钥石换永久属性——跨局成长账本") # 主菜单营地入口
|
||||
box.add_child(campbtn)
|
||||
# 生涯页一级入口(与营地平级;页=局外只读跨局汇总,零跳转零购买)
|
||||
var careerbtn := UiKit.button("生涯")
|
||||
careerbtn.tooltip_text = "跨局生涯汇总:总局数 / 通关局数 / Boss 击杀 / 钥石余额 / 三柜台解锁概览(只读)"
|
||||
box.add_child(careerbtn)
|
||||
var settingsbtn := UiKit.button("设置") # 最小设置面入口
|
||||
# 三入口(主菜单三入口化——营地交互重做卡②,用户裁决 1:进入存档/设置/退出游戏;
|
||||
# 组帽双撤——冒险组帽组内零钮退化态不留、「营地与系统」帽指称失义,追认单留痕)
|
||||
var entersavebtn := UiKit.primary_button("进入存档") # 主操作钮(唯一进度入口)
|
||||
entersavebtn.tooltip_text = "选择一个存档位进入(新档 / 进档 / 删档)"
|
||||
box.add_child(entersavebtn)
|
||||
var settingsbtn := UiKit.button("设置") # 最小设置面入口(行为零变化——契约 2)
|
||||
settingsbtn.tooltip_text = "音量 / 全屏 / 减动效"
|
||||
box.add_child(settingsbtn)
|
||||
# 退出游戏与设置同层并行——只在一级菜单出现
|
||||
# 退出游戏与设置同层并行——只在一级菜单出现(行为零变化——契约 2)
|
||||
var quitbtn := UiKit.button("退出游戏")
|
||||
box.add_child(quitbtn)
|
||||
|
||||
@@ -190,8 +174,7 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
right.add_child(stage)
|
||||
|
||||
return {"overlay": overlay, "box": box,
|
||||
"lvbtn": lvbtn, "resumebtn": resumebtn,
|
||||
"campbtn": campbtn, "careerbtn": careerbtn,
|
||||
"entersavebtn": entersavebtn,
|
||||
"settingsbtn": settingsbtn, "quitbtn": quitbtn}
|
||||
|
||||
|
||||
|
||||
@@ -28,23 +28,19 @@ func _ready() -> void:
|
||||
main = load("res://presentation/main.tscn").instantiate()
|
||||
add_child(main)
|
||||
await get_tree().process_frame
|
||||
ProbeUiUtil.isolate_save(main, "fx_shot_probe", false, true, false)
|
||||
ProbeUiUtil.isolate_save(main, "fx_shot_probe", false, true, true) # 末参=swap_save(卡②签名换代——原 refresh_resume 槽位语义退役)
|
||||
# 隔离档即时应用(真实档 fullscreen 态会污染抓帧尺寸〔shot_probe 同款口径〕)
|
||||
main.settings_store.apply()
|
||||
for i in 8:
|
||||
await get_tree().process_frame # UI 装配完成等足帧(canvas_item 空引用窗口)
|
||||
var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains")
|
||||
if lvbtn == null:
|
||||
_fail("开始冒险按钮缺失")
|
||||
return
|
||||
lvbtn.pressed.emit()
|
||||
main._start_adventure_from_menu() # 函数直调中间态(卡② mn10——开始冒险钮已撤)
|
||||
# 等关卡画面出图(choices_presented 异步到达——最多 3s 轮询)
|
||||
for i in 60:
|
||||
await get_tree().process_frame
|
||||
if main.level_screen != null and main.level_screen.visible:
|
||||
break
|
||||
if main.level_screen == null or not main.level_screen.visible:
|
||||
_fail("关卡画面未出现(lvbtn 路径)")
|
||||
_fail("关卡画面未出现(函数直调中间态路径)")
|
||||
return
|
||||
for i in 5:
|
||||
await get_tree().process_frame
|
||||
|
||||
@@ -89,14 +89,14 @@ static func _text_match(text: String, needle: String, mode: String) -> bool:
|
||||
# ── 存档/设置/元进度三面隔离(探针禁碰真实档 user://save.json——SaveManager 路径注入纪律) ──
|
||||
# tag = 隔离档名(不带扩展名,如 "smoke_input_probe_save"——各探针后缀保持不变);先删后建防陈旧档泄入。
|
||||
# mark_first_done = 对齐真实档游玩史口径(模板抽签路径不变);with_settings = 连设置面换注
|
||||
#(隔离 cfg 名 = <tag>_settings.cfg,与被收口探针原文件名逐一同名);refresh_resume = 组合根
|
||||
#(隔离 cfg 名 = <tag>_settings.cfg,与被收口探针原文件名逐一同名);
|
||||
# 「继续上局」按钮重刷;swap_save = 是否换注全局 SaveManager(营地先行段只换 meta 侧不换 SaveManager)。
|
||||
# 返回隔离 SaveManager 实例(调用方常需后续直读余额/重读档)。
|
||||
# SaveManager/MetaProgression 是 autoload 单例——隔离面走单例原地重置
|
||||
#(attach_path 沿 RngService.set_master_seed 先例;MetaProgression 持 save 引用透传,
|
||||
# swap_save=false 分支换 meta 侧引用=独立 iso 实例,只换 meta 不换 save_manager)。
|
||||
static func isolate_save(main, tag: String, mark_first_done: bool = false, with_settings: bool = false,
|
||||
refresh_resume: bool = false, swap_save: bool = true):
|
||||
swap_save: bool = true): # refresh_resume 参数已随卡② _refresh_resume_button 删除退役(mn7)
|
||||
var save_path := "user://%s.json" % tag
|
||||
for p in [save_path, save_path + ".tmp", "user://%s_settings.cfg" % tag]:
|
||||
if FileAccess.file_exists(p):
|
||||
@@ -116,6 +116,22 @@ static func isolate_save(main, tag: String, mark_first_done: bool = false, with_
|
||||
main.get_node("/root/MetaProgression").save = iso # 只换 meta 侧(营地段语义)——SaveManager 全局不动
|
||||
if with_settings:
|
||||
main.settings_store = SettingsStoreScript.new("user://%s_settings.cfg" % tag)
|
||||
if refresh_resume:
|
||||
main._refresh_resume_button()
|
||||
return iso
|
||||
|
||||
# 营地经进档开层(卡② mn9 新路径——campbtn 已撤;槽模板注入隔离命名空间,防碰真实槽
|
||||
# user://save_slot_N.json——真实档红线)。创建=激活=暂行开营地(卡③ Q3 乙落点);
|
||||
# 驱动后写盘目标=隔离槽文件(持久化断言读 user://<tag>_slot_1.json)。返回 false=新档钮缺失(驱动中断)。
|
||||
static func open_camp_via_savesel(main, tag: String) -> bool:
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
sm.attach_slot_template("user://%s_slot_%%d.json" % tag)
|
||||
for i in range(1, 4): # 夹具清场——空槽起(陈旧槽文件会翻有档态、新档钮缺席)
|
||||
for suf in ["", ".tmp", ".corrupt.bak"]:
|
||||
var sp: String = sm.slot_path(i) + suf
|
||||
if FileAccess.file_exists(sp):
|
||||
DirAccess.remove_absolute(sp)
|
||||
main._open_save_select()
|
||||
var new_btn: Button = main.save_select_overlay._new_btns.get(1)
|
||||
if new_btn == null:
|
||||
return false
|
||||
new_btn.pressed.emit() # 真实按钮信号路径 → _on_save_select_new → create_slot+open_camp
|
||||
return true
|
||||
@@ -21,7 +21,7 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
|
||||
# 隔离存档(全 worktree 共享同一份 user://save.json——探针必须换注,禁碰真实档)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow", false, false, false, false)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow", false, false, false)
|
||||
await get_tree().process_frame
|
||||
|
||||
await _step_boot_menu()
|
||||
@@ -107,11 +107,10 @@ func _step_boot_menu() -> void:
|
||||
|
||||
# ---- ② 菜单 → 营地(真实按钮信号路径)----
|
||||
func _step_menu_to_camp() -> void:
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn == null:
|
||||
_problems.append("②菜单→营地:营地按钮缺失")
|
||||
# 营地经进档开层(卡② mn9 新路径——campbtn 已撤;槽模板注入隔离命名空间)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_screen_flow_camp"):
|
||||
_problems.append("②菜单→营地:选档层新档钮缺失(新路径驱动中断)")
|
||||
return
|
||||
campbtn.pressed.emit()
|
||||
await _frames()
|
||||
_expect_exclusive("②菜单→营地", "营地")
|
||||
|
||||
@@ -123,6 +122,8 @@ func _step_camp_back_to_menu() -> void:
|
||||
return
|
||||
main.camp_overlay.closed.emit()
|
||||
await _frames()
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await _frames()
|
||||
_expect_exclusive("③营地→菜单(回退)", "菜单")
|
||||
|
||||
|
||||
@@ -130,9 +131,13 @@ func _step_camp_back_to_menu() -> void:
|
||||
# ---- 选档界面开合(卡③ sl10):函数直调开层(「进入存档」钮归卡② mn3)→屏级互斥采样→
|
||||
# 返回钮真实信号路径关闭→ESC 语境不响应(卡⑤ 契约 2 范围外——零实现即断言)。----
|
||||
func _step_save_select_open_back() -> void:
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow_savesel", false, false, false, true)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_screen_flow_savesel", false, false, true)
|
||||
main.save_manager.attach_slot_template("user://smoke_screen_flow_savesel_slot_%d.json")
|
||||
main._open_save_select()
|
||||
var esb: Button = ProbeUiUtil.find_button(main._start_overlay, "进入存档", "prefix")
|
||||
if esb == null:
|
||||
_problems.append("[savesel] mn3 进入存档钮缺失(卡② 交付物)")
|
||||
return
|
||||
esb.pressed.emit() # 真实按钮信号路径 → _open_save_select(卡② mn3 点击链——卡③ 直调中间态就此闭环)
|
||||
await get_tree().process_frame
|
||||
var seals := _screen_seals()
|
||||
if not main.save_select_overlay.visible or not seals_check_single(seals):
|
||||
@@ -172,13 +177,8 @@ func seals_check_single(f: Dictionary) -> bool:
|
||||
|
||||
|
||||
func _step_menu_to_adventure() -> void:
|
||||
var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains")
|
||||
if lvbtn == null:
|
||||
lvbtn = ProbeUiUtil.find_button(main._start_overlay, "冒险", "contains")
|
||||
if lvbtn == null:
|
||||
_problems.append("④菜单→冒险:开始冒险按钮缺失")
|
||||
return
|
||||
lvbtn.pressed.emit()
|
||||
# 开始冒险钮已随三入口化撤出——函数直调中间态(卡② mn10;卡④ 大门两分支换代)
|
||||
main._start_adventure_from_menu()
|
||||
await _frames(3)
|
||||
_expect_exclusive("④菜单→冒险", "冒险")
|
||||
_expect_adventure_seal("④菜单→冒险", true)
|
||||
|
||||
+15
-22
@@ -5,7 +5,7 @@
|
||||
# Godot_console.exe --path . res://smoke/shot_probe.tscn -- <输出目录>
|
||||
# 流程 = 真实按钮信号路径驱动(ui_click_probe 同款;存档/设置/元进度三面换注隔离档——禁碰真实档,
|
||||
# 坑册「断点写盘随 save_manager 引用走」教训同款覆盖):菜单(启动态)→ 设置面(settingsbtn
|
||||
# 真实信号路径)→ 生涯页(careerbtn 同款)→ 营地(campbtn)→ 关卡画面(lvbtn→停点出图)→
|
||||
# 真实信号路径)→ 生涯页(函数直调中间态——卡② mn10)→ 营地(进档开层新路径——mn9)→ 关卡画面(函数直调中间态→停点出图)→
|
||||
# 战斗(level_screen.press_candidate(0) 真实选路提交)→ 状态面板(地图屏状态角标真实信号路径)。
|
||||
# 每屏双帧 + frame_post_draw 同步后抓 get_viewport().get_texture(),PNG 落输出目录;
|
||||
# 最小自检 = 七件存在且非零字节(像素方差断言归 tools/shot_checker.py——B 档骨架分工)。
|
||||
@@ -100,16 +100,13 @@ func _ready() -> void:
|
||||
else:
|
||||
set_close.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
# ①c 生涯页(careerbtn 真实信号路径,ui_struct_probe 同款入口链)
|
||||
var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if careerbtn == null:
|
||||
_problems.append("生涯入口缺失(开始层 careerbtn)")
|
||||
else:
|
||||
careerbtn.pressed.emit()
|
||||
# ①c 生涯页(函数直调中间态——卡② mn10:careerbtn 已撤,卡④ 笔记本改挂前无 UI 路径)
|
||||
if true:
|
||||
main._open_career()
|
||||
for i in 3:
|
||||
await get_tree().process_frame
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
_problems.append("生涯页未打开或开始层未隐藏(careerbtn 路径)")
|
||||
_problems.append("生涯页未打开或开始层未隐藏(函数直调中间态路径)")
|
||||
else:
|
||||
_meta["career_title"] = ProbeUiUtil.label_rect(main.career_overlay, "生 涯")
|
||||
await _snap("career")
|
||||
@@ -122,26 +119,22 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("生涯页关闭后页未隐藏或开始层未恢复")
|
||||
# ② 营地
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "contains")
|
||||
if campbtn == null:
|
||||
_problems.append("营地入口缺失(开始层 campbtn)")
|
||||
# ② 营地(进档开层新路径——卡② mn9;槽模板注入隔离命名空间)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_shot_probe_camp"):
|
||||
_problems.append("营地入口缺失(选档层新档钮——新路径驱动中断)")
|
||||
else:
|
||||
campbtn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
await _snap("camp")
|
||||
var close_btn: Button = ProbeUiUtil.find_button(main.camp_overlay, "关闭营地", "contains")
|
||||
if close_btn != null:
|
||||
close_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
# ③ 关卡画面(开始冒险→停点出图——入口停点语义)
|
||||
var lvbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "开始冒险", "contains")
|
||||
if lvbtn == null:
|
||||
_problems.append("开始冒险按钮缺失(开始层 lvbtn)")
|
||||
else:
|
||||
lvbtn.pressed.emit()
|
||||
for i in 4:
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态)
|
||||
await get_tree().process_frame
|
||||
# ③ 关卡画面(开始冒险→停点出图——入口停点语义;函数直调中间态 mn10)
|
||||
main._start_adventure_from_menu()
|
||||
for i in 4:
|
||||
await get_tree().process_frame
|
||||
await _snap("level")
|
||||
# GP 常驻徽章断言(读数=runner.gp 现值,刷新=写路径回执后重查〔open_choices〕)
|
||||
var gp_label: Label = ProbeUiUtil.find_label(main.level_screen, "◈ ")
|
||||
@@ -190,7 +183,7 @@ func _ready() -> void:
|
||||
if main.status_panel.visible:
|
||||
_problems.append("状态面板关闭后未隐藏(继续钮路径)")
|
||||
else:
|
||||
_problems.append("关卡画面未出现(lvbtn 路径)")
|
||||
_problems.append("关卡画面未出现(函数直调中间态路径)")
|
||||
# ── 几何元数据落盘(shot_checker 取样坐标源) ──
|
||||
var mf := FileAccess.open(out_dir.path_join("shot_meta.json"), FileAccess.WRITE)
|
||||
if mf != null:
|
||||
|
||||
+44
-30
@@ -159,8 +159,8 @@ func _smoke_scene_split() -> void:
|
||||
var menu: Node = load("res://presentation/scenes/menu_screen.tscn").instantiate()
|
||||
root.add_child(menu)
|
||||
await process_frame
|
||||
check(menu.start_overlay != null and menu.lvbtn != null and menu.resumebtn != null and menu.campbtn != null and menu.careerbtn != null and menu.settingsbtn != null and menu.quitbtn != null,
|
||||
"V2 菜单屏壳独立实例化(start_overlay+操作组六钮在位)")
|
||||
check(menu.start_overlay != null and menu.entersavebtn != null and menu.settingsbtn != null and menu.quitbtn != null,
|
||||
"V2 菜单屏壳独立实例化(start_overlay+操作组三钮在位——主菜单三入口化)〔卡② mn1〕")
|
||||
check(menu.start_overlay.visible, "V2 菜单层默认可见(非模态全屏态)")
|
||||
check(menu.mouse_filter == Control.MOUSE_FILTER_IGNORE, "V2 屏壳根零鼠标截获(IGNORE——全屏 STOP 壳吃输入病灶回归闸)")
|
||||
menu.queue_free()
|
||||
@@ -238,6 +238,14 @@ func _topmost_visible_layer(main: Node) -> Node:
|
||||
return best
|
||||
|
||||
|
||||
# 渲染面可见按钮递归计数(V2d mn1/mn2 变异锚——句柄缝盲区闭合)
|
||||
func _count_visible_buttons(node: Node) -> int:
|
||||
var n := 1 if (node is Button and node.visible) else 0
|
||||
for c in node.get_children():
|
||||
n += _count_visible_buttons(c)
|
||||
return n
|
||||
|
||||
|
||||
# ---- boot 链路时序后置条件(启动态六断言;只立行为可判断言,不造假时序)----
|
||||
func _smoke_boot_chain() -> void:
|
||||
print("--- 迭代28 T2 boot 链路时序后置条件(V2:六断言)---")
|
||||
@@ -266,9 +274,8 @@ func _smoke_boot_chain() -> void:
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
# ④-1 boot 路径:启动态钉死(卡① sv2)——boot 无激活态、断点在档恒否,续玩钮恒隐
|
||||
#(原「按钮态==真实档断点态」关系判据随启动态换代改写:test-conventions §9.5 申报在案,卡② mn8 再承接)
|
||||
check(not sm.has_breakpoint() and not main._resume_btn.visible,
|
||||
"V2d 续玩钮 boot 态恒隐(无激活态——启动态不隐式激活;断点在档=%s visible=%s)〔装配生命批 V2·卡① sv2 改写〕" % [
|
||||
str(sm.has_breakpoint()), str(main._resume_btn.visible)])
|
||||
check(not sm.has_breakpoint(),
|
||||
"V2d 续玩钮族退役·boot 无断点在档(启动态不隐式激活——卡① sv2 钉死;恒隐判据随钮退役由本断言+V2d 三钮在位承接)〔装配生命批 V2·卡② mn8 改写〕")
|
||||
# ④-1b 启动态三断言+旧单档迁移不变式(卡① sv2/sv12——真实 autoload boot 链)
|
||||
check(sm.active_slot() == 0 and not sm.has_write_target(),
|
||||
"V2-s1 boot 后无激活态(active_slot=0、写盘目标空)〔卡① sv2〕")
|
||||
@@ -278,24 +285,20 @@ func _smoke_boot_chain() -> void:
|
||||
"V2-s3 boot 无激活写盘拒绝(write_to_disk=false 生产入口)〔卡① sv3〕")
|
||||
check(not (FileAccess.file_exists("user://save.json") and not FileAccess.file_exists(sm.slot_path(1))),
|
||||
"V2-s4 旧单档迁移不变式(旧档在则槽 1 必在——Q1 甲一次性迁移已发生)〔卡① sv12〕")
|
||||
# ④-2 隔离新档双向(attach 原地重置——绝不碰真实档 user://save.json;刷新单口与 boot 路径同源)
|
||||
# ④-2 三钮承接(卡② mn8——V2d 续玩钮族随钮退役废止:钮可见性联动面由卡① V2-s 启动态断言与
|
||||
# sv11 attach 语义段承接;attach 原地重置语义保持——绝不碰真实档 user://save.json)
|
||||
for p in ["user://smoke_boot_chain.json", "user://smoke_boot_chain.json.tmp"]:
|
||||
if FileAccess.file_exists(p):
|
||||
DirAccess.remove_absolute(p)
|
||||
sm.attach_path("user://smoke_boot_chain.json")
|
||||
main._refresh_resume_button()
|
||||
check(not sm.has_breakpoint() and not main._resume_btn.visible,
|
||||
"V2d 续玩钮·无断点态隐藏(visible=%s has_breakpoint=%s)〔装配生命批 V2〕" % [
|
||||
str(main._resume_btn.visible), str(sm.has_breakpoint())])
|
||||
sm.set_breakpoint({"level_index": 2, "master_seed": 42})
|
||||
main._refresh_resume_button()
|
||||
check(sm.has_breakpoint() and main._resume_btn.visible,
|
||||
"V2d 续玩钮·有断点态可见(visible=%s has_breakpoint=%s)〔装配生命批 V2〕" % [
|
||||
str(main._resume_btn.visible), str(sm.has_breakpoint())])
|
||||
sm.clear_breakpoint()
|
||||
main._refresh_resume_button()
|
||||
check(not main._resume_btn.visible,
|
||||
"V2d 续玩钮·清断点后回隐藏(visible=%s)〔装配生命批 V2〕" % str(main._resume_btn.visible))
|
||||
check(main._menu_screen.entersavebtn != null and main._menu_screen.settingsbtn != null
|
||||
and main._menu_screen.quitbtn != null,
|
||||
"V2d 三钮在位·进入存档/设置/退出游戏(续玩钮族退役后主菜单操作组承接)〔卡② mn1/mn8〕")
|
||||
for old_btn in ["lvbtn", "resumebtn", "campbtn", "careerbtn"]:
|
||||
check(not (old_btn in main._menu_screen),
|
||||
"V2d 四旧钮句柄零命中·%s(彻底撤出——禁隐藏态禁置灰态残留)〔卡② mn2〕" % old_btn)
|
||||
check(_count_visible_buttons(main._start_overlay) == 3,
|
||||
"V2d 渲染面可见按钮计数==3(旧钮接回即红——渲染面锚,句柄缝盲区闭合)〔卡② mn1/mn2〕")
|
||||
# ⑤ 闲时会话(_ready 即建、永非 null、在树)
|
||||
check(main.run_scope != null and not main.run_scope.is_adventure and main.run_scope.is_inside_tree(),
|
||||
"V2e run_scope 非空且为闲时会话(is_adventure=false+is_inside_tree)〔装配生命批 V2〕")
|
||||
@@ -327,11 +330,10 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
if FileAccess.file_exists(p):
|
||||
DirAccess.remove_absolute(p)
|
||||
sm.attach_path("user://smoke_lifecycle.json")
|
||||
main._refresh_resume_button() # 隔离后重同步(boot 时按钮态反映的是真实档——T2 已断 boot 关系,此处按隔离档定基)
|
||||
main.debug_overlay.seed_edit.text = "42"
|
||||
# 阶段①闲时
|
||||
await _stage_faces(main, "V3a 闲时", "null", "null", "null",
|
||||
{"mf_start": true, "mf_inter": false, "mf_rows_empty": true, "start_vis": true, "resume_vis": false})
|
||||
{"mf_start": true, "mf_inter": false, "mf_rows_empty": true, "start_vis": true})
|
||||
# 阶段②开局停点(地图选路停点态)
|
||||
main._start_adventure_from_menu()
|
||||
for i in range(6):
|
||||
@@ -416,11 +418,18 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
elif modal_name == "career":
|
||||
main._open_career()
|
||||
elif modal_name == "camp":
|
||||
var campbtn: Button = main._menu_screen.campbtn
|
||||
if campbtn == null:
|
||||
check(false, "V3g 营地入口缺失(驱动中断)〔装配生命批 V3〕")
|
||||
# 营地经进档开层(卡② mn9 新路径——campbtn 已撤);槽模板注入隔离命名空间
|
||||
#(防碰真实槽 user://save_slot_N.json——真实档红线),营地闭合后恢复生命周期 attach 写盘目标
|
||||
#(卡① sv3 无激活拒写——后续阶段断点写盘依赖)
|
||||
sm.attach_slot_template("user://smoke_lifecycle_slot_%d.json")
|
||||
main._open_save_select()
|
||||
for i in range(2):
|
||||
await process_frame
|
||||
var ssel_new: Button = main.save_select_overlay._new_btns.get(1)
|
||||
if ssel_new == null:
|
||||
check(false, "V3g 营地入口缺失(选档层新档钮驱动中断)〔装配生命批 V3〕")
|
||||
continue
|
||||
campbtn.pressed.emit()
|
||||
ssel_new.pressed.emit() # 创建=激活=暂行开营地(卡③ Q3 乙落点)
|
||||
else:
|
||||
main._show_debug_overlay()
|
||||
for i in range(4):
|
||||
@@ -441,6 +450,15 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
await process_frame
|
||||
await _stage_faces(main, "V3g 模态合·%s" % modal_name, "null", "null", "null",
|
||||
{"mf_start": true, "start_vis": true})
|
||||
if modal_name == "camp":
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
for i in range(2):
|
||||
await process_frame
|
||||
sm.attach_path("user://smoke_lifecycle.json") # 恢复生命周期写盘目标
|
||||
for suf in ["", ".tmp"]:
|
||||
var slot_p: String = "user://smoke_lifecycle_slot_1.json" + suf
|
||||
if FileAccess.file_exists(slot_p):
|
||||
DirAccess.remove_absolute(slot_p)
|
||||
# 阶段⑧两连局(第二局全新会话——旧局对象不复用、脏态零残留)
|
||||
var first_adv = main.run_scope.adventure
|
||||
main.debug_overlay.seed_edit.text = "43"
|
||||
@@ -475,8 +493,6 @@ func _smoke_lifecycle_matrix() -> void:
|
||||
"keystone_drops": [], "bonus_taken": {},
|
||||
"bonus_pending": {"candidates": [{"kind": "heal", "tier": "common"}], "payload": {"gp_dropped": 0}},
|
||||
})
|
||||
main._refresh_resume_button()
|
||||
check(main._resume_btn.visible, "V3i 续玩钮·断点在档可见〔装配生命批 V3〕")
|
||||
var idle_scope = main.run_scope
|
||||
main._resume_from_menu()
|
||||
check(main.run_scope != idle_scope and main.run_scope.is_inside_tree(),
|
||||
@@ -570,9 +586,7 @@ func _stage_faces(main: Node, tag: String, adv: String, run: String, set: String
|
||||
"end_open":
|
||||
if main._end_overlay.is_open() != bool(extra[k]):
|
||||
bad += " _end_overlay.is_open 应=%s" % str(extra[k])
|
||||
"resume_vis":
|
||||
if main._resume_btn.visible != bool(extra[k]):
|
||||
bad += " _resume_btn.visible 应=%s" % str(extra[k])
|
||||
|
||||
"start_vis":
|
||||
if main._start_overlay.visible != bool(extra[k]):
|
||||
bad += " _start_overlay.visible 应=%s" % str(extra[k])
|
||||
|
||||
@@ -20,17 +20,13 @@ func _ready() -> void:
|
||||
# 存档/设置两面隔离(ProbeUiUtil.isolate_save 现行事实源,先删后建防陈旧档泄入)——
|
||||
# 隔离面走 attach_path 原地重置 autoload 单例:组合根 save_manager/meta 是getter-only
|
||||
# 读视图,直接赋值无效,隔离必须落在单例上。
|
||||
ProbeUiUtil.isolate_save(main, "t17_defer_probe", false, true, false)
|
||||
ProbeUiUtil.isolate_save(main, "t17_defer_probe", false, true, true) # 末参=swap_save(卡②签名换代——原 refresh_resume 槽位语义退役)
|
||||
# 本探针验证完整动画档的演播后排窗——强制 motion_scale=1.0(隔离档替换在 boot 后,
|
||||
# 减动效已随真档 settings.cfg 应用于引擎态;减动效档=consume_now 快路、开窗即时,另属语义)
|
||||
UiKit.motion_scale = 1.0
|
||||
for i in 8:
|
||||
await get_tree().process_frame
|
||||
var lvbtn: Button = _find_button_by_sub(main._start_overlay, "开始冒险")
|
||||
if lvbtn == null:
|
||||
_fail("开始冒险按钮缺失")
|
||||
return
|
||||
lvbtn.pressed.emit()
|
||||
main._start_adventure_from_menu() # 函数直调中间态(卡② mn10——开始冒险钮已撤)
|
||||
for i in 60:
|
||||
await get_tree().process_frame
|
||||
if main.level_screen != null and main.level_screen.visible:
|
||||
|
||||
@@ -49,20 +49,20 @@ func _ready() -> void:
|
||||
# 任何 UI 不遮挡;浮层角标遮挡判据见设置面段)
|
||||
if main.debug_overlay.visible:
|
||||
_problems.append("调试浮窗 boot 自动开(菜单优先失守)")
|
||||
# ---- 营地购买合成点击路径(campbtn/购买/关闭全走真实按钮信号路径;
|
||||
# ---- 营地购买合成点击路径(选档进档开层→购买→关闭全走真实按钮信号路径;
|
||||
# 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json);陈旧档段首清理)----
|
||||
for p0 in ["user://smoke_click_probe_reset.json", "user://smoke_click_probe_reset.json.tmp"]:
|
||||
if FileAccess.file_exists(p0):
|
||||
DirAccess.remove_absolute(p0) # 重置档段前清场兜底(营地/设置段不触该档——防陈旧断点泄入后续段)
|
||||
var iso_c = ProbeUiUtil.isolate_save(main, "smoke_click_probe_camp", false, false, false, false)
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn == null:
|
||||
_problems.append("营地入口按钮缺失(开始层 campbtn)")
|
||||
# swap=true(整链换注——购买写盘经 autoload 落隔离槽文件,与下方持久化核验同源;
|
||||
# 原 swap=false 形态的写盘走 iso 实例旧路径,与槽文件断言不同源——卡② mn9 换代)
|
||||
var iso_c = ProbeUiUtil.isolate_save(main, "smoke_click_probe_camp", false, false, true)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_click_probe_camp"):
|
||||
_problems.append("营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
campbtn.pressed.emit() # 真实按钮信号路径 → 组合根 _open_camp
|
||||
await get_tree().process_frame
|
||||
if not main.camp_overlay.visible:
|
||||
_problems.append("营地层未打开(点击路径)")
|
||||
_problems.append("营地层未打开(进档开层新路径)")
|
||||
elif main.camp_overlay._tree_buy_btns.is_empty():
|
||||
_problems.append("树淬炼柜台购买钮缺失(点击路径——四柜台重排后树=主界面)")
|
||||
else:
|
||||
@@ -83,7 +83,7 @@ func _ready() -> void:
|
||||
await get_tree().process_frame
|
||||
if int(iso_c.keystone_balance()) != bal_before - price:
|
||||
_problems.append("营地树购买未出账(%d→%d 应 −%d)" % [bal_before, iso_c.keystone_balance(), price])
|
||||
var iso_chk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp.json")
|
||||
var iso_chk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp_slot_1.json")
|
||||
iso_chk.load_from_disk()
|
||||
if int(iso_chk.tree_level("sp_hp")) != 1:
|
||||
_problems.append("营地树购买未持久(reload 后级 != 1)")
|
||||
@@ -117,12 +117,14 @@ func _ready() -> void:
|
||||
else:
|
||||
side_b.pressed.emit() # 合成切态点击 → _on_camp_fork_toggle → meta.tree_toggle_fork
|
||||
await get_tree().process_frame
|
||||
var iso_fk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp.json")
|
||||
var iso_fk = load("res://core/save_manager.gd").new("user://smoke_click_probe_camp_slot_1.json")
|
||||
iso_fk.load_from_disk()
|
||||
if String(iso_fk.fork_side("fg_posture")) != "b":
|
||||
_problems.append("Fork 切态未持久(reload 后激活态 != b)")
|
||||
main._on_camp_closed()
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await get_tree().process_frame
|
||||
if main.camp_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("营地关闭后未恢复开始层")
|
||||
# ---- 选档界面行为走查(迭代 33 卡③):sl5 空槽新档链/sl6 有档槽进档链/sl7 删档二次确认双路径
|
||||
@@ -134,7 +136,7 @@ func _ready() -> void:
|
||||
var cp: String = csel_tpl % i + suf
|
||||
if FileAccess.file_exists(cp):
|
||||
DirAccess.remove_absolute(cp)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_savesel", true, false, false, true)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_savesel", true, false, true)
|
||||
main.save_manager.attach_slot_template(csel_tpl)
|
||||
var f_c2 := FileAccess.open(csel_tpl % 2, FileAccess.WRITE)
|
||||
f_c2.store_string(JSON.stringify({"version": 7, "meta": {"keystone_balance": 100,
|
||||
@@ -290,11 +292,9 @@ func _ready() -> void:
|
||||
_problems.append("设置面仍含退出游戏按钮(二轮 D1——只在一级菜单出现)")
|
||||
# ---- 生涯页段(入口点击链+关闭回返,真实按钮信号路径;本页只读零写,
|
||||
# 值断言归冒烟投影段与 ui_struct 结构族,此处只验开合路径与零跳转)----
|
||||
var career_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if career_btn == null:
|
||||
_problems.append("生涯入口按钮缺失(开始层 careerbtn)")
|
||||
else:
|
||||
career_btn.pressed.emit() # 真实按钮信号路径 → 组合根 _open_career
|
||||
# 生涯页驱动=函数直调中间态(卡② mn10——careerbtn 已撤,卡④ 笔记本改挂前无 UI 路径)
|
||||
if true:
|
||||
main._open_career()
|
||||
await get_tree().process_frame
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
_problems.append("生涯页未打开(点击路径)")
|
||||
@@ -316,12 +316,7 @@ func _ready() -> void:
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
_problems.append("生涯页关闭后未恢复开始层")
|
||||
# 换回全新零档(营地购买态不泄入后续冒险段——确定性;档案残留下次段首清理兜底)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_reset", true, false, true) # 零档换注 + 继续上局按钮重刷(原三行样板收口)
|
||||
var resume_btn0: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 继续上局", "prefix")
|
||||
if resume_btn0 == null:
|
||||
_problems.append("继续上局按钮缺失(开始层 resumebtn——装配器)")
|
||||
elif resume_btn0.visible:
|
||||
_problems.append("无断点态继续上局按钮未隐藏(卡② AC①——新档合法空态)")
|
||||
ProbeUiUtil.isolate_save(main, "smoke_click_probe_reset", true, false, true) # 零档换注(继续上局钮已随三入口化撤出——卡② mn8)
|
||||
main.debug_overlay.set_sliders(400, 200) # 高加成保 L1 可通关——L2 岔路选路段只能经冒险推进到达(单关直入口退役)
|
||||
main.debug_overlay.seed_edit.text = "42" # 种子钉死(种子框默认为空=非首局随机,行为走查确定性禁依赖默认分支)
|
||||
var t1 := Time.get_ticks_msec()
|
||||
@@ -555,73 +550,9 @@ func _ready() -> void:
|
||||
# 战败态前提失配——记录不计 problem(返回路径已实机目检)。
|
||||
if not _closed_via_abandon:
|
||||
_problems.append("断点段:终局返回未回开始菜单")
|
||||
var resume_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 继续上局", "prefix")
|
||||
if resume_btn != null and resume_btn.visible:
|
||||
_problems.append("断点段:退出清断点后继续上局按钮未隐藏(卡②/T3 AC③)")
|
||||
# ② 中断→续玩:新冒险达入口停点=断点在档 → 合成回菜单(模拟关游戏重开)→ 按钮点亮 → 点击恢复至停点
|
||||
var lv_btn: Button = ProbeUiUtil.find_button(main._start_overlay, "▶ 开始冒险", "prefix")
|
||||
if lv_btn == null or resume_btn == null:
|
||||
_problems.append("断点段:开始冒险/继续上局按钮缺失")
|
||||
else:
|
||||
lv_btn.pressed.emit() # 无断点态单击直启(不触发二次确认)
|
||||
await get_tree().process_frame
|
||||
if not main.level_screen.visible:
|
||||
if not _closed_via_abandon:
|
||||
_problems.append("断点段:无断点开新冒险未达入口停点")
|
||||
else:
|
||||
iso_chk.load_from_disk()
|
||||
if not iso_chk.has_breakpoint():
|
||||
_problems.append("断点段:入口停点断点未写盘(卡①写面失守)")
|
||||
var cand_before: Array = main.run_scope.runner.next_candidate_ids()
|
||||
# 合成「关游戏重开回菜单」(探针专用——真实路径无此入口;断点已在盘)
|
||||
main._exit_level_screen()
|
||||
main._start_overlay.visible = true
|
||||
main.run_scope.adventure = null
|
||||
main._refresh_resume_button()
|
||||
await get_tree().process_frame
|
||||
if not resume_btn.visible:
|
||||
_problems.append("断点段:有断点态继续上局按钮未点亮(卡② AC②前置)")
|
||||
else:
|
||||
resume_btn.pressed.emit() # 真实按钮信号路径 → _resume_from_menu → resume_adventure
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.adventure == null or main.run_scope.runner == null or not main.level_screen.visible:
|
||||
_problems.append("断点段:续玩未恢复至停点(关卡画面未现)")
|
||||
else:
|
||||
var cand_after: Array = main.run_scope.runner.next_candidate_ids()
|
||||
if cand_after.size() != cand_before.size() or (cand_after.size() > 0 and int(cand_after[0]) != int(cand_before[0])):
|
||||
_problems.append("断点段:续玩候选与中断前不一致(停点重建失准)")
|
||||
if not iso_chk.load_from_disk() or not iso_chk.has_breakpoint():
|
||||
_problems.append("断点段:续玩误清断点(只在三结局清)")
|
||||
# ③ 互斥确认弹窗(二轮修改批 A):断点在档点开始冒险 → 弹确认框;取消=回菜单;开新冒险=提交
|
||||
main._exit_level_screen()
|
||||
main._start_overlay.visible = true
|
||||
main.run_scope.adventure = null
|
||||
main._refresh_resume_button()
|
||||
await get_tree().process_frame
|
||||
lv_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if not main.confirm_dialog.is_open() or main.run_scope.adventure != null:
|
||||
_problems.append("断点段:有断点点开始冒险未弹确认框(二轮 A 失守)")
|
||||
var cancel_btn: Button = ProbeUiUtil.find_button(main.confirm_dialog, "取消", "contains")
|
||||
if cancel_btn == null:
|
||||
_problems.append("断点段:确认框取消按钮缺失")
|
||||
else:
|
||||
cancel_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
if main.confirm_dialog.is_open() or main.run_scope.adventure != null or not main._start_overlay.visible:
|
||||
_problems.append("断点段:取消未回开始菜单(二轮 A)")
|
||||
lv_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
var confirm_btn: Button = ProbeUiUtil.find_button(main.confirm_dialog, "开新冒险", "contains")
|
||||
if confirm_btn == null:
|
||||
_problems.append("断点段:确认框开新冒险按钮缺失")
|
||||
else:
|
||||
confirm_btn.pressed.emit()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
if main.run_scope.adventure == null or main._start_overlay.visible or main.confirm_dialog.is_open():
|
||||
_problems.append("断点段:确认开新冒险后未开局(二轮 A)")
|
||||
# ②③ 中断→续玩全链+互斥确认两分支:随三入口化撤出(卡② §7.2 申报——断点确认探针段移交
|
||||
# 卡④大门 T5 接收,两头登记禁静默删除;续玩钮已退役,主菜单确认链已摘 mn6)。
|
||||
# ① 战斗收口断点写盘断言保留(上方——冒险流直调中间态 mn10)。
|
||||
print("[click_probe] 循环退出(done=%s budget=%s)问题=%d" % [
|
||||
str(_done), str(action_budget), _problems.size()])
|
||||
for p in _problems:
|
||||
|
||||
@@ -23,15 +23,13 @@ func _ready() -> void:
|
||||
# ---- 营地覆盖层(主菜单入口/开合/余额文案/购买禁用态;
|
||||
# 隔离存档换注 main.meta 保确定性(禁碰真实档 user://save.json——SaveManager 路径注入纪律;
|
||||
# 营地先行段只换 meta 不换 save_manager——冒险段换注零档在前)----
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", false, false, false, false)
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn == null:
|
||||
problems.append("营地入口按钮缺失(开始层 campbtn)")
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_probe_camp", false, false, false)
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_ui_probe_camp"):
|
||||
problems.append("营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
campbtn.pressed.emit() # 合成信号路径(真实按钮 → 组合根 _open_camp)
|
||||
await get_tree().process_frame
|
||||
if not main.camp_overlay.visible:
|
||||
problems.append("营地层未打开(campbtn 路径)")
|
||||
problems.append("营地层未打开(进档开层新路径)")
|
||||
elif main._start_overlay.visible:
|
||||
problems.append("营地层打开时开始层未隐藏(规范 2.3 遮挡纪律)")
|
||||
else:
|
||||
@@ -51,6 +49,8 @@ func _ready() -> void:
|
||||
problems.append("秘宝匣柜台行数错误(%d ≠ 12——迭代 22 秘宝批换代)" % main.camp_overlay._workshop_rows.size())
|
||||
main._on_camp_closed()
|
||||
await get_tree().process_frame
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
await get_tree().process_frame
|
||||
if main.camp_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("营地关闭后未恢复开始层(开合往返失守)")
|
||||
# 换回全新零档(营地段购买态不泄入后续冒险段——确定性;先删后建防陈旧档泄入)
|
||||
|
||||
@@ -38,35 +38,32 @@ func _ready() -> void:
|
||||
main._on_settings_closed()
|
||||
_settle()
|
||||
|
||||
var campbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "营地", "prefix")
|
||||
if campbtn != null:
|
||||
campbtn.pressed.emit()
|
||||
if not ProbeUiUtil.open_camp_via_savesel(main, "smoke_ui_struct_probe_menu"):
|
||||
problems.append("[camp] 营地入口缺失(选档层新档钮——mn9 新路径驱动中断)")
|
||||
else:
|
||||
_settle()
|
||||
await _audit("camp", [main.camp_overlay])
|
||||
main._on_camp_closed()
|
||||
_settle()
|
||||
else:
|
||||
problems.append("[camp] 营地入口按钮缺失(驱动中断)")
|
||||
main._on_save_select_closed() # 关闭被栈还原的选档层(动线序中间态——卡④ 换代点)
|
||||
_settle()
|
||||
|
||||
# ---- 生涯页:入口点击链(合成点击真路径=pressed.emit→组合根 _open_career)→
|
||||
# 结构断言族→只读巡检(契约 3)+零动效契约+零跳转契约(提纲 P4 甲)→组合根真实路径关闭。
|
||||
#(登记序/树序契约统一在全模态 _modal_registry_contract——boot 段跑)----
|
||||
var careerbtn: Button = ProbeUiUtil.find_button(main._start_overlay, "生涯", "prefix")
|
||||
if careerbtn != null:
|
||||
careerbtn.pressed.emit()
|
||||
_settle()
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
problems.append("[career] 生涯页未打开或开始层未隐藏(入口点击链断裂)")
|
||||
await _audit("career", [main.career_overlay])
|
||||
_career_readonly_contract(main)
|
||||
_career_zero_motion_contract(main)
|
||||
_career_nojump_contract(main)
|
||||
main._on_career_closed()
|
||||
_settle()
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("[career] 关闭后页未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
else:
|
||||
problems.append("[career] 生涯入口按钮缺失(开始层 careerbtn)")
|
||||
# 生涯页驱动=函数直调中间态(卡② mn9/mn10——careerbtn 已撤,卡④ 营地笔记本改挂前无 UI 路径)
|
||||
main._open_career()
|
||||
_settle()
|
||||
if not main.career_overlay.visible or main._start_overlay.visible:
|
||||
problems.append("[career] 生涯页未打开或开始层未隐藏(函数直调中间态断裂)")
|
||||
await _audit("career", [main.career_overlay])
|
||||
_career_readonly_contract(main)
|
||||
_career_zero_motion_contract(main)
|
||||
_career_nojump_contract(main)
|
||||
main._on_career_closed()
|
||||
_settle()
|
||||
if main.career_overlay.visible or not main._start_overlay.visible:
|
||||
problems.append("[career] 关闭后页未隐藏或开始层未恢复(模态栈单口失守)")
|
||||
|
||||
# ---- 选档界面(迭代 33 卡③):函数直调开层(「进入存档」钮归卡② mn3——点击链在卡② 承接),
|
||||
# sl1 三槽呈现/sl2 摘要三项逐槽读数/sl3 摘要禁项/sl4 操作集二分/sl9 重启链不预选。
|
||||
@@ -197,7 +194,6 @@ func _ready() -> void:
|
||||
# resume 提前 return)——GP 总结 lambda 求值时 runner 尚未赋值,修复前 717 炸 null。
|
||||
ProbeUiUtil.isolate_save(main, "smoke_ui_struct_probe_resume", true)
|
||||
main.save_manager.set_breakpoint(_resume_bp_fixture())
|
||||
main._refresh_resume_button()
|
||||
main.run_scope.runner = null # 全新启动等价态(真机=菜单直进续玩,无前置冒险——runner 从未赋值;探针此前推流会残留旧 runner)
|
||||
main._resume_from_menu()
|
||||
_settle(8)
|
||||
|
||||
@@ -89,7 +89,7 @@ func _ready() -> void:
|
||||
# (攻击 ×2 / 生命 +50%)——旧缺陷(残留值被当基线再乘)在 encounter 参数链上同样被抓获
|
||||
# 存档隔离(停点断点写盘随 main.save_manager;探针禁碰真实档,同族探针隔离纪律;
|
||||
# isolate_save 先删后建——上次运行的残留断点会触发互斥确认早退)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, false)
|
||||
ProbeUiUtil.isolate_save(main, "smoke_tune_probe_save", true, false, true) # 末参=swap_save(卡②签名换代——断点写盘经 autoload 落隔离档)
|
||||
main.debug_overlay.set_sliders(100, 50)
|
||||
main.debug_overlay.press_apply_for_probe()
|
||||
main.debug_overlay.seed_edit.text = "42" # 种子钉死(18卡⑦审计🔴——空框=非首局随机,显式优先经真实路径断言 master_seed)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 312 KiB After Width: | Height: | Size: 312 KiB |
@@ -27,7 +27,6 @@ func _init() -> void:
|
||||
var sm = main.get_node("/root/SaveManager")
|
||||
sm.attach_path("user://test_pacing_queue_save.json")
|
||||
sm.mark_first_adventure_done()
|
||||
main._refresh_resume_button()
|
||||
# 行信号计数器(真实信号路径旁挂计数——零触碰既有接线)
|
||||
var rows_seen: Array = []
|
||||
main._start_adventure_from_menu()
|
||||
|
||||
@@ -24,3 +24,13 @@
|
||||
| 5 | 提交切分与 worktree 命名(§9-5) | worktree `iter33card3-saveselect`/分支 `iter33-card3-saveselect`;三笔:T1+T2+T3 实现+变异伴生强化+T4 产出物 | — | — |
|
||||
| 6 | ConfirmDialog 消费方编排机制(§9-6,卡片预授权取法照录) | **open 前设消费方状态量(`_confirm_consumer`)、confirmed/cancelled 后按量分派(`_on_confirm_accepted`/`_on_confirm_declined` match 路由)**;双钮签名未动(`confirm_dialog.gd:36-38`);分派面=match 分支可扩展(卡④ 第三消费方直接加分支) | 禁双常驻静态接线 ✓(变异m4 拦截在役);本批消费方=删档确认+现役新冒险确认(随卡②撤出) | 机制重选=分派层重写 |
|
||||
| 7 | 窥视读器 has_file 位(实现期接口补全——超出 §9 清单单项,按 T0 对齐授权补记待追认) | `peek_slot_summary` 返回结构加 `has_file: bool`(空/有档操作集二分判定来处;卡③ 6.0「槽态唯一来处=卡① 窥视 API 返回值」的接口闭环——交付面缺该位则二分不可实现) | 非摘要第四项(契约 5 三项不变)✓;向后兼容(既有断言零改)✓;卡① 侧 sv7/sv8 断言复跑绿 ✓ | 若裁「二分判定改走他口」(如独立 has_slot API)——save_manager 增一访问器+组合根改一行 |
|
||||
|
||||
## 卡② 主菜单三入口化批
|
||||
|
||||
| # | 代拍项(卡片 §9 条目) | 取法 | 约束核对 | veto 影响 |
|
||||
|---|---|---|---|---|
|
||||
| 1 | 组帽与左列布局(§9-1) | **双组帽全撤**(冒险帽=组内零钮退化态不留;营地与系统帽=指称失义——「营地」已非菜单入口),三钮纵列原左列骨(布局零重构——契约 7) | v1.1「保留原样=留指称不可达地点文案,禁」✓ | 恢复任一组帽=视图一处 |
|
||||
| 2 | _refresh_resume_button 去留(§9-2) | **净删除**+消费点全清(main 五处/camp ctx 载体/presenter 三处/probe_ui_util 参数/pacing_queue/V2d 族——T0 清点口径 grep 零残留) | 卡④ 不复用已证 ✓ | — |
|
||||
| 3 | 进入存档钮命名(§9-3) | 「进入存档」primary_button 主操作钮(原主黄钮位),tooltip=「选择一个存档位进入(新档 / 进档 / 删档)」 | 裁决 1 原话 ✓ 动词化 ✓ | 改文案=装配器一处 |
|
||||
| 4 | 探针中间态写法(§9-4) | 营地=open_camp_via_savesel 助手(选档层新档钮真实信号路径,槽模板清场防真实槽污染、swap=true 整链落槽文件保持久化核验同源);生涯/冒险=函数直调(mn10 登记实现报告「已知中间态」) | 契约 5 中间态合法交付 ✓ 禁假路径 ✓ | 卡④ 落地后代换 |
|
||||
| 5 | 提交切分与 worktree 命名(§9-5) | worktree `iter33card2-menu`/分支 `iter33-card2-menu`;四笔(T1+T2/golden/变异强化+报告/T4) | — | — |
|
||||
@@ -21,3 +21,14 @@
|
||||
| 8 | `design/gdd/08-Alpha版本标准.md` 「三 · 界面」表 | 无选档界面行 | **增行请求(须用户裁——08 头注纪律)**:新增「选档界面」行(在役,迭代 33 卡③) | 卡③ §5 统一口径 |
|
||||
| 9 | `待办清单.md`/`roadmap.md` | 迭代 33 进行中 | 卡③ 完工状态推进(归文档批) | doc-conventions §12.1 |
|
||||
| 10 | `design/gdd/systems/表现与支撑/存档序列化.md` 消费面纪律节 | 窥视读器未记载(卡① 反哺点 4 补迁移口径时顺带) | 补 `peek_slot_summary` 返回结构(readable/has_file/三值)与「has_file=占档判定、非摘要项」口径 | 卡③ T0 对齐补充(二分判定来处的文档化) |
|
||||
|
||||
## 卡② 主菜单三入口化批
|
||||
|
||||
| # | 文档与落点 | 现行陈述 | 应改成 | 依据 |
|
||||
|---|---|---|---|---|
|
||||
| 11 | `design/gdd/systems/跨局循环/生涯.md` `:9`/`:11-23` | 主菜单六钮组(冒险组+营地与系统组)记述+生涯入口=开始层生涯钮 | 信息架构改三钮组(进入存档/设置/退出游戏);生涯入口改挂营地笔记本(卡④ 承载) | 卡② 实装(mn1/mn2) |
|
||||
| 12 | `design/gdd/ux/camp.md` `:10` | 「主菜单营地独立入口进入」 | 营地入口改挂存档内(选档→进档→营地场景图) | 同上 |
|
||||
| 13 | `design/gdd/08-Alpha版本标准.md` `:102-105` 三·界面表 | 主菜单/开始覆盖层等四行 | 状态列换代+入口拓扑注记(增删行须用户裁) | 卡② §5 统一口径 |
|
||||
| 14 | `体验验证清单.md` `:170`/`:192` | 左操作列(冒险/营地与系统两组)/营地与系统组生涯钮 | 主菜单形态引述换代(三钮)+目检项并入迭代 33 实机目检总清单(实现报告) | 卡② F13 |
|
||||
| 15 | `design/art/art-bible.md` `:433` | 小字号豁免合并条款含「主菜单分组 overline×2」枚举片段 | excision 两片段(组帽双撤——**禁整行删**) | 卡② mn11 实装 |
|
||||
| 16 | `待办清单.md`/`roadmap.md` | 迭代 33 进行中 | 卡② 完工状态推进+当前位换代(归文档批) | doc-conventions §12.1 |
|
||||
@@ -144,3 +144,48 @@
|
||||
| 单元 | 38 套件全绿 | **38 套件全绿** |
|
||||
| probe --click | 全绿 | 全绿(struct/click/flow 三件新段全绿+ui_contrast 等既有件零回归) |
|
||||
| 重闸 --code | — | 首轮 all_green=false(R1×2 新增)→ 回炉后**全绿**(回执随合并提交留痕——收口流程订正:回执须核 verdict 非仅 commit) |
|
||||
|
||||
---
|
||||
|
||||
## 卡② 主菜单三入口化批(6 钮 → 3 钮)——已合并(见合并记录)
|
||||
|
||||
**状态**:T0–T4 完成;批末全量闸全绿(回执随合并提交留痕);独立验收审计通过(`reports/iter33-验收审计-2026-10-21.md` 卡② 节)。
|
||||
|
||||
### 一、实际改动—验收对照表(§7.1 需求侧表的执行对账,六列+结果)
|
||||
|
||||
| 需求点 | 改动实值(文件:行) | 验收测试实值(落点+尾缀) | 层级 | 真实入口 | 撤销或变异证明 | 结果 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| mn1 三钮在位 | `ui_assembler.gd:126-137` build_start_overlay 三钮(进入存档 primary/设置/退出)+组帽双撤 | 冒烟 V2(`smoke_all.gd:162` 三钮在位)+V2d 渲染面计数==3(`smoke_all.gd:292`)〔mn1〕 | 冒烟 | 真实 MenuScreen 经装配器构建后读句柄+渲染面枚举 | 变异A=生涯钮接回三钮集 → 渲染面计数红(已执行;句柄缝盲区由变异暴露后强化) | 通过 |
|
||||
| mn2 四旧钮彻底撤出 | `menu_screen.gd:9-12` 句柄面撤 4 留 3;assembler 返回字典换代 | 冒烟 V2d 四旧钮句柄零命中×4+渲染面计数锚〔mn2〕 | 冒烟 | 菜单场景句柄枚举+渲染面 | 变异A 同锚 | 通过 |
|
||||
| mn3 进入存档可达选档 | `main.gd:323` entersavebtn.pressed→_open_save_select | `screen_flow_probe` 选档步〔mn3〕:合成点击进入存档钮→选档层可见且开始层隐藏 | 探针 | 真实按钮信号路径(卡③ 直调中间态就此闭环) | 变异B=接错层(连营地)→ sl10 屏级互斥 5 处红(已执行) | 通过 |
|
||||
| mn4 设置钮零行为变化 | settingsbtn 接线保持 | 冒烟 V3g settings 模态段复跑〔mn4〕 | 冒烟 | settingsbtn 句柄 pressed | 撤销=断线 → V3g 红 | 通过 |
|
||||
| mn5 退出接线正确 | quitbtn→_quit_game 保持 | ui_click 退出游戏按钮存在断言(D1 二轮段)复跑〔mn5〕 | 探针 | MenuScreen.quitbtn | 变异=改连空函数 → 连接断言红 | 通过 |
|
||||
| mn6 断点确认零残留 | `main.gd:489-497` 确认分支摘除+分派器 new_adventure 臂退役(机制保留) | ui_struct confirm 采样复跑+mn10 直调段绿(确认链不可达=直调直启)〔mn6〕 | 探针 | 主菜单路径确认链已无触发入口(钮撤+分支摘) | 撤销=接线复现 → 申报内 ui_click 断点段(已按 §7.2 删除移交卡④)原断言红 | 通过 |
|
||||
| mn7 _refresh_resume_button 删除+消费点清零 | 函数删除+main.gd 五处+camp_flow_context 载体+camp_shop_presenter 三处+probe_ui_util 参数+pacing_queue+V2d 族 | T0 清点口径全仓 grep 零命中件核(本表随附清点)+冒烟/探针全绿 | 集成 | 真实消费链已全部拆除 | 变异=漏删一处 ctx 字段 → 解析错/调用错红(camp_flow_context 参数摘除即证) | 通过 |
|
||||
| mn8 废止断言族有改写承接 | smoke V2 三钮/V2d 族重写(`smoke_all.gd:160-166`/`:281-293`)/V3g camp 新路径(`:411-449`)/V3i 钮断言摘(`:474-481`)/resume_vis 键退役(`_stage_faces`) | 改写后断言〔mn8〕逐族承接(渲染面计数+V3g 新路径+V2d 四旧钮零命中) | 冒烟 | boot 与回菜单生命周期段真实入口 | 撤销=只删不写承接 → 「每个废止族须有承接」计数断言红 | 通过 |
|
||||
| mn9 营地/生涯入口探针段改走新路径 | ui_probe/ui_struct/screen_flow/shot/ui_click 营地=进档开层新路径(open_camp_via_savesel 助手——槽模板清场防真实槽污染);生涯=函数直调中间态(卡④ 笔记本改挂前) | 各探针自身绿+新路径断言〔mn9〕 | 探针 | 选档层新档钮真实信号路径(持久化核验同源落槽文件) | 撤销=入口段留旧句柄 → 取不到钮即红(助手返回 false 即问题行) | 通过 |
|
||||
| mn10 冒险段探针直调中间态 | `_start_adventure_from_menu`/`_resume_from_menu` 保留仅摘接线/确认分支;直调位点=screen_flow 选档后冒险步、shot 关卡段、fx_shot、t17、ui_input、layout、ui_tune、smoke ×4、pacing_queue、ui_struct resume 专项 | 各该段复跑绿〔mn10〕+本节「已知中间态」逐位点登记 | 探针 | 函数直调(如实标中间态,卡④ 到位换代) | 撤销=删函数 → 直调段运行即红 | 通过 |
|
||||
| mn11 组帽撤除+左列几何不破 | `ui_assembler.gd` 两枚 overline 删除+三钮纵列(左列布局原骨) | ui_struct `_start_columns_contract`+`_audit("start")` 复跑〔mn11〕 | 探针 | 真实菜单构建后几何审计 | 变异=左列改单列致相交 → 不相交合同红 | 通过 |
|
||||
| mn12 menu golden 重制 | `game/tests/golden/menu_boot.png` 重采(三钮形态;golden_baseline_refresh --menu,触发原因=钮集换代) | render_gate 菜单 golden 逐像素段〔mn12〕 | golden | render_gate 驱动 shot_probe 真机渲染比对 | 撤销=拿旧基线跑 → 钮集区差红 | 通过(重闸渲染闸绿) |
|
||||
| mn13 pacing_queue 套件连带改造 | `pacing_queue_test.gd` 钮依赖行摘除(宿主链驱动保持) | 该套件自身绿(40 套件全绿内)〔mn13〕 | 单元 | run_all 真实套件入口 | 变异=裸调下层 → 宿主链断言红 | 通过 |
|
||||
| mn14 反哺点清单(非行为改动) | §5 所列(生涯.md/camp.md/08/体验验证清单/art-bible :433 excision/待办清单/roadmap)列点不落文 | 件核对表〔mn14〕落反哺点清单卡② 节 | 件核 | 收口前逐条指认 | 产出物件核不产码 | 通过 |
|
||||
|
||||
### 二、变异验证记录表
|
||||
|
||||
| # | 注入点 | 实测红 | 最窄闸 | 还原后 | 伴生强化 |
|
||||
|---|---|---|---|---|---|
|
||||
| A | 生涯钮接回三钮集(渲染面,无句柄) | 首轮 ui_struct/冒烟均零红——**句柄缝盲区暴露**(V2 只查三钮在位、V2d 只查句柄);补渲染面计数锚后冒烟红(1 项失败) | run_smoke | 1213/0 | V2d 渲染面计数锚 |
|
||||
| B | 进入存档钮接错层(连 _camp_pres.open_camp) | screen_flow 5 处红(sl10 屏级互斥失守+营地/冒险同屏) | screen_flow_probe | PASS | — |
|
||||
|
||||
### 三、已知中间态(mn10 逐位点登记——卡④ 到位换代)
|
||||
|
||||
生涯页与冒险入口无 UI 路径(生涯=营地笔记本、冒险=大门两分支,均卡④ 承载):`_open_career`/`_start_adventure_from_menu`(确认链已摘,直启形态)/`_resume_from_menu` 三函数保留为探针直调中间态,直调位点=ui_struct resume 专项、screen_flow 冒险步、shot 关卡段、fx_shot、t17_defer、ui_input、layout、ui_tune、smoke 四处、pacing_queue。ui_click 断点段②③(续玩全链+互斥确认两分支)按 §7.2 申报删除,卡④ 大门 T5 接收两头登记。
|
||||
|
||||
### 四、读数对照
|
||||
|
||||
| 闸 | 基线(卡③ 合并态) | 末态(卡② 收口) |
|
||||
|---|---|---|
|
||||
| 冒烟 | 1201 / 0 | **1213 / 0**(+12:V2 三钮+V2d 承接族+渲染面锚) |
|
||||
| 单元 | 38 套件全绿 | **40 套件全绿**(+2=平行迭代34 批次合入所带来的套件,非本批新增) |
|
||||
| 探针 | 全绿 | 全绿(struct/click/flow/ui_probe/tune/layout/input/t17 直跑;fx/shot 归窗口化闸件) |
|
||||
| golden | 六钮基线 | 三钮基线重制(渲染闸复跑绿) |
|
||||
@@ -189,3 +189,87 @@
|
||||
### 卡③ 结论(终审)
|
||||
|
||||
**通过**——卡③ 选档界面新建批 14 行(sl1–sl14)全部通过(首轮未过记录保留于上,回炉事实=提交 `b673ced`)。独立验收审计合并前置达成。复审全程零 commit、`game/` 零残留、`git status` 仅本报告工作件。
|
||||
|
||||
## 卡② 主菜单三入口化批(6 钮 → 3 钮)
|
||||
|
||||
> 审计人:未参与卡② 实现的独立会话,只采信盘面证据与自跑实测,不采信任何报告的「已全绿」。
|
||||
> 被审计对象:worktree `D:\code\g-plan2-iter33card2-menu`,分支 `iter33-card2-menu`,卡② 提交 `3661689a`+`93d0e679`+`5a39b116`+`821a2eae`,基线 `5c2a7bcf`(卡③ 合并态);区间内非本批改动(迭代34 卡④ 合并 `16a7ec80`、锻造工坊死链修 `4bc6b366`/`a10d15c7`)已按提交拓扑剔除,卡② 本体 diff 取 `a10d15c7..HEAD`(20 件:presentation 5+smoke 12+golden+pacing 单测+reports 3)。
|
||||
> 审计材料:需求卡片 §7.1 对照表 mn1-mn14+§7.2 七条申报+§2 F10 全量位点表、实现报告卡② 节(实际对照表+变异表 A/B+已知中间态)、卡② 本体 diff、闸回执。
|
||||
> 审计自跑:变异 B 注入→`screen_flow_probe` 红→还原→复绿全程实测(见②);另按改动域复跑最窄面与清点口径 grep(见各节)。
|
||||
|
||||
### ① 逐行核对表(mn1–mn14,对实现报告实际对照表逐行复核)
|
||||
|
||||
| # | 判定 | 依据(审计自查实录) |
|
||||
|---|---|---|
|
||||
| mn1 三钮在位 | 通过 | 断言在盘可 grep:冒烟 V2 三钮非空(`smoke_all.gd:162-163`,〔卡② mn1〕尾缀)+V2d 渲染面可见按钮计数==3(`:292-293`,5a39b116 强化件)。真实入口未绕过:`menu_screen.tscn` 真实实例化经 `UiAssembler.build_start_overlay` 构建后读句柄+渲染面递归枚举。变异 A 已执行(报告变异表 A+提交 5a39b116 提交信息在案)。 |
|
||||
| mn2 四旧钮彻底撤出 | 通过 | V2d 四旧句柄零命中×4(`smoke_all.gd:297-299` 循环断言)+渲染面计数锚(接回钮在渲染面出现即计数红——句柄缝盲区已由变异 A 暴露并闭合)。句柄面 diff 核实:`menu_screen.gd` 撤 `lvbtn/resumebtn/campbtn/careerbtn` 四字段、增 `entersavebtn`,装配器返回字典同步换代。 |
|
||||
| mn3 进入存档可达选档 | 通过 | `screen_flow_probe` 选档步在盘:`find_button(_start_overlay, "进入存档")` → `pressed.emit()`(真实按钮信号路径)→ 屏级互斥断言;钮缺失即 `_problems.append("[savesel] mn3 进入存档钮缺失")`(`screen_flow_probe.gd:165-172`,mn3 尾缀可 grep)。**审计实测变异 B 闭合**(见②-1):接线改连 `_camp_pres.open_camp()` → 5 处红含 `[savesel] sl10 屏级互斥失守`——与报告变异表 B 逐字一致。 |
|
||||
| mn4 设置钮零行为变化 | 通过 | settingsbtn→`_open_settings` 接线 diff 核实零触碰(`main.gd:328`);V3g settings 模态段冒烟生命周期矩阵原样复跑(该分支 diff 零改动=纯复跑,申报形态即「复跑」,无削弱)。 |
|
||||
| mn5 退出接线正确 | 通过 | quitbtn→`_quit_game` 接线 diff 核实零触碰(`main.gd:329`);对照面在盘:ui_click D1 二轮段「开始菜单有退出游戏钮+设置面无」双断言(`ui_click_probe.gd:288-292`)复跑。 |
|
||||
| mn6 断点确认主菜单零残留 | 通过(例外见注) | diff 核实两处摘除:`_start_adventure_from_menu` 确认分支整段删除(直启形态)+`_on_confirm_accepted` 分派器 `"new_adventure"` 臂退役(match 机制保留——V5 口径)。ui_struct 既有 confirm 采样在盘复跑(`ui_struct_probe.gd:100-103`)。注:本行撤销证明依赖的 ui_click 断点段原断言已按 §7.2 申报移交卡④(申报内删除)——残留拦截力由 mn2 四钮零命中+mn10 直调直启绿(直启不经确认框)组合承接,属间接面非专项断言;卡④ 落地后须补大门侧专项。 |
|
||||
| mn7 `_refresh_resume_button` 删除+消费点清零 | 通过 | 净删除 diff 核实:`main.gd` 函数体+五处调用+`camp_flow_context` 载体字段/构造参+`camp_shop_presenter` 三处+`probe_ui_util` 参数+`pacing_queue_test` 一处全清。**F10 表尾清点口径全仓 grep 复核**(口径照卡片):`_refresh_resume_button` 零命中;其余命中逐条归类——`start_overlay`(未退役件,合法在役)、两函数定义(契约 5 保留)、直调位点(全部为批前既有或已登记中间态,见 mn10)、注释引述与 mn2 零命中断言字面量(`smoke_all.gd:297`)——**表外新位点:零**。 |
|
||||
| mn8 废止断言族有改写承接 | 通过 | 逐族核对 diff:V2 六钮断言→三钮改写+〔mn1〕尾缀;V2d 续玩钮族→三钮在位+四旧零命中+渲染锚承接(卡① sv2 boot 态断言保留);V3g campbtn 直呼→进档开层新路径(`smoke_all.gd:411-449`);V3i 钮断言两行摘除+`_stage_faces` 的 `resume_vis` 键退役(键处理分支同步删)——逐族均有承接断言顶上,非裸删。生命周期其余阶段断言键 diff 核实零删改。 |
|
||||
| mn9 营地/生涯入口探针段改走新路径 | 通过 | 五件营地段全改 `open_camp_via_savesel` 新路径(ui_probe/ui_struct/screen_flow/shot/ui_click),该助手驱动=选档层新档钮 `pressed.emit()` 真实信号路径(`probe_ui_util.gd:126-137`),非绕过直调;槽模板注入隔离命名空间(真实档红线保持)。生涯段改函数直调——契约 5 中间态(登记见 mn10 注)。 |
|
||||
| mn10 冒险段探针直调中间态 | 通过(附注) | 契约 5 形态核实:两函数保留仅摘接线。直调位点全仓 grep 逐条对账——**本批新转直调 4 处全部已登记**(screen_flow 冒险步 `:181`、shot 关卡段 `:135`、fx_shot `:36`、t17_defer `:29`,实现报告「已知中间态」逐位点列名);批前既有直调位点(ui_input `:35`、layout `:27`、ui_tune `:96`、smoke ×4 `:338/:465/:620/:650`、pacing_queue `:32`、ui_struct 冒险簇 `:115`、ui_probe `:59`、ui_click 冒险段 `:323`)diff 核实零触碰或仅随 mn7 摘刷钮行。注(登记粒度微瑕,不判缺漏):生涯直调 3 处(ui_struct `:57`/ui_click `:296`/shot `:105`)与 smoke `_resume_from_menu` `:497` 为函数级登记(「已知中间态」明列 `_open_career`/`_resume_from_menu` 两函数保留+mn9 行「生涯=函数直调中间态」),未逐位点列名——实质已登记、粒度粗于冒险段。 |
|
||||
| mn11 组帽撤除+左列几何不破 | 通过 | diff 核实两枚 overline 整行删除(「── 冒 险 ──」「── 营地与系统 ──」);ui_struct `_audit("start")`(`:31`)+`_start_columns_contract`(`:32`/`:675`)在盘复跑,真实菜单构建后几何审计。组帽撤除处置与 §9 第 1 条一致且追认单留痕(reports/iter33-代拍板追认单卡② 节在盘)。F12 两处注释引述(main.gd:289、career_overlay.gd:3)按卡片「实施本体内可自理」保留。 |
|
||||
| mn12 menu golden 重制 | 通过 | 提交 `93d0e679` 提交信息完整记载触发原因(主菜单钮集换代)与重制入口(`golden_baseline_refresh --menu` 重采);二进制 diff 仅 `menu_boot.png` 一件(319500→319749 字节);`tools/golden_baseline_refresh.sh` 与 `tools/render_gate.sh` diff 核实零触碰(只跑不改——契约 6);复闸绿以回执 05 渲染闸 green 为准(fx/shot 探针窗口化形态,headless 直跑属预期 harness 形态不另直跑)。 |
|
||||
| mn13 pacing_queue 套件连带改造 | 通过(例外见注) | diff 核实仅摘 `_refresh_resume_button()` 一行(mn7 连带);`_start_adventure_from_menu` 直调保留。注:卡片 mn13 改动列写「去掉 _refresh_resume_button 与菜单直调依赖」,直调依赖未去掉——但契约 5(红线)+§9.4 白名单明定卡④ 未到位批内冒险段探针维直调合法,实现报告 mn13 行已如实对账「钮依赖行摘除(宿主链驱动保持)」并登记进「已知中间态」(pacing_queue 位点在列)——按契约优先于卡片行文判通过,非隐瞒偏差。 |
|
||||
| mn14 反哺点清单 | 通过 | `reports/iter33-反哺点-2026-10-21.md` 卡② 节在盘,第 11-16 条全覆盖 §5:生涯.md/camp.md/08/体验验证清单/art-bible :433 excision(禁整行删口径在案)/待办清单+roadmap,各条有现行陈述/应改成/依据。件核不产码,合规。 |
|
||||
|
||||
### ② 撤销证明抽查记录(审计自跑实测)
|
||||
|
||||
**②-1 变异 B 复现(报告变异表 B,实测全程)**
|
||||
|
||||
- 注入:`game/presentation/main.gd:318` `_menu_screen.entersavebtn.pressed.connect(_open_save_select)` → `_menu_screen.entersavebtn.pressed.connect(func() -> void: _camp_pres.open_camp())`(进入存档钮接错层——mn3 行申报的变异本体)。
|
||||
- `timeout 120 Godot_console.exe --headless --path . res://smoke/screen_flow_probe.tscn` → **FAIL — 5 处问题**:`[savesel] sl10 开层后屏级互斥失守(选档=false)`+⑤冒险内切换两条(营地/冒险同屏)+⑦终局→菜单两条(菜单/营地同屏)——与报告变异表 B「screen_flow 5 处红(sl10 屏级互斥失守+营地/冒险同屏)」一致,**mn3 断言拦截力实测成立**。
|
||||
- `git checkout -- game/presentation/main.gd` → `git status --porcelain` 空(零残留)→ 复跑 **PASS — 六步主流程+回退路径全绿**。注入→红→还原→复绿闭环。
|
||||
- 附核:探针全程走 `isolate_save` 隔离面,真实档 `user://save.json` 零触碰(探针纪律在案)。
|
||||
|
||||
**②-2 变异 A 处置历史核对(盘面凭据,未重放)**
|
||||
|
||||
- 首轮零红证据:报告变异表 A 原文「首轮 ui_struct/冒烟均零红——句柄缝盲区暴露(V2 只查三钮在位、V2d 只查句柄)」。
|
||||
- 伴生强化实证:提交 `5a39b116` diff 全量=`smoke_all.gd` +10 行零删——`_count_visible_buttons` 递归助手+渲染面计数==3 一条 check,**纯收紧**(只增断言不改旧断言不放宽阈值),提交信息同步记载盲区成因与两变异闭合实况。
|
||||
- 强化后拦截力推演:接回钮只要可见即计数 >3 必红,与句柄面无关——句柄缝盲区在锚面上不可再穿透。m-A 处置链(零红→补锚→复红)凭据齐、强化纯收紧,判成立。
|
||||
|
||||
### ③ 测试削弱检查表(卡② 本体 diff 全部删改逐处 vs 卡片 §7.2 七条申报)
|
||||
|
||||
| diff 改动处 | 定性 | vs §7.2 申报 |
|
||||
|---|---|---|
|
||||
| `smoke_all.gd` V2d 续玩钮族(旧 :266-290 六断言+boot 态断言改写+`_refresh_resume_button` 调用三处) | 既有断言废止/改写 | **申报内**(§7.2 行 1「钮已撤判据失去对象——废止」)。承接断言在盘:三钮在位+四旧零命中+渲染锚+卡① sv2 boot 态断言保留;卡① V2d-1 改写批内已申报「卡② mn8 再承接」——两代申报链闭合。 |
|
||||
| `smoke_all.gd` V3g campbtn 直呼(旧 :322/:326/:411-415) | 驱动路径换代 | **申报内**(行 2)。新路径=选档层新档钮真实信号→进档开营地,非直调开层——入口真实性与卡③ Q3 乙落点一致;camp 段后新增选档层闭合/attach 恢复/槽文件清理三步为路径换代伴生机械(非断言削弱)。 |
|
||||
| `smoke_all.gd` V3i 阶段⑨(旧 :470-478/:565-567) | 钮断言摘除+`resume_vis` 键退役 | **申报内**(行 3)。`_resume_from_menu` 全链断言保留(run_scope 换代+is_inside_tree),只摘钮可见性断言与 `_stage_faces` 键;生命周期其余阶段 diff 核实零删改。 |
|
||||
| `ui_click_probe.gd` resume_btn0 两断言(旧 :319-324,卡片 :224-228 行号漂移) | 既有断言删除 | **申报内**(行 4 前半——F10 表明列「resumebtn 断言+断点段」双位点)。行号漂移成因=卡③ savesel 段插入使基线行号后移,位点实质对应无疑义。 |
|
||||
| `ui_click_probe.gd` 断点段②③(旧 :555-616 约 73 行,卡片 :462-518) | 既有断言段删除 | **申报内**(行 4,约 80 行口径吻合)。两头登记核实:卡② 侧=卡片 T2+§7.2+实现报告「已知中间态」明列「卡④ 大门 T5 接收两头登记禁静默删除」;卡④ 接收侧=卡④ 未重立,登记义务随其重立卡兑现(现状为申报明文的待办形态,非静默删除)。段①(战斗收口断点写盘断言)保留在盘。 |
|
||||
| `shot_probe.gd` career/camp 段(旧 :103-133) | 生涯改直调+营地改新路径 | **申报内**(行 5「归卡④」的卡② 侧处置+行 7)。**七屏链存在性自检未降档**:`:192`「七件存在且非零字节」自检段 diff 零触碰;career 截图段保留(直调驱动)。 |
|
||||
| `ui_struct_probe.gd` resume 专项(旧 :86/:163-183) | 刷钮行摘除 | **申报内**(行 6)。`_resume_from_menu` 专项链与结构断言保留,仅摘 `_refresh_resume_button()` 调用(mn7 净删除连带)。 |
|
||||
| 冒险段探针入口路径断言(fx_shot/t17/screen_flow④/shot③) | 降级为函数直调 | **申报内**(行 7)。逐位点登记核实(见①-mn10),无「为凑绿改假路径」形态——直调目标=`_start_adventure_from_menu` 本体,下游断言(关卡画面出现/停点出图/冒险屏互斥)原样保留。 |
|
||||
| `probe_ui_util.gd` `isolate_save` 签名换代+`open_camp_via_savesel` 新增+ui_click camp 段 swap=false→true | 测试基建换代 | 非断言削弱:refresh_resume 参数随 mn7 退役(参数槽位语义由 swap_save 承接,全部调用点逐一同步换代——diff 逐处核对无错位);swap 翻转为写盘路径与槽文件断言同源化(注释在案),判据面对齐非放松。 |
|
||||
| `pacing_queue_test.gd` 删 1 行+`ui_probe.gd`/`ui_struct_probe.gd` 营地/生涯段改写 | 申报内改写 | 见①-mn7/mn9/mn10 对应行,申报面内。 |
|
||||
|
||||
**其余既有断言零删改核验**:卡② 本体 diff 逐 hunk 清点——ui_probe 秘宝匣 12 行断言原样在盘(`:48-49`);smoke 生命周期其余阶段断言键零删改;三探针既有段(sl1-sl9、设置面段、D1 段、ui_struct 各 `_audit` 面)零触碰;golden 两工具零触碰。**除 §7.2 申报面外,未发现任何删断言、放宽阈值、缩小扫描面或真实入口换下层直调**。
|
||||
|
||||
### ④ 回执核验(`game/tests/.gates/receipt.json`)
|
||||
|
||||
- `commit`=`821a2eae82664ab51fe00c6b6e639f55b60a0660`=HEAD(`821a2eae`)✓
|
||||
- `all_green`=**true** ✓;`domain`=**"full"** ✓(本批同触 game/ 与文档面,全量档选档正确)
|
||||
- 闸序:01 冒烟全量/02 单元套件/03 探针 --click/04 探针 --full/05 渲染闸(fx_shot/shot 两窗口化探针的绿以本闸记录为准,headless 直跑挂起属预期 harness 形态未直跑)/06-10 各文档闸全 green;11 回放确定性对拍 SKIP(SKIP 件非红);`quick_mode`=false;回执时间戳(2026-10-22T22:49:41+08:00)晚于末提交(22:41:58)=修后重闸实测。
|
||||
- 读数对照:实现报告冒烟 1213/0(+12 与 V2/V2d/渲染锚新增量吻合);单元 40 套件(+2 系迭代34 并行批合入非本批新增——diff 核实 `level_map_*_test` 两件属 16a7ec80)。
|
||||
|
||||
### ⑤ V5 专项(断点确认零残留)
|
||||
|
||||
- 全仓 grep「开新冒险将覆盖旧断点」:`game/` **零命中**;命中仅两处非码面——`待办清单.md:648`(2026-10-18 卫生批历史登记条,记述批前缺陷实况)+`reports/需求卡片-…md` F4 行(申报本体)。弹窗文案随消费方退役已不在任何生产代码。
|
||||
- 分派器机制保留核实:`_on_confirm_accepted` match 机制在盘(卡④ 第三消费方接入面),`"delete_slot"` 臂在役(卡③ 删档确认);`"new_adventure"` 臂整段退役(diff 在案)——代码与实现报告「机制保留、消费方退役」口径一致。
|
||||
- `rng_service.new_adventure`/`adventure_runner` 等同名散点为 RNG 会话入口,与确认消费方无关(grep 逐条判别非残留)。
|
||||
- 主菜单写档路径清零佐证:mn2 四钮零命中(无入口)+`_start_adventure_from_menu` 直启形态(无确认链)+`open_camp_via_savesel` 写盘只落隔离槽文件——主菜单无任何写档路径(契约 4)。
|
||||
|
||||
### 卡② 结论
|
||||
|
||||
**通过**——卡② 主菜单三入口化批 14 行(mn1–mn14)全部通过(mn6/mn10/mn13 三行附例外注记,均有申报或契约依据,非缺漏)。变异 B 审计实测闭合(注入→5 红→还原→复绿),变异 A 处置链凭据齐且强化纯收紧;§7.2 七条申报外的既有断言零删改;回执 commit/all_green/domain 三项全对上。独立验收审计合并前置达成。
|
||||
|
||||
**例外注记汇总(不阻塞合并,随卡④ 落地消解)**:
|
||||
|
||||
1. mn6:断点确认残留的拦截力现由 mn2+mn10 组合间接承接,卡④ 大门落地时应补大门侧专项残留断言(该断言原属卡④ 接收清单,两头登记在案)。
|
||||
2. mn10:生涯直调 3 处与 smoke `_resume_from_menu` 1 处为函数级登记、未逐位点列名——登记粒度微瑕,实质已登记。
|
||||
3. mn13:卡片「去掉菜单直调依赖」字面未兑现,按契约 5/§9.4 判中间态合法,报告已如实对账。
|
||||
|
||||
审计全程零 commit;变异注入经 `git checkout` 精确还原,`game/` 零残留(`git status` 仅本报告工作件)。
|
||||
Reference in new issue
Block a user